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

Clarify some parts of the PermissionService documentation #1387

Merged
merged 1 commit into from
Oct 16, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ public interface PermissionService extends ContextualService<Subject> {
* subject is at the root of all inheritance trees, above even subject type-specific
* defaults, meaning it has the lowest priority when all other weighting is equal.
*
* <p>Note: This data should be persisted, so plugins that add permissions to this subject
* must take care to not override permissions already set or modified. It is also
* recommended to use {@link Subject#getTransientSubjectData()} where possible to
* avoid persisting unnecessary data.
Copy link
Member

@ST-DDT ST-DDT Oct 9, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not so sure about the persisting part.
If you modify defaults then its customized and no longer a default. IMO its better to specify a user group that inherits from the default group and overwrite things there.
In addition to that on one hand you force the permission plugin to persist the data, but on the other hand you ask the plugin owner to set transient data only.

Missing </p>tag.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with you - however, the current intended behaviour is that defaults are persisted.

(at least, thats what I'm assuming, judging from the responses I've had from blood, and from looking at the PEX implementation. I'm all for saying "nope, defaults should be transient", however this PR was about improving documentation, not changing intended behaviours.)

There's missing </p> tags throughout PermissionService. You'll notice they don't appear in the existing JavaDocs either, so I just followed the same convention.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the intention is that persistent defaults and transient defaults are exposed.

Generally, the persistent defaults are primarily set by the user and transient defaults are primarily set by plugins, but the permissions API exposes both.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep - that's fine, it just wasn't documented.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mk good, it would probably be good to say more about the purposes of persistent vs transient (and make sure to update the javadocs in SubjectCollection as well)

Copy link
Contributor Author

@lucko lucko Oct 9, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's already in my commit, kinda. There's an explanation of transient data on the #getTransientSubjectData method.

201386e#diff-10cc1565e2d1c6e37bae54aabd176204R101
I don't think you really need to say more than that.

*
* @return The default subject data
*/
Subject getDefaults();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@
* child levels would granted but {@code example.access} would denied (for
* example).
*
* <p>It is the responsibility of the {@link PermissionService} implementation
* to provide this behavior, and resolve the implicit permission node inheritance
* explained above when a Subject is queried for permissions. Use of a
* {@link NodeTree} is recommended.
*
* <p>Plugins may opt to implement "dynamic" permissions such as {@code
* example.region.define.&lt;region&gt;} where {@code region} would be a
* dynamically added level based on the context, though some attention should be
Expand All @@ -59,7 +64,15 @@
* administrators to grant {@code example.function.self} to permit usage on
* one's self and grant {@code example.function} to grant usage on other users.
*
* <p>Use a {@link PermissionService} to create instances.
* <p>All methods are expected unlike {@link SubjectData}, to account for data
* inherited from parent subjects. For a representation of the data that the
* subject explicitly holds, obtain the {@link SubjectData} for the object.
*
* <p>Additionally, all methods are expected to account for the defaults
* defined in the {@link SubjectCollection} containing this subject, as well
* as the defaults set globally in {@link PermissionService#getDefaults()}.
*
* <p>Use a {@link SubjectCollection} to create instances.
*
* @see PermissionService
*/
Expand Down Expand Up @@ -101,14 +114,17 @@ public interface Subject extends Contextual {
SubjectData getTransientSubjectData();

/**
* Test whether the subject is permitted to perform an action given as the
* given permission string.
* Test whether the subject is permitted to perform an action corresponding to the
* given permission string. This must return the same boolean equivalent as
* {@link #getPermissionValue(Set, String)}.
*
* @param contexts The set of contexts that represents the subject's current environment
* @param permission The permission string
* @return True if permission is granted
*/
boolean hasPermission(Set<Context> contexts, String permission);
default boolean hasPermission(Set<Context> contexts, String permission) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also mention the "format" permission strings are supposed to follow.
(See PermissionDescription for more details)
And it should mention that there are no wildcard.* permissions.

The same applies for getPermissionValue

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Plugins wouldn't normally check if users had wildcard permissions, so I don't think those methods are the correct place to document that.

I added a reminder that implementations should consider "wildcards" in those checks. For the actual explanation, they can read the description in the main Subject class documentation.

return getPermissionValue(contexts, permission).asBoolean();
}

/**
* Test whether the subject is permitted to perform an action given as the
Expand All @@ -125,6 +141,17 @@ default boolean hasPermission(String permission) {
/**
* Returns the calculated value set for a given permission.
*
* <p>It is expected that this method will also account for values
* inherited from parent subjects, as well as permission nodes inherited
* implicitly from a more generic level.
*
* <p>Additionally, the defaults defined the {@link SubjectCollection}
* that holds this subject, as well as defaults defined in
* {@link PermissionService#getDefaults()} should be considered for this lookup.
*
* <p> This method is likely to be called frequently, so it is desirable
* that implementations cache the results to method calls.
*
* @param contexts The contexts to check for permissions in
* @param permission The permission to check
* @return The tristate true/false/unset value for permissions
Expand All @@ -134,7 +161,7 @@ default boolean hasPermission(String permission) {
/**
* Check if this subject is a child of the given parent in the subject's
* current context, traversing inheritance. This must return the same value as
* {@link #hasPermission(Set, String)} using {@link #getActiveContexts()}.
* {@link #isChildOf(Set, Subject)} using {@link #getActiveContexts()}.
*
* @param parent The parent to check for inheritance
* @return Whether this is a child of the given parent
Expand All @@ -157,7 +184,7 @@ default boolean isChildOf(Subject parent) {
* Return all parents that this group has in its current context
* combination. This must include inherited values if the permissions
* service supports inheritance. This must return the same value as
* {@link #hasPermission(Set, String)} using {@link #getActiveContexts()}.
* {@link #getParents(Set)} using {@link #getActiveContexts()}.
*
* @return An immutable list of parents
*/
Expand All @@ -177,6 +204,13 @@ default List<Subject> getParents() {
/**
* Get the value of a given option in the given context.
*
* <p>It is expected that this method will account for options
* inherited from parent subjects.
*
* <p>Additionally, the default options defined the {@link SubjectCollection}
* that holds this subject, as well as defaults defined in
* {@link PermissionService#getDefaults()} should be considered for this lookup.
*
* @param contexts The contexts to get the options from
* @param key The key to get an option by. Case-insensitive.
* @return The value of the option, if any is present
Expand All @@ -185,7 +219,7 @@ default List<Subject> getParents() {

/**
* Get the value of a given option in the subject's current context
* This must return the same value as {@link #hasPermission(Set, String)}
* This must return the same value as {@link #getOption(Set, String)}
* using {@link #getActiveContexts()}.
*
* @param key The key to get an option by. Case-insensitive.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,14 @@ public interface SubjectCollection {
Map<Subject, Boolean> getAllWithPermission(Set<Context> contexts, String permission);

/**
* Get the subject that provides defaults for subjects of this type. This subject is placed at the root of any inheritance tree involving subjects of this type.
* Get the subject holding data that is applied by default for subjects of this type.
* This subject is placed at the root of any inheritance tree involving subjects of
* this type, but has a higher priority than {@link PermissionService#getDefaults()}.
*
* <p>Note: This data may be persisted, so plugins that add permissions to this subject
* must take care to not override permissions already set or modified. It is also
* recommended to use {@link Subject#getTransientSubjectData()} where possible to
* avoid persisting unnecessary data.
*
* @return The subject holding defaults
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ public interface SubjectData {
* Clear all options in the given context combination.
*
* @param contexts The context combination
* @return Whether the operation was successful (any options were remowed)
* @return Whether the operation was successful (any options were removed)
*/
boolean clearOptions(Set<Context> contexts);

Expand Down