Skip to content

Commit d6adfe1

Browse files
committed
Improve JavaDocs of some API classes
1 parent e153f6d commit d6adfe1

File tree

3 files changed

+84
-74
lines changed

3 files changed

+84
-74
lines changed

src/main/java/io/quarkus/security/PermissionChecker.java

+32-6
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
/**
99
* Annotation that can be used to annotate a CDI bean method that checks
10-
* if a {@link io.quarkus.security.identity.SecurityIdentity} holds a permission specified by the {@link #value()}.
10+
* if a matching {@link PermissionsAllowed} permission with the {@link #value()} name can be granted.
1111
* For example:
1212
* <pre>
1313
* {@code
@@ -27,7 +27,7 @@
2727
* }
2828
* }
2929
* </pre>
30-
* The permission checker methods can include any of secured method parameters (matched by name).
30+
* The permission checker methods can include any of the secured method parameters, matched by name.
3131
* Consider the following secured method:
3232
* <pre>
3333
* {@code
@@ -37,8 +37,8 @@
3737
* }
3838
* }
3939
* </pre>
40-
* The permission checker that grants access to the {@code updateString} method can inject
41-
* any arguments it requires and optionally even {@link io.quarkus.security.identity.SecurityIdentity}:
40+
* The permission checker that grants access to the {@code updateString} method can include
41+
* any of the {@code updateString} method parameters, {@link io.quarkus.security.identity.SecurityIdentity} can also be included:
4242
* <pre>
4343
* {@code
4444
* &#64;PermissionChecker("update")
@@ -47,8 +47,34 @@
4747
* }
4848
* }
4949
* </pre>
50-
* The permission checker method parameters are matched with the secured method parameters in exactly same fashion
51-
* as are constructor parameters of a custom permission. Please see {@link PermissionsAllowed#params()} for more information.
50+
* The permission checker method parameters are matched with the secured method parameters exactly the same way as
51+
* the constructor parameters of a custom permission are. Please see {@link PermissionsAllowed#params()} for more information.
52+
* <pre>
53+
* If the {@link PermissionsAllowed} annotation lists several permission names and its {@link PermissionsAllowed#inclusive} property is set to `true` then an equal number of permission checker methods must be available.
54+
* Consider the following secured method:
55+
* <pre>
56+
* {@code
57+
* &#64;PermissionsAllowed(value={"read:all", "write"}, inclusive=true)
58+
* public String readWriteString(String a) {
59+
* ...
60+
* }
61+
* }
62+
* </pre>
63+
* For the access to the {@code readWriteString} method be granted, two permission checkers,
64+
* one for the `read:all` permission, and another one for the `write` permission, must be available:
65+
* <pre>
66+
* {@code
67+
* &#64;PermissionChecker("read:all")
68+
* public boolean canRead(SecurityIdentity identity) {
69+
* ...
70+
* }
71+
* &#64;PermissionChecker("write")
72+
* public boolean canWrite(SecurityIdentity identity) {
73+
* ...
74+
* }
75+
* }
76+
* </pre>
77+
* Note that a permission checker matches one of the {@link PermissionsAllowed} permissions if their String names are equal.
5278
*/
5379
@Target(ElementType.METHOD)
5480
@Retention(RetentionPolicy.RUNTIME)

src/main/java/io/quarkus/security/PermissionsAllowed.java

+35-47
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,7 @@
99
import java.security.Permission;
1010

1111
/**
12-
* Indicates that a resource can only be accessed by a user with one of permissions specified through {@link #value()}.
13-
* There are some situations where you want to require more than one permission, this can be achieved by repeating
14-
* annotation. Please see an example below:
15-
*
16-
* <pre>
17-
* &#64;PermissionsAllowed("create")
18-
* &#64;PermissionsAllowed("update")
19-
* public Resource createOrUpdate(Long id) {
20-
* // business logic
21-
* }
22-
* </pre>
23-
*
24-
* To put it another way, permissions specified by one annotation instance are disjunctive and the permission check is
25-
* only true if all annotation instances are evaluated as true.
12+
* Lists one or more required permissions that must be granted.
2613
*/
2714
@Documented
2815
@Retention(RetentionPolicy.RUNTIME)
@@ -32,7 +19,7 @@
3219

