Skip to content

Commit 5338fe4

Browse files
committed
Added removeUserRole method to UserRoleManager
Added new userHasPermissions method overload to AuthManager Added new userHasPermissions method overload to Subject Fixed bugs and missing methods in Subject Fixed deprecated methods in NativeMethods Fixed other small bugs Updated JavaDoc Signed-off-by: Joshua Gager <[email protected]>
1 parent e34412b commit 5338fe4

File tree

242 files changed

+1555
-694
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

242 files changed

+1555
-694
lines changed

src/main/java/com/jgcomptech/tools/NativeMethods.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public static int getProductInfo(final int major, final int minor) {
3939

4040
/** Interface object to hold all the Kernel32 Instances. */
4141
public interface Kernel32 extends com.sun.jna.platform.win32.Kernel32 {
42-
Kernel32 INSTANCE = Native.loadLibrary("kernel32", Kernel32.class, W32APIOptions.DEFAULT_OPTIONS);
42+
Kernel32 INSTANCE = Native.load("kernel32", Kernel32.class, W32APIOptions.DEFAULT_OPTIONS);
4343

4444
boolean GetProductInfo(
4545
int dwOSMajorVersion,
@@ -53,7 +53,7 @@ boolean GetProductInfo(
5353

5454
/** Interface object to hold all the Shell32 Instances. */
5555
public interface Shell32 extends com.sun.jna.platform.win32.Shell32 {
56-
Shell32 INSTANCE = Native.loadLibrary("shell32", Shell32.class, W32APIOptions.DEFAULT_OPTIONS);
56+
Shell32 INSTANCE = Native.load("shell32", Shell32.class, W32APIOptions.DEFAULT_OPTIONS);
5757

5858
WinDef.HINSTANCE ShellExecuteW(WinDef.HWND hwnd,
5959
String lpOperation,
@@ -65,7 +65,7 @@ WinDef.HINSTANCE ShellExecuteW(WinDef.HWND hwnd,
6565

6666
/** Interface object to hold all the Secur32 Instances. */
6767
public interface Secur32 extends com.sun.jna.platform.win32.Secur32 {
68-
Secur32 INSTANCE = Native.loadLibrary("secur32", Secur32.class, W32APIOptions.DEFAULT_OPTIONS);
68+
Secur32 INSTANCE = Native.load("secur32", Secur32.class, W32APIOptions.DEFAULT_OPTIONS);
6969
}
7070

7171
/** Prevents instantiation of this utility class. */

src/main/java/com/jgcomptech/tools/authc/AuthManager.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
import java.time.LocalDateTime;
1313
import java.time.format.DateTimeFormatter;
14-
import java.util.HashMap;
14+
import java.util.Arrays;
1515
import java.util.HashSet;
1616
import java.util.Map;
1717

@@ -691,6 +691,17 @@ public boolean userHasPermission(final String username, final String permissionN
691691
return getUserRole(username).hasPermission(permissionName);
692692
}
693693

694+
/**
695+
* Checks if the specified username has ALL the specified permissions.
696+
* @param username the username to check
697+
* @param permissionNames a list of all the names of the permissions to check
698+
* @return true if the currently assigned username has ALL the specified permissions
699+
* @since 1.5.1 new overload
700+
*/
701+
public boolean userHasPermissions(final String username, final String... permissionNames) {
702+
return Arrays.stream(permissionNames).allMatch(permissionName -> userHasPermission(username, permissionName));
703+
}
704+
694705
/**
695706
* Checks if the specified username has ALL the specified permissions.
696707
* @param username the username to check

src/main/java/com/jgcomptech/tools/authc/SessionManager.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import org.jetbrains.annotations.Contract;
99
import org.jetbrains.annotations.Nullable;
1010

11+
import java.util.Collections;
1112
import java.util.HashMap;
1213
import java.util.Map;
1314
import java.util.Objects;
@@ -571,7 +572,7 @@ public SessionEvent getEventMultiSessionClosed() {
571572
* Returns the current logged in sessions under the multi session context.
572573
* @return the current logged in sessions under the multi session context
573574
*/
574-
public Map<String, Session> getSessions() { return multiUserSessions; }
575+
public Map<String, Session> getSessions() { return Collections.unmodifiableMap(multiUserSessions); }
575576

576577
/** Returns the username of the currently logged in user under the single session context.
577578
* @return the username of the currently logged in user under the single session context

src/main/java/com/jgcomptech/tools/authc/Subject.java

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,44 @@ public Subject(final AuthManager authManager) {
2727
* Attempts to login the specified user account from the specified token under the single-session context.
2828
* @param token the username and password token to use for login
2929
* @return true if login succeeds, false if login fails
30+
* @throws CredentialsException if the token is null, if the username or password in the specified token are null
31+
* or if the username in the specified token is an empty string
32+
* @throws ConcurrentAccessException if user is already logged in under the specified context
3033
*/
3134
@Contract("null -> fail")
32-
public boolean login(final UsernamePasswordToken token) { return login(token, false); }
35+
public boolean login(final UsernamePasswordToken token)
36+
throws CredentialsException, ConcurrentAccessException { return login(token, false); }
3337

3438
/**
3539
* Attempts to login the specified user account from the previously saved token under the single-session context.
3640
* The token is only saved if the previously supplied token had rememberMe set to true.
3741
* @return true if login succeeds, false if login fails
38-
* @throws CredentialsException if no token was previously saved
42+
* @throws CredentialsException if no token was previously saved, if the token is null,
43+
* if the username or password in the specified token are null
44+
* or if the username in the specified token is an empty string
45+
* @throws ConcurrentAccessException if user is already logged in under the specified context
3946
*/
40-
public boolean login() {
47+
public boolean login() throws CredentialsException, ConcurrentAccessException {
48+
return login(false);
49+
}
50+
51+
/**
52+
* Attempts to login the specified user account from the previously saved token under the single-session context.
53+
* The token is only saved if the previously supplied token had rememberMe set to true.
54+
* @param multiSession if true, logs in the user under the multi-session context,
55+
* or if false, under the single-session context
56+
* @return true if login succeeds, false if login fails
57+
* @throws CredentialsException if no token was previously saved, if the token is null,
58+
* if the username or password in the specified token are null
59+
* or if the username in the specified token is an empty string
60+
* @throws ConcurrentAccessException if user is already logged in under the specified context
61+
* @since 1.5.1 new overload
62+
*/
63+
public boolean login(final boolean multiSession) throws CredentialsException, ConcurrentAccessException {
4164
if(token == null || token.getUsername() == null || token.getPassword() == null) {
4265
throw new CredentialsException("Subject Credential Token Not Saved!");
4366
}
44-
return login(token, false);
67+
return login(token, multiSession);
4568
}
4669

4770
/**
@@ -50,20 +73,27 @@ public boolean login() {
5073
* @param multiSession if true, logs in the user under the multi-session context,
5174
* or if false, under the single-session context
5275
* @return true if login succeeds, false if login fails
76+
* @throws CredentialsException if the token is null, if the username or password in the specified token are null
77+
* or if the username in the specified token is an empty string
78+
* @throws ConcurrentAccessException if user is already logged in under the specified context
5379
*/
5480
@Contract("null, _ -> fail")
55-
public boolean login(final UsernamePasswordToken token, final boolean multiSession) {
81+
public boolean login(final UsernamePasswordToken token, final boolean multiSession)
82+
throws CredentialsException, ConcurrentAccessException {
5683
if(token == null) throw new CredentialsException("Login Token cannot be null!");
5784
if(token.getUsername() == null || token.getPassword() == null) {
5885
throw new CredentialsException("Login Token Username and Password cannot be null!");
5986
}
87+
if(token.getUsername().trim().isEmpty()) {
88+
throw new CredentialsException("Login Token Username cannot be empty!");
89+
}
6090
if(authManager.userExists(token.getUsername())) {
6191
final var account = authManager.getUser(token.getUsername());
6292
username = token.getUsername();
6393
final var password = token.getPassword();
6494
if (getSession(multiSession) == null) {
6595
if (authManager.checkPasswordMatches(username, new String(password))
66-
&& authManager.loginUser(username)) {
96+
&& authManager.loginUser(username, multiSession)) {
6797
if(token.isRememberMe()) {
6898
remembered = true;
6999
this.token = new UsernamePasswordToken(username, password);
@@ -166,7 +196,7 @@ public String getLastSessionDurationStringFull() {
166196
* Checks if the subject's assigned username is currently logged in.
167197
* @return true if the subject's assigned username is currently logged in
168198
*/
169-
public boolean isAuthenticated() { return username != null && getSession() != null; }
199+
public boolean isAuthenticated() { return !isAnonymous() && getSession() != null; }
170200

171201
/**
172202
* Checks if the subject's assigned username is currently logged in.
@@ -215,7 +245,7 @@ public Session getSession(final boolean multiSession) {
215245
* @return true if password is changed successfully
216246
*/
217247
public boolean setPassword(final String password) {
218-
assertAuthenticated();
248+
assertNotAnonymous();
219249
if (password == null) {
220250
throw new IllegalArgumentException("Password cannot be null!");
221251
}
@@ -247,6 +277,18 @@ public boolean hasPermission(final String permissionName) {
247277
* @return true if the currently assigned username has ALL the specified permissions
248278
*/
249279
public boolean hasPermissions(final HashSet<String> permissionNames) {
280+
assertNotAnonymous();
281+
return authManager.userHasPermissions(username, permissionNames);
282+
}
283+
284+
/**
285+
* Checks if the currently assigned username has ALL the specified permissions.
286+
* @param permissionNames a list of all the names of the permissions to check
287+
* @return true if the currently assigned username has ALL the specified permissions
288+
* @since 1.5.1 new overload
289+
*/
290+
public boolean hasPermissions(final String... permissionNames) {
291+
assertNotAnonymous();
250292
return authManager.userHasPermissions(username, permissionNames);
251293
}
252294

@@ -383,10 +425,12 @@ public boolean checkPasswordMatches(final String password) {
383425
}
384426

385427
/** Throws an UnknownAccountException if the Subject is anonymous. */
386-
private void assertNotAnonymous() { if(isAnonymous()) throw new UnknownAccountException("Subject is anonymous!"); }
428+
private void assertNotAnonymous() throws UnknownAccountException {
429+
if(isAnonymous()) throw new UnknownAccountException("Subject is anonymous!");
430+
}
387431

388432
/** Throws an UnauthenticatedException if the Subject is not authenticated. */
389-
private void assertAuthenticated() {
433+
private void assertAuthenticated() throws UnauthenticatedException {
390434
if(!isAuthenticated(false) && !isAuthenticated(true)) {
391435
throw new UnauthenticatedException("Subject is not authenticated!");
392436
}

src/main/java/com/jgcomptech/tools/authc/UserRole.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
import org.apache.commons.lang3.builder.ToStringBuilder;
77

88
import java.util.Arrays;
9+
import java.util.Collections;
910
import java.util.HashSet;
11+
import java.util.Set;
1012

1113
/**
1214
* An object representing a user account role.
@@ -59,7 +61,7 @@ public void disable() {
5961
* Returns a list of permissions assigned to the user role.
6062
* @return a list of permissions assigned to the user role
6163
*/
62-
public HashSet<String> getPermissions() { return permissions; }
64+
public Set<String> getPermissions() { return Collections.unmodifiableSet(permissions); }
6365

6466
/**
6567
* Checks if the user role has the specified permission.
@@ -209,7 +211,7 @@ public Builder add(final String name) {
209211
final var result = role.addPermission(name);
210212
if(!result) throw new IllegalStateException(
211213
"Modification Failed! Could Not Add Permission \""
212-
+ name + "\" to user role \"" + role.name + "\"!");
214+
+ name + "\" to user role \"" + role.getName() + "\"!");
213215
return this;
214216
}
215217

@@ -224,7 +226,7 @@ public Builder add(final String... names) {
224226
final var result = Arrays.stream(names).allMatch(role::addPermission);
225227
if(!result) throw new IllegalStateException(
226228
"Modification Failed! Could Not Add Permissions \""
227-
+ name + "\" to user role \"" + role.name + "\"!");
229+
+ name + "\" to user role \"" + role.getName() + "\"!");
228230
return this;
229231
}
230232

@@ -240,7 +242,7 @@ public Builder addImplicit(final String name) {
240242
final var result = role.addImplicitPermission(name);
241243
if(!result) throw new IllegalStateException(
242244
"Modification Failed! Could Not Add Implicit Permission \""
243-
+ name + "\" to user role \"" + role.name + "\"!");
245+
+ name + "\" to user role \"" + role.getName() + "\"!");
244246
return this;
245247
}
246248

@@ -256,7 +258,7 @@ public Builder addImplicit(final String... names) {
256258
final var result = Arrays.stream(names).allMatch(role::addImplicitPermission);
257259
if(!result) throw new IllegalStateException(
258260
"Modification Failed! Could Not Add Implicit Permissions \""
259-
+ name + "\" to user role \"" + role.name + "\"!");
261+
+ name + "\" to user role \"" + role.getName() + "\"!");
260262
return this;
261263
}
262264

@@ -270,7 +272,7 @@ public Builder remove(final String name) {
270272
final var result = role.removePermission(name);
271273
if(!result) throw new IllegalStateException(
272274
"Modification Failed! Could Not Remove Permission \""
273-
+ name + "\" from user role \"" + role.name + "\"!");
275+
+ name + "\" from user role \"" + role.getName() + "\"!");
274276
return this;
275277
}
276278

@@ -284,7 +286,7 @@ public Builder remove(final String... names) {
284286
final var result = Arrays.stream(names).allMatch(role::removePermission);
285287
if (!result) throw new IllegalStateException(
286288
"Modification Failed! Could Not Remove Permissions \""
287-
+ name + "\" from user role \"" + role.name + "\"!");
289+
+ name + "\" from user role \"" + role.getName() + "\"!");
288290
return this;
289291
}
290292

src/main/java/com/jgcomptech/tools/authc/UserRoleManager.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public static HashSet<String> getRoles() {
7878
* @return the new role as a UserRole object
7979
*/
8080
public UserRole createUserRole(final String name) {
81-
if(name == null || name.trim().trim().isEmpty()) {
81+
if(name == null || name.trim().isEmpty()) {
8282
throw new IllegalArgumentException("Name Cannot Be Empty!");
8383
}
8484

@@ -115,4 +115,25 @@ public void addExistingUserRole(final UserRole role) {
115115
* @return the specified user role
116116
*/
117117
public UserRole getUserRole(final String name) { return userRoles.get(name); }
118+
119+
/**
120+
* Removes the specified user role.
121+
* @param name the name of the user role to remove
122+
* @return true if no errors occurred
123+
* @since 1.5.1
124+
*/
125+
public boolean removeUserRole(final String name) {
126+
if(name == null || name.trim().isEmpty()) {
127+
throw new IllegalArgumentException("Name Cannot Be Empty!");
128+
}
129+
130+
if(SystemUserRoles.getRoles().contains(name)) {
131+
throw new IllegalArgumentException(name + " Is A System Role And Cannot Be Removed!");
132+
}
133+
134+
if(userRoles.containsKey(name)) {
135+
userRoles.remove(name);
136+
return true;
137+
} else return false;
138+
}
118139
}

src/main/java/com/jgcomptech/tools/authz/Permission.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.io.Serializable;
1313
import java.util.HashSet;
1414
import java.util.Objects;
15+
import java.util.Set;
1516

1617
/**
1718
* An object representing a permission.
@@ -169,7 +170,7 @@ public void setEnabled(final boolean enabled) {
169170
* Returns a list of child permissions.
170171
* @return a list of child permissions
171172
*/
172-
public HashSet<String> getChildPermissions() { return childPermissions; }
173+
public Set<String> getChildPermissions() { return childPermissions; }
173174

174175
/**
175176
* Checks if the permission has the specified child permission.
@@ -242,8 +243,8 @@ public boolean copyToNewParent(final String newParentName) {
242243
}
243244

244245
private void copyChildPermissions(final String newParentName,
245-
final HashSet<String> oldL,
246-
final HashSet<String> newL) {
246+
final Set<String> oldL,
247+
final Set<String> newL) {
247248
if(!oldL.isEmpty()) {
248249
for (final var permission : oldL) {
249250
newL.add(newParentName + ":" + getBaseName(permission));

src/main/java/com/jgcomptech/tools/authz/PermissionManager.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ public void setReadPermission(final boolean value) {
228228
* Returns a HashMap of all existing permission objects.
229229
* @return a HashMap of all existing permission objects
230230
*/
231-
public Map<String, Permission> getPermissions() { return permissions; }
231+
public Map<String, Permission> getPermissions() { return Collections.unmodifiableMap(permissions); }
232232

233233
/**
234234
* Returns a list of names of existing permissions.
@@ -248,7 +248,7 @@ public Permission getPermission(final String name) {
248248

249249
/**
250250
* Checks if the specified permission exists.
251-
* @param name the name of the permisssion to check
251+
* @param name the name of the permission to check
252252
* @return true if the specified permission exists
253253
* @since 1.5.0
254254
*/
@@ -322,7 +322,7 @@ public boolean isPermissionDisabled(final String name) {
322322
* @return a list of child permissions of the specified permission.
323323
* Returns null if the permission does not exist.
324324
*/
325-
public HashSet<String> getPermissionChildren(final String name) {
325+
public Set<String> getPermissionChildren(final String name) {
326326
return permissions.containsKey(name) ? permissions.get(name).getChildPermissions() : null;
327327
}
328328

@@ -332,6 +332,7 @@ public HashSet<String> getPermissionChildren(final String name) {
332332
* @param parentName the name of the parent permission, null or empty string if none
333333
* @return false if permission already exists
334334
*/
335+
//TODO: Add root permission overload
335336
public boolean addCustomPermission(final String name, final String parentName) {
336337
if(name.equals(parentName)) return false;
337338
else if(parentName == null || parentName.trim().isEmpty()) {
@@ -361,6 +362,7 @@ else if(parentName == null || parentName.trim().isEmpty()) {
361362
* @param parentName the name of the parent permission, null or empty string if none
362363
* @return false if permission already exists
363364
*/
365+
//TODO: Add root permission overload
364366
public boolean addAndEnableCustomPermission(final String name, final String parentName) {
365367
if(addCustomPermission(name, parentName)) {
366368
return parentName == null || parentName.trim().isEmpty()

src/main/java/com/jgcomptech/tools/authz/SimpleAuthorizationInfo.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.apache.commons.lang3.builder.HashCodeBuilder;
55
import org.apache.commons.lang3.builder.ToStringBuilder;
66

7+
import java.util.Collections;
78
import java.util.HashSet;
89
import java.util.Set;
910

@@ -49,7 +50,7 @@ public SimpleAuthorizationInfo(final Set<String> roles) {
4950
@Override
5051
public Set<String> getRoles() {
5152
if (roles == null) roles = new HashSet<>();
52-
return roles;
53+
return Collections.unmodifiableSet(roles);
5354
}
5455

5556
// /**

0 commit comments

Comments
 (0)