Skip to content

Commit

Permalink
Refactored security utils, implemented login/logout.
Browse files Browse the repository at this point in the history
  • Loading branch information
nmihajlovski committed Mar 1, 2016
1 parent a434a45 commit c6b702c
Show file tree
Hide file tree
Showing 26 changed files with 641 additions and 383 deletions.
11 changes: 5 additions & 6 deletions rapidoid-commons/src/main/java/org/rapidoid/ctx/Current.java
Expand Up @@ -37,21 +37,20 @@ public static boolean hasContext() {

public static UserInfo user() {
Ctx ctx = Ctxs.get();
return ctx != null ? ctx.user() : null;
UserInfo user = ctx != null ? ctx.user() : null;
return U.or(user, UserInfo.ANONYMOUS);
}

public static boolean isLoggedIn() {
return user() != null;
return user().username != null;
}

public static String username() {
UserInfo user = user();
return user != null ? user.username : null;
return user().username;
}

public static Set<String> roles() {
UserInfo user = user();
return U.safe(user != null && user.roles != null ? U.set(user.roles) : U.<String>set());
return user().roles;
}

public static Req request() {
Expand Down
49 changes: 18 additions & 31 deletions rapidoid-commons/src/main/java/org/rapidoid/ctx/UserInfo.java
Expand Up @@ -2,10 +2,10 @@

import org.rapidoid.annotation.Authors;
import org.rapidoid.annotation.Since;
import org.rapidoid.security.Roles;
import org.rapidoid.u.U;

import java.io.Serializable;
import java.util.Collections;
import java.util.Map;
import java.util.Set;

Expand Down Expand Up @@ -35,45 +35,25 @@ public class UserInfo implements Serializable {

private static final long serialVersionUID = 7062732348562440194L;

private static final UserInfo ANONYMOUS = new UserInfo("anonymous", null, "Anonymous", null, null, U.<String>set());
public static final UserInfo ANONYMOUS = new UserInfo(null, U.<String>set());

public final String username;

public final String email;

public final String name;

public final String oauthId;

public final String oauthProvider;

public final Set<String> roles;

public final Map<String, Boolean> is;

public UserInfo(String username) {
this(username, username, username);
}
public volatile String email;

public UserInfo(String username, Set<String> roles) {
this(username, username, username, null, null, roles);
}
public volatile String name;

public UserInfo(String username, String email, String name) {
this(username, email, name, null, null);
}
public volatile String oauthId;

public UserInfo(String username, String email, String name, String oauthId, String oauthProvider) {
this(username, email, name, oauthId, oauthProvider, Roles.getRolesFor(username));
}
public volatile String oauthProvider;

public UserInfo(String username, String email, String name, String oauthId, String oauthProvider, Set<String> roles) {
public UserInfo(String username, Set<String> roles) {
this.username = username;
this.email = email;
this.name = name;
this.oauthId = oauthId;
this.oauthProvider = oauthProvider;
this.roles = roles;
this.roles = Collections.unmodifiableSet(U.safe(roles));
this.is = rolesMap(roles);
}

Expand All @@ -84,13 +64,20 @@ private static Map<String, Boolean> rolesMap(Set<String> roles) {
rolesMap.put(role, true);
}

return rolesMap;
return Collections.unmodifiableMap(rolesMap);
}

@Override
public String toString() {
return "UserInfo [username=" + username + ", email=" + email + ", name=" + name + ", oauthId=" + oauthId
+ ", oauthProvider=" + oauthProvider + "]";
return "UserInfo{" +
"username='" + username + '\'' +
", roles=" + roles +
", is=" + is +
", email='" + email + '\'' +
", name='" + name + '\'' +
", oauthId='" + oauthId + '\'' +
", oauthProvider='" + oauthProvider + '\'' +
'}';
}

@Override
Expand Down
12 changes: 12 additions & 0 deletions rapidoid-commons/src/main/java/org/rapidoid/http/Resp.java
Expand Up @@ -203,4 +203,16 @@ public interface Resp {
*/
Req request();

/**
* Initiates a user login process with the specified <b>username</b> and <b>password</b>.<br>
* Returns information whether the login was successful. After a successful login, the username will be persisted
* in the cookie-pack.
*/
boolean login(String username, String password);

/**
* Initiates a user logout process, clearing the login information (username) from the cookie-pack.
*/
void logout();

}
Expand Up @@ -81,7 +81,7 @@ public boolean canAccessClass(String username, Class<?> clazz) {
return true;
}

public boolean hasRole(String username, String role, Class<?> clazz, Object record) {
public boolean hasRole(String username, Set<String> roles, String role, Class<?> clazz, Object record) {

if (Roles.ANYBODY.equalsIgnoreCase(role)) {
return true;
Expand All @@ -102,14 +102,14 @@ public boolean hasRole(String username, String role, Class<?> clazz, Object reco
}
}

return hasRole(username, role);
return hasRole(username, roles, role);
}

protected boolean hasSpecialRoleInDevMode(String username, String role) {
return false;
}

protected boolean hasRole(String username, String role) {
protected boolean hasRole(String username, Set<String> roles, String role) {
if (hasSpecialRoleInDevMode(username, role)) {
return true;
}
Expand All @@ -118,19 +118,25 @@ protected boolean hasRole(String username, String role) {
return !U.isEmpty(username);
}

return Roles.getRolesFor(username).contains(role.toLowerCase());
for (String r : roles) {
if (r.equalsIgnoreCase(role)) {
return true;
}
}

return false;
}

public boolean isAdmin(String username) {
return hasRole(username, Roles.ADMIN, null, null);
public boolean isAdmin(String username, Set<String> roles) {
return hasRole(username, roles, Roles.ADMIN, null, null);
}

public boolean isManager(String username) {
return hasRole(username, Roles.MANAGER, null, null);
public boolean isManager(String username, Set<String> roles) {
return hasRole(username, roles, Roles.MANAGER, null, null);
}

public boolean isModerator(String username) {
return hasRole(username, Roles.MODERATOR, null, null);
public boolean isModerator(String username, Set<String> roles) {
return hasRole(username, roles, Roles.MODERATOR, null, null);
}

public DataPermissions classPermissions(String username, Class<?> clazz) {
Expand Down
84 changes: 84 additions & 0 deletions rapidoid-commons/src/main/java/org/rapidoid/security/Auth.java
@@ -0,0 +1,84 @@
package org.rapidoid.security;

import org.rapidoid.annotation.Authors;
import org.rapidoid.annotation.Since;
import org.rapidoid.commons.Coll;
import org.rapidoid.config.Conf;
import org.rapidoid.config.Config;
import org.rapidoid.u.U;

import java.util.Collection;
import java.util.Collections;
import java.util.Set;

/*
* #%L
* rapidoid-commons
* %%
* Copyright (C) 2014 - 2016 Nikolche Mihajlovski and contributors
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/

@Authors("Nikolche Mihajlovski")
@Since("5.1.0")
public class Auth {

@SuppressWarnings("unchecked")
public static Set<String> getRolesFor(String username) {
if (U.isEmpty(username)) {
return U.set();
}

Config user = Conf.USERS.sub(username);

if (user.isEmpty()) {
return U.set();
}

Object roles = user.entry("roles").getOrNull();

if (Coll.isCollection(roles)) {
Set<String> roleSet = U.set();

for (String role : (Collection<String>) roles) {
roleSet.add(role.toLowerCase());
}

return roleSet;

} else if (roles instanceof String) {
Set<String> roleSet = U.set();

for (String role : ((String) roles).toLowerCase().split("\\s*\\,\\s*")) {
role = role.trim();
if (U.notEmpty(role)) {
roleSet.add(role);
}
}

return roleSet;

} else {
return Collections.emptySet();
}
}

public static boolean login(String username, String password) {
Config user = Conf.USERS.sub(username);

return !user.isEmpty() && U.eq(password, user.entry("password").str().getOrNull());
}

}
41 changes: 0 additions & 41 deletions rapidoid-commons/src/main/java/org/rapidoid/security/Roles.java
Expand Up @@ -2,12 +2,6 @@

import org.rapidoid.annotation.Authors;
import org.rapidoid.annotation.Since;
import org.rapidoid.commons.Coll;
import org.rapidoid.config.Conf;
import org.rapidoid.config.Config;
import org.rapidoid.u.U;

import java.util.*;

/*
* #%L
Expand Down Expand Up @@ -51,39 +45,4 @@ public class Roles {

public static final String RESTARTER = "restarter";

public static final List<String> COMMON_ROLES = Collections.unmodifiableList(Arrays.asList(ADMIN, MANAGER,
MODERATOR, LOGGED_IN, OWNER, RESTARTER));

public static final Set<String> ROLES_LOGGED_IN = U.set(LOGGED_IN);

@SuppressWarnings("unchecked")
public static Set<String> getRolesFor(String username) {
if (U.isEmpty(username)) {
return U.set();
}

Config user = Conf.USERS.sub(username);

if (user.isEmpty()) {
return U.set();
}

Object roles = user.entry("roles").getOrNull();

if (Coll.isCollection(roles)) {
Set<String> roleSet = U.set();
for (String role : (Collection<String>) roles) {
roleSet.add(role.toLowerCase());
}
return roleSet;

} else if (roles instanceof String) {
String role = (String) roles;
return U.set(role.toLowerCase().split("\\s*\\,\\s*"));

} else {
return ROLES_LOGGED_IN;
}
}

}

0 comments on commit c6b702c

Please sign in to comment.