3320
/**
3421
* Constant value for {@link #params()} indicating that the constructor parameters of the {@link #permission()}
35-
* should be autodetected based on formal parameter names. For example, consider following method secured with this
22+
* should be autodetected based on formal parameter names. For example, consider the following method secured with this
3623
* annotation:
3724
* <pre>
3825
* {@code
@@ -81,7 +68,7 @@
8168

8269
/**
8370
* Colon is used to separate a {@link Permission#getName()} and an element of the {@link Permission#getActions()}.
84-
* For example, {@link StringPermission} created for method 'getResource':
71+
* For example, {@link StringPermission} created for the 'getResource' method:
8572
*
8673
* <pre>
8774
* &#64;PermissionsAllowed("resource:retrieve")
@@ -97,8 +84,9 @@
9784
String PERMISSION_TO_ACTION_SEPARATOR = ":";
9885

9986
/**
100-
* Specifies a list of permissions that grants the access to the resource. It is also possible to define permission's
101-
* actions that are permitted for the resource. Yet again, consider method 'getResource':
87+
* Specifies a list of permissions that grants access to the resource.
88+
* It is also possible to define permission actions that are permitted for the resource.
89+
* Consider the `getResource` method:
10290
*
10391
* <pre>
10492
* &#64;PermissionsAllowed({"resource:crud", "resource:retrieve", "system-resource:retrieve"})
@@ -107,15 +95,15 @@
10795
* }
10896
* </pre>
10997
*
110-
* Two {@link StringPermission}s will be created:
98+
* Two {@link StringPermission} permissions will be created:
11199
*
112100
* <pre>
113101
* var pem1 = new StringPermission("resource", "crud", "retrieve");
114102
* var pem2 = new StringPermission("system-resource", "retrieve");
115103
* </pre>
116104
*
117-
* And the permission check will pass if either {@code pem1} or {@code pem2} implies user permissions.
118-
* Technically, it is also possible to both define actions and no action for same-named permission like this:
105+
* The permission check will pass if either {@code pem1} or {@code pem2} implies user permissions.
106+
* It is also possible to combine permissions with and without actions like this:
119107
*
120108
* <pre>
121109
* &#64;PermissionsAllowed({"resource:crud", "resource:retrieve", "natural-resource"})
@@ -130,19 +118,26 @@
130118
* var pem1 = new StringPermission("resource", "crud", "retrieve");
131119
* var pem2 = new StringPermission("natural-resource");
132120
* </pre>
121+
* Alternatively, when multiple required permissions must be listed, you can repeat the annotation, for example:
122+
* <pre>
123+
* &#64;PermissionsAllowed("create")
124+
* &#64;PermissionsAllowed("update")
125+
* public Resource createOrUpdate(Long id) {
126+
// business logic
127+
* }
128+
* </pre>
133129
*
134-
* To see how the example above is evaluated, please see "implies" method of your {@link #permission()}.
135-
*
136-
* @see StringPermission#implies(Permission) for more details on how above-mentioned example is evaluated
130+
* @see StringPermission#implies(Permission) for more details on how the above example is evaluated.
137131
*
138-
* @return permissions linked to respective actions
132+
* @return permissions
139133
*/
140134
String[] value();
141135

142136
/**
143-
* Choose a relation between permissions specified via {@link #value()}. By default, at least one of permissions
144-
* is required (please see the example above). You can require all of them by setting `inclusive` to `true`.
145-
* Let's re-use same example and make permissions inclusive:
137+
* Choose a relation between multiple permissions specified in {@link #value()}.
138+
* By default, at least one of permissions must be granted.
139+
* You can request that all of the listed permissions by setting the `inclusive` property to `true`.
140+
* For example:
146141
*
147142
* <pre>
148143
* &#64;PermissionsAllowed(value = {"resource:crud", "resource:retrieve", "natural-resource"}, inclusive = true)
@@ -158,23 +153,23 @@
158153
* var pem2 = new StringPermission("system-resource", "retrieve");
159154
* </pre>
160155
*
161-
* And the permission check will pass if <b>both</b> {@code pem1} and {@code pem2} implies user permissions.
156+
* And the permission check will pass if <b>both</b> {@code pem1} and {@code pem2} imply user permissions.
162157
*
163158
* @return `true` if permissions should be inclusive
164159
*/
165160
boolean inclusive() default false;
166161

