authproc: Support conditionally adding attributes declaratively #2579
+2,625
−0
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I have a number of cases where I'm looking to use authprocs to add extra attributes, but only if certain attributes already exist, and in some cases only if they have particular values or the names or values of the attributes match given regular expressions. I've found
%preconditionto be ok for really simple cases, but maintenance and debugging to be a pain - I really want something more expressive and declarative.I previously wrote PR #2559 to partially address this, but it was a bit of a hack to tack on support for just a few use cases. The incompleteness bothered me, so I've since torn that down and produced a far more comprehensive way to declaratively specify conditional adding of attributes in an authproc.
In doing this, the base case of unconditionally adding an attribute (essentially what the existing
core:AttributeAdddoes) remains reasonably simple:However, the main feature of this PR is the
conditionskey, which has a list of optional conditionals, which if satisfied, theattributesare added. By default, if more than one condition is specified, all must pass (essentially AND). The%anyconditionflag switches this to "one or more must pass" (essentially OR).The full dictionary of supported conditionals is:
The
%replaceflag is retained from the existingcore:AttributeAdd, and there is a new%nodupeflag, which removes duplicate values when appending new values to an attribute.One final example (taken from the documentation) showing the power of what this PR brings - in the below case, the user must either have a "supplierId" attribute, or have the "staff" role and be in the "Procurement" department to receive the 'allowedSystems' => ['procurement'] attribute:
The implementation itself is quite extensible. To add an extra type of condition later you implement three private methods (eg. if you were implementing
attrHasSomethingOrOther, you'd implementsetAttrHasSomethingOrOther()andisConfiguredAttrHasSomethingOrOther()andprocessConditionalAttrHasSomethingOrOther(). So extra new types of conditionals are now trivial to add later on.Included in this PR is 50+ PHPUnit tests and detailed user documentation which includes examples.
Follow-up work would be to have the existing
core:AttributeAddjust call this, providing backward compatibility but not carrying extra code. However, I thought I'd get this reviewed first before disturbing existing functionality.