ProfileService.java
package jasper.service;
import io.micrometer.core.annotation.Timed;
import jasper.component.ProfileManager;
import jasper.errors.DeactivateSelfException;
import jasper.errors.InvalidUserProfileException;
import jasper.security.Auth;
import jasper.service.dto.ProfileDto;
import org.apache.commons.compress.utils.Sets;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.data.domain.Page;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import java.util.Set;
import static jasper.security.AuthoritiesConstants.ADMIN;
import static jasper.security.AuthoritiesConstants.ANONYMOUS;
import static jasper.security.AuthoritiesConstants.EDITOR;
import static jasper.security.AuthoritiesConstants.MOD;
import static jasper.security.AuthoritiesConstants.PRIVATE;
import static jasper.security.AuthoritiesConstants.USER;
import static jasper.security.AuthoritiesConstants.VIEWER;
@Profile("scim")
@Service
public class ProfileService {
/**
* Valid roles for a user.
*/
private static final Set<String> ROLES = Sets.newHashSet(ADMIN, MOD, EDITOR, USER, VIEWER, ANONYMOUS);
@Autowired
ProfileManager profileManager;
@Autowired
Auth auth;
@PreAuthorize("@auth.rootMod()")
@Timed(value = "jasper.service", extraTags = {"service", "profile"}, histogram = true)
public void create(String qualifiedTag, String password, String role) {
validateRole(role);
if (qualifiedTag.startsWith("user/")) {
throw new InvalidUserProfileException("User tag must be protected or private.");
}
if (!qualifiedTag.startsWith("_user/") && !qualifiedTag.startsWith("+user/")) {
throw new InvalidUserProfileException("User tag must be start with user/");
}
profileManager.createUser(qualifiedTag.substring("+user/".length()), password, getRoles(qualifiedTag, role));
}
private void validateRole(String role) {
if (role.equals(ADMIN) && !auth.hasRole(ADMIN)) {
throw new InvalidUserProfileException("Cannot assign elevated role.");
}
}
private String[] getRoles(String qualifiedTag, String role) {
if (!ROLES.contains(role)) {
throw new InvalidUserProfileException("Invalid role: " + role);
}
if (qualifiedTag.startsWith("_")) {
return new String[]{ role, PRIVATE };
} else {
return new String[]{ role };
}
}
@PreAuthorize("@auth.hasRole('VIEWER') and @auth.canReadTag(#qualifiedTag)")
@Timed(value = "jasper.service", extraTags = {"service", "profile"}, histogram = true)
public ProfileDto get(String qualifiedTag) {
return profileManager.getUser(qualifiedTag.substring("+user/".length()));
}
@PreAuthorize("@auth.rootMod()")
@Timed(value = "jasper.service", extraTags = {"service", "profile"}, histogram = true)
public Page<ProfileDto> page(int pageNumber, int pageSize) {
return profileManager.getUsers(auth.getOrigin(), pageNumber, pageSize);
}
@PreAuthorize("(@auth.isUser(#qualifiedTag) or @auth.rootMod()) and @auth.freshLogin()")
@Timed(value = "jasper.service", extraTags = {"service", "profile"}, histogram = true)
public void changePassword(String qualifiedTag, String password) {
profileManager.changePassword(qualifiedTag.substring("+user/".length()), password);
}
@PreAuthorize("@auth.hasRole('MOD') and @auth.canWriteUserTag(#qualifiedTag)")
@Timed(value = "jasper.service", extraTags = {"service", "profile"}, histogram = true)
public void changeRole(String qualifiedTag, String role) {
validateRole(role);
profileManager.changeRoles(qualifiedTag.substring("+user/".length()), getRoles(qualifiedTag, role));
}
@PreAuthorize("@auth.rootMod()")
@Timed(value = "jasper.service", extraTags = {"service", "profile"}, histogram = true)
public void setActive(String qualifiedTag, boolean active) {
if (!active && auth.getUserTag().tag.equals(qualifiedTag)) {
throw new DeactivateSelfException();
}
profileManager.setActive(qualifiedTag.substring("+user/".length()), active);
}
@PreAuthorize("@auth.rootMod()")
@Timed(value = "jasper.service", extraTags = {"service", "profile"}, histogram = true)
public void delete(String qualifiedTag) {
profileManager.deleteUser(qualifiedTag.substring("+user/".length()));
}
}