167162
/**
168163
* Mark parameters of the annotated method that should be passed to the constructor of the {@link #permission()}.
169-
* First, let's define ourselves three classes:
164+
* Consider the following three classes:
170165
*
171166
* <pre>
172167
* class ResourceIdentity { }
173168
* class User extends ResourceIdentity { }
174169
* class Admin extends ResourceIdentity { }
175170
* </pre>
176171
*
177-
* Now that we have defined parameter data types, please consider the secured method 'getResource':
172+
* Next, consider the secured 'getResource' method:
178173
*
179174
* <pre>
180175
* &#64;PermissionsAllowed(permission = UserPermission.class, value = "resource", params = {user1, admin1})
@@ -183,7 +178,7 @@
183178
* }
184179
* </pre>
185180
*
186-
* In the example above, we marked parameters {@code user1} and {@code admin1} as {@link #permission()} constructor
181+
* In the example above, the parameters {@code user1} and {@code admin1} are marked as {@link #permission()} constructor
187182
* arguments:
188183
*
189184
* <pre>
@@ -202,19 +197,13 @@
202197
* }
203198
* </pre>
204199
*
205-
* Please mention that:
200+
* Please note that:
206201
* <ul>
207-
* <li>constructor parameter names {@code user1} and {@code admin1} must exactly match respective "params",</li>
208-
* <li>"ResourceIdentity" could be used as constructor parameter data type, for "User" and "Admin" are assignable
209-
* from "ResourceIdentity",</li>
210-
* <li>"getResource" parameters {@code user} and {@code admin} are not passed to the "UserPermission" constructor.</li>
202+
* <li>The constructor parameter names {@code user1} and {@code admin1} must match respective {@code PermissionsAllowed#params}</li>
203+
* <li>`ResourceIdentity` can also be used as a constructor parameter data type</li>
211204
* </ul>
212205
*
213-
* When this annotation is used as the class-level annotation, same requirements are put on every single secured method.
214-
*
215-
* <p>
216-
* <b>WARNING:</b> "params" attribute is only supported in the scenarios explicitly named in the Quarkus documentation.
217-
* </p>
206+
* When this annotation is used as the class-level annotation, it applies to every secured method in the class.
218207
*
219208
* Method parameter fields or methods can be passed to a Permission constructor as well.
220209
* Consider the following secured method and its parameters:
@@ -252,8 +241,8 @@
252241
* }
253242
* </pre>
254243
*
255-
* Here, the constructor parameter {@code param1} refers to the {@code admin1#param1} secured method parameter
256-
* and the constructor parameter {@code param3} to the {@code user1#getParam3} secured method parameter.
244+
* The constructor parameter {@code param1} refers to the {@code admin1#param1} secured method parameter
245+
* and the constructor parameter {@code param3} refers to the {@code user1#getParam3} secured method parameter.
257246
*
258247
* @see #AUTODETECTED
259248
*
@@ -262,7 +251,7 @@
262251
String[] params() default AUTODETECTED;
263252

264253
/**
265-
* The class that extends the {@link Permission} class, used to create permissions specified via {@link #value()}.
254+
* The class that extends the {@link Permission} class to create a permission specified in {@link #value()}.
266255
*
267256
* For example:
268257
*
@@ -287,8 +276,7 @@
287276
Class<? extends Permission> permission() default StringPermission.class;
288277

289278
/**
290-
* The repeatable holder for {@link PermissionsAllowed}. The annotation is not repeatable on class-level as
291-
* repeatable interceptor bindings declared on classes are not supported by Quarkus.
279+
* The repeatable holder for {@link PermissionsAllowed}. The annotation can only be repeatable on methods.
292280
*/
293281
@Target(ElementType.METHOD)
294282
@Retention(RetentionPolicy.RUNTIME)

src/main/java/io/quarkus/security/identity/SecurityIdentity.java

+17-21
Original file line numberDiff line numberDiff line change
@@ -4,51 +4,49 @@
44
import java.security.Principal;
55
import java.util.Map;
66
import java.util.Set;
7-
import java.util.concurrent.CompletionStage;
87

98
import io.quarkus.security.credential.Credential;
109
import io.smallrye.mutiny.Uni;
1110

