Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New args policies security #224

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from
17 changes: 10 additions & 7 deletions src/main/java/cz/startnet/utils/pgdiff/PgDiff.java
Original file line number Diff line number Diff line change
Expand Up @@ -277,10 +277,10 @@ private static void updateSchemas(final PrintWriter writer,
writer, arguments, oldSchema, newSchema, searchPathHelper);
PgDiffViews.dropViews(
writer, oldSchema, newSchema, searchPathHelper);
PgDiffConstraints.dropConstraints(
writer, oldSchema, newSchema, true, searchPathHelper);
PgDiffConstraints.dropConstraints(
writer, oldSchema, newSchema, false, searchPathHelper);
PgDiffConstraints.dropConstraints(
writer, oldSchema, newSchema, true, searchPathHelper);
PgDiffIndexes.dropIndexes(
writer, oldSchema, newSchema, searchPathHelper);
PgDiffTables.dropClusters(
Expand All @@ -289,8 +289,9 @@ private static void updateSchemas(final PrintWriter writer,
writer, oldSchema, newSchema, searchPathHelper);
PgDiffSequences.dropSequences(
writer, oldSchema, newSchema, searchPathHelper);
PgDiffPolicies.dropPolicies(
writer, oldSchema, newSchema, searchPathHelper);
if(!PgDiffUtils.isNoPolicies())
PgDiffPolicies.dropPolicies(
writer, oldSchema, newSchema, searchPathHelper);
PgDiffSequences.createSequences(
writer, oldSchema, newSchema, searchPathHelper);
PgDiffSequences.alterSequences(
Expand Down Expand Up @@ -320,10 +321,12 @@ private static void updateSchemas(final PrintWriter writer,
writer, oldSchema, newSchema, searchPathHelper);
PgDiffViews.alterViews(
writer, oldSchema, newSchema, searchPathHelper);
PgDiffPolicies.createPolicies(
writer, oldSchema, newSchema, searchPathHelper);
PgDiffPolicies.alterPolicies(
if(!PgDiffUtils.isNoPolicies()){
PgDiffPolicies.createPolicies(
writer, oldSchema, newSchema, searchPathHelper);
PgDiffPolicies.alterPolicies(
writer, oldSchema, newSchema, searchPathHelper);
}
PgDiffFunctions.alterComments(
writer, oldSchema, newSchema, searchPathHelper);
PgDiffConstraints.alterComments(
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/cz/startnet/utils/pgdiff/PgDiffArguments.java
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,10 @@ public boolean parse(final PrintWriter writer, final String[] args) {
setVersion(true);
} else if ("--drop-if-exists".equals(args[i])) {
PgDiffUtils.setUseExists(true);
} else if ("--no-policies".equals(args[i])) {
PgDiffUtils.setNoPolicies(true);
} else if ("--no-alter-row-level-security".equals(args[i])) {
PgDiffUtils.setNoAlterRLS(true);
} else {
writer.print(Resources.getString("ErrorUnknownOption"));
writer.print(": ");
Expand Down
19 changes: 17 additions & 2 deletions src/main/java/cz/startnet/utils/pgdiff/PgDiffConstraints.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,20 @@ public static void dropConstraints(final PrintWriter writer,
writer.println(constraint.getDropSQL());
}
}
if(oldSchema!=null){
for (final PgTable oldTable : oldSchema.getTables()) {
//oldTable doesn't exit any more -> delete all her constraints
if(newSchema.getTable(oldTable.getName())==null){
// Drop constraints that no more exist
for (final PgConstraint constraint :
getDropConstraints(oldTable, null, primaryKey)) {
searchPathHelper.outputSearchPath(writer);
writer.println();
writer.println(constraint.getDropSQL());
}
}
}
}
}

/**
Expand All @@ -105,10 +119,11 @@ private static List<PgConstraint> getDropConstraints(final PgTable oldTable,
@SuppressWarnings("CollectionWithoutInitialCapacity")
final List<PgConstraint> list = new ArrayList<PgConstraint>();

if (newTable != null && oldTable != null) {
if (oldTable != null) {
for (final PgConstraint constraint : oldTable.getConstraints()) {
if (constraint.isPrimaryKeyConstraint() == primaryKey
&& (!newTable.containsConstraint(constraint.getName())
&& (newTable==null
|| !newTable.containsConstraint(constraint.getName())
|| !newTable.getConstraint(constraint.getName()).equals(
constraint))) {
list.add(constraint);
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/cz/startnet/utils/pgdiff/PgDiffTables.java
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ public static void alterTables(final PrintWriter writer,
alterOwnerTo(writer, oldTable, newTable, searchPathHelper);
alterPrivileges(writer, oldTable, newTable, searchPathHelper);
alterPrivilegesColumns(writer, oldTable, newTable, searchPathHelper);
alterRLS(writer, oldTable, newTable, searchPathHelper);
if(!PgDiffUtils.isNoAlterRLS())
alterRLS(writer, oldTable, newTable, searchPathHelper);
}
}

Expand Down
12 changes: 12 additions & 0 deletions src/main/java/cz/startnet/utils/pgdiff/PgDiffTriggers.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ public static void dropTriggers(final PrintWriter writer,
writer.println(trigger.getDropSQL());
}
}
if(oldSchema!=null){
for (final PgRelation oldRelation : oldSchema.getRels()) {
//oldRelation doesn't exit any more -> delete all her triggers
if(newSchema.getRelation(oldRelation.getName())==null){
for(final PgTrigger trigger : oldRelation.getTriggers()){
searchPathHelper.outputSearchPath(writer);
writer.println();
writer.println(trigger.getDropSQL());
}
}
}
}
}

/**
Expand Down
33 changes: 33 additions & 0 deletions src/main/java/cz/startnet/utils/pgdiff/PgDiffUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,18 @@ public class PgDiffUtils {
* Determine if use CREATE IF NOT EXISTS OR DROP IF EXISTS where is possible
*/
private static boolean useIfExists;


/**
* Determine if no create policies statements
*/
private static boolean noUsePolicies;


/**
* Determine if no create RLS statements in alter
*/
private static boolean noAlterRLS;

/**
* If name contains only lower case characters and digits and is not
Expand Down Expand Up @@ -565,6 +577,27 @@ public static void setUseExists(final boolean useExists) {

useIfExists = useExists;
}

public static void setNoPolicies(final boolean noPolicies) {

noUsePolicies = noPolicies;
}

public static void setNoAlterRLS(final boolean noRLS) {

noAlterRLS = noRLS;
}


public static boolean isNoPolicies() {

return noUsePolicies;
}

public static boolean isNoAlterRLS() {

return noAlterRLS;
}

/**
* Creates a new PgDiffUtils object.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public class PgDumpLoader { //NOPMD
* Pattern for testing whether it is CREATE TRIGGER statement.
*/
private static final Pattern PATTERN_CREATE_TRIGGER = Pattern.compile(
"^CREATE[\\s]+TRIGGER[\\s]+.*$",
"^CREATE[\\s]+(CONSTRAINT){0,1}[\\s]*TRIGGER[\\s]+.*$",
Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
/**
* Pattern for testing whether it is CREATE FUNCTION or CREATE OR REPLACE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,39 @@
public class CreateTriggerParser {

/**
* Parses CREATE TRIGGER statement.
* Parses CREATE [CONSTRAINT] TRIGGER statement.
*
* @param database database
* @param statement CREATE TRIGGER statement
* @param statement CREATE [CONSTRAINT] TRIGGER statement
* @param ignoreSlonyTriggers whether Slony triggers should be ignored
*/
public static void parse(final PgDatabase database,
final String statement, final boolean ignoreSlonyTriggers) {
final Parser parser = new Parser(statement);
parser.expect("CREATE", "TRIGGER");

final PgTrigger trigger = new PgTrigger();
final Parser parser = new Parser(statement);

parser.expect("CREATE");
if(parser.expectOptional("CONSTRAINT"))
trigger.setConstraint(true);
parser.expect("TRIGGER");

final String triggerName = parser.parseIdentifier();
final String objectName = ParserUtils.getObjectName(triggerName);

final PgTrigger trigger = new PgTrigger();
trigger.setName(objectName);

if (parser.expectOptional("BEFORE")) {
trigger.setEventTimeQualification(PgTrigger.EventTimeQualification.before);
} else if (parser.expectOptional("AFTER")) {
trigger.setEventTimeQualification(PgTrigger.EventTimeQualification.after);
} else if (parser.expectOptional("INSTEAD OF")) {
trigger.setEventTimeQualification(PgTrigger.EventTimeQualification.instead_of);

if(trigger.isConstraint()){
parser.expect("AFTER");
trigger.setEventTimeQualification(PgTrigger.EventTimeQualification.after);
} else {
if (parser.expectOptional("BEFORE")) {
trigger.setEventTimeQualification(PgTrigger.EventTimeQualification.before);
} else if (parser.expectOptional("AFTER")) {
trigger.setEventTimeQualification(PgTrigger.EventTimeQualification.after);
} else if (parser.expectOptional("INSTEAD OF")) {
trigger.setEventTimeQualification(PgTrigger.EventTimeQualification.instead_of);
}
}

boolean first = true;
Expand Down Expand Up @@ -75,6 +85,23 @@ public static void parse(final PgDatabase database,
final String relationName = parser.parseIdentifier();

trigger.setRelationName(ParserUtils.getObjectName(relationName));

if(trigger.isConstraint()){
if(parser.expectOptional("DEFERRABLE")){
trigger.setDeferrable(true);
if(parser.expectOptional("INITIALLY","DEFERRED")){
trigger.setDeferred(true);
}else if(parser.expectOptional("INITIALLY","IMMEDIATE")){
trigger.setDeferred(false);
}else{
trigger.setDeferred(false);
}
}else if(parser.expectOptional("NOT","DEFERRABLE")){
trigger.setDeferrable(false);
}else {
trigger.setDeferrable(false);
}
}

if (parser.expectOptional("FOR")) {
parser.expectOptional("EACH");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ public String getCreationSQL() {
sbSQL.append(PgDiffUtils.getQuotedName(getTableName()));
sbSQL.append(System.getProperty("line.separator"));
sbSQL.append("\tADD CONSTRAINT ");
sbSQL.append(PgDiffUtils.getCreateIfNotExists());
sbSQL.append(PgDiffUtils.getQuotedName(getName()));
sbSQL.append(' ');
sbSQL.append(getDefinition());
Expand Down
101 changes: 98 additions & 3 deletions src/main/java/cz/startnet/utils/pgdiff/schema/PgTrigger.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,27 @@ public static String toString(EventTimeQualification eventTimeQualification) {
return stringRepresentation.get(eventTimeQualification);
}
}

/**
* Whether the trigger is contraint.
*/
private boolean constraint;

/**
* This controls whether the constraint can be deferred.
* A constraint that is not deferrable will be checked immediately after every command.
* Checking of constraints that are deferrable can be postponed until the end of the transaction.
*/

private boolean deferrable;

/**
* If a constraint is deferrable, this clause specifies the default time to check the constraint.
* If the constraint is INITIALLY IMMEDIATE, it is checked after each statement.
* This is the default. If the constraint is INITIALLY DEFERRED, it is checked only at the end of the transaction.
*/

private boolean deferred;

/**
* Function name and arguments that should be fired on the trigger.
Expand Down Expand Up @@ -139,14 +160,17 @@ public void setComment(final String comment) {
*/
public String getCreationSQL() {
final StringBuilder sbSQL = new StringBuilder(100);
sbSQL.append("CREATE TRIGGER ");
sbSQL.append("CREATE");
if(isConstraint())
sbSQL.append(" CONSTRAINT");
sbSQL.append(" TRIGGER ");
sbSQL.append(PgDiffUtils.getQuotedName(getName()));
sbSQL.append(System.getProperty("line.separator"));
sbSQL.append("\t");
sbSQL.append(EventTimeQualification.toString(getEventTimeQualification()));

boolean firstEvent = true;

if (isOnInsert()) {
sbSQL.append(" INSERT");
firstEvent = false;
Expand Down Expand Up @@ -197,6 +221,20 @@ public String getCreationSQL() {

sbSQL.append(" ON ");
sbSQL.append(PgDiffUtils.getQuotedName(getRelationName()));
if(isConstraint()){
sbSQL.append(System.getProperty("line.separator"));
sbSQL.append("\t");
if(isDeferrable()){
sbSQL.append(" DEFERRABLE ");
if(isDeferred()){
sbSQL.append(" INITIALLY DEFERRED ");
}else{
sbSQL.append(" INITIALLY IMMEDIATE ");
}
}else {
sbSQL.append(" NOT DEFERRABLE ");
}
}
sbSQL.append(System.getProperty("line.separator"));
sbSQL.append("\tFOR EACH ");
sbSQL.append(isForEachRow() ? "ROW" : "STATEMENT");
Expand Down Expand Up @@ -237,6 +275,60 @@ public String getDropSQL() {
return "DROP TRIGGER " + PgDiffUtils.getDropIfExists() + PgDiffUtils.getQuotedName(getName()) + " ON "
+ PgDiffUtils.getQuotedName(getRelationName()) + ";";
}

/**
* Setter for {@link #constraint}.
*
* @param constraint {@link #constraint}
*/
public void setConstraint(final boolean constraint) {
this.constraint = constraint;
}

/**
* Getter for {@link #constraint}.
*
* @return {@link #constraint}
*/
public boolean isConstraint() {
return constraint;
}

/**
* Setter for {@link #deferrable}.
*
* @param deferrable {@link #deferrable}
*/
public void setDeferrable(final boolean deferrable) {
this.deferrable = deferrable;
}

/**
* Getter for {@link #deferrable}.
*
* @return {@link #deferrable}
*/
public boolean isDeferrable() {
return deferrable;
}

/**
* Setter for {@link #deferred}.
*
* @param deferred {@link #deferred}
*/
public void setDeferred(final boolean deferred) {
this.deferred = deferred;
}

/**
* Getter for {@link #deferred}.
*
* @return {@link #deferred}
*/
public boolean isDeferred() {
return deferred;
}

/**
* Setter for {@link #forEachRow}.
Expand Down Expand Up @@ -434,7 +526,10 @@ public boolean equals(final Object object) {
&& (onInsert == trigger.isOnInsert())
&& (onUpdate == trigger.isOnUpdate())
&& (onTruncate == trigger.isOnTruncate())
&& relationName.equals(trigger.getRelationName());
&& relationName.equals(trigger.getRelationName())
&& constraint == trigger.isConstraint()
&& deferrable == trigger.isDeferrable()
&& deferred == trigger.isDeferred();

if (equals) {
final List<String> sorted1 =
Expand Down
Loading