1211
/**
13-
* Interface that represents the currently logged in user.
12+
* Interface that represents the current security identity such as a logged-in user or other authenticated subject.
1413
* <p>
15-
* Instances of this class will always be available for injection even if no user is currently
16-
* logged in. In this case {@link #isAnonymous()} will return <code>true</code>, and the user
17-
* will generally not have any roles (although some implementation may assign roles to anonymous users).
14+
* Instances of this class will always be available for injection even if no authentication has taken place.
15+
* In this case {@link #isAnonymous()} will return <code>true</code>, and the security identity will generally have no roles.
1816
* <p>
1917
* Implementations should be immutable.
2018
*/
2119
public interface SecurityIdentity {
2220

2321
/**
24-
* The attribute name that is used to store the underlying user representation.
22+
* The attribute name that is used to store the underlying security identity representation.
2523
*/
2624
String USER_ATTRIBUTE = "quarkus.user";
2725

2826
/**
29-
* @return the {@link Principal} representing the current user.
27+
* @return the {@link Principal} representing the current security identity.
3028
*/
3129
Principal getPrincipal();
3230

3331
/**
3432
* @param clazz {@link Principal} subclass
35-
* @return the {@link Principal} subclass representing the current user.
33+
* @return the {@link Principal} subclass representing the current security identity.
3634
*/
3735
default <T extends Principal> T getPrincipal(Class<T> clazz) {
3836
return clazz.cast(getPrincipal());
3937
}
4038

4139
/**
42-
* @return <code>true</code> if this identity represents an anonymous (i.e. not logged in) user
40+
* @return <code>true</code> if this identity is anonymous
4341
*/
4442
boolean isAnonymous();
4543

4644
/**
47-
* Returns the set of all roles held by the user. These roles must be resolvable in advance for every request.
45+
* Returns the set of all roles held by the security identity. These roles must be resolvable in advance for every request.
4846
* <p>
4947
* Note that roles are returned on a best effort basis. To actually check if
5048
* a user holds a role {@link #hasRole(String)} should be used instead. Some API's (e.g. JAX-RS) do not allow
51-
* for all roles to be returned, so if the underlying user representation does not support retrieving all the roles
49+
* for all roles to be returned, so if the underlying identity representation does not support retrieving all the roles
5250
* this method will not always be reliable. In general all built in Quarkus security extensions should provide this,
5351
* unless it is documented otherwise.
5452
*
@@ -61,7 +59,7 @@ default <T extends Principal> T getPrincipal(Class<T> clazz) {
6159
Set<String> getRoles();
6260

6361
/**
64-
* Checks if a user has a given role. These roles must be resolvable in advance for every request.
62+
* Checks if a security identity has a given role. These roles must be resolvable in advance for every request.
6563
* <p>
6664
* If more advanced authorization support is required than can be provided by a simple role based system
6765
* then {@link #checkPermission(Permission)} and {@link #checkPermissionBlocking(Permission)} should be used
@@ -73,7 +71,7 @@ default <T extends Principal> T getPrincipal(Class<T> clazz) {
7371
boolean hasRole(String role);
7472

7573
/**
76-
* Gets the users credential of the given type, or <code>null</code> if a credential of the given type is not
74+
* Gets the security identity credential of the given type, or <code>null</code> if a credential of the given type is not
7775
* present.
7876
*
7977
* @param credentialType The type of the credential
@@ -83,7 +81,7 @@ default <T extends Principal> T getPrincipal(Class<T> clazz) {
8381
<T extends Credential> T getCredential(Class<T> credentialType);
8482

8583
/**
86-
* Returns a set of all credentials owned by this user.
84+
* Returns a set of all credentials owned by this security identity.
8785
*
8886
* @return a set of all credentials
8987
*/
@@ -111,24 +109,22 @@ default <T extends Principal> T getPrincipal(Class<T> clazz) {
111109
Map<String, Object> getAttributes();
112110

113111
/**
114-
* Checks if a user holds a given permissions, and if so will return <code>true</code>.
112+
* Checks if a security identity holds a given permission.
115113
* <p>
116114
* This method is asynchronous, as it may involve calls to a remote resource.
117115
*
118116
* @param permission The permission
119-
* @return A completion stage that will resolve to true if the user has the specified permission
117+
* @return Uni that will resolve to true if the security identity has the specified permission
120118
*/
121119
Uni<Boolean> checkPermission(Permission permission);
122120

123121
/**
124-
* Checks if a user holds a given permissions, and if so will return <code>true</code>.
122+
* Checks if a user holds a given permission.
125123
* <p>
126-
* This method is a blocking version of {@link #checkPermission(Permission)}. By default it will
127-
* just wait for the {@link CompletionStage} to be complete, however it is likely that some implementations
128-
* will want to provide a more efficient version.
124+
* This method is a blocking version of {@link #checkPermission(Permission)}..
129125
*
130126
* @param permission The permission
131-
* @return A completion stage that will resolve to true if the user has the specified permission
127+
* @return true if the security identity has the specified permission
132128
*/
133129
default boolean checkPermissionBlocking(Permission permission) {
134130
return checkPermission(permission).await().indefinitely();

0 commit comments

Comments
 (0)