All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sirius.web.security.UserInfo Maven / Gradle / Ivy

There is a newer version: 22.2.3
Show newest version
/*
 * Made with all the love in the world
 * by scireum in Remshalden, Germany
 *
 * Copyright by scireum GmbH
 * http://www.scireum.de - [email protected]
 */

package sirius.web.security;

import com.typesafe.config.Config;
import com.typesafe.config.ConfigException;
import sirius.kernel.commons.Strings;
import sirius.kernel.commons.Value;
import sirius.kernel.di.transformers.Composable;
import sirius.kernel.di.transformers.Transformable;
import sirius.kernel.health.Exceptions;

import javax.annotation.CheckReturnValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;

/**
 * Represents an user.
 * 

* A user is authenticated using a {@link UserManager}. To obtain or modify the current user, use {@link * UserContext#getCurrentUser()} or {@link UserContext#setCurrentUser(UserInfo)}. */ public class UserInfo extends Composable { /** * This permission represents a user which was successfully authenticated by its user manager. */ public static final String PERMISSION_LOGGED_IN = "flag-logged-in"; /** * Fallback user if no user is currently available. This user has no permissions. */ public static final UserInfo NOBODY = Builder.createUser("ANONYMOUS").withUsername("(no user)").build(); private String tenantId; private String tenantName; private String userId; private String username; private String email; private String lang; private Set permissions = null; private Function configSupplier; private Function userSupplier; /** * Builder pattern to create a new {@link UserInfo}. */ public static class Builder { private UserInfo user; private Builder() { } /** * Creates a new builder and initializes it with an id for the user. * * @param id the id of the user to build. * @return the builder itself for fluent method calls */ @CheckReturnValue public static Builder createUser(@Nonnull String id) { Builder builder = new Builder(); builder.user = new UserInfo(); builder.user.userId = id; return builder; } /** * Sets the name of the user. * * @param name the name of the user. * @return the builder itself for fluent method calls */ public Builder withUsername(String name) { verifyState(); user.username = name; return this; } /** * Sets the id of the tenant the user belongs to. * * @param id the id of the tenant * @return the builder itself for fluent method calls */ public Builder withTenantId(String id) { verifyState(); user.tenantId = id; return this; } /** * Sets the name of the tenant the user belongs to. * * @param name the name of the tenant * @return the builder itself for fluent method calls */ public Builder withTenantName(String name) { verifyState(); user.tenantName = name; return this; } private void verifyState() { if (user == null) { throw new IllegalStateException("UserInfo already built."); } } /** * Sets the email address of the user. * * @param email the email address * @return the builder itself for fluent method calls */ public Builder withEmail(String email) { verifyState(); user.email = email; return this; } /** * Sets the language code of the user. * * @param lang a two-letter language code which should be understood by {@link sirius.kernel.nls.NLS}. * @return the builder itself for fluent method calls */ public Builder withLang(String lang) { verifyState(); user.lang = lang; return this; } /** * Sets the permissions granted to the user. * * @param permissions the set of permissions granted to the user * @return the builder itself for fluent method calls */ public Builder withPermissions(Set permissions) { verifyState(); user.permissions = permissions; return this; } /** * Sets a config supplier which can provide an individual configuration for the current user. * * @param configSupplier the function which fetches or computes the configuration for this user on demand. * @return the builder itself for fluent method calls */ public Builder withConfigSupplier(Function configSupplier) { verifyState(); user.configSupplier = configSupplier; return this; } /** * Sets a user supplier which returns the underlying user object (e.g. a database entity). * * @param userSupplier the function which fetches or computes the user object * @return the builder itself for fluent method calls */ public Builder withUserSupplier(Function userSupplier) { verifyState(); user.userSupplier = userSupplier; return this; } /** * Builds the user, with the previously given settings. * * @return the resulting user */ public UserInfo build() { UserInfo result = user; user = null; return result; } } protected UserInfo() { } /** * Returns the unique ID of the user. * * @return the unique ID of the user */ public String getUserId() { return userId; } /** * Returns the login or descriptive name of the user. * * @return the name of the user */ public String getUserName() { return username; } /** * The unique ID of the tenant. * * @return the unique ID the tenant the user belongs to */ @Nullable public String getTenantId() { return tenantId; } /** * The name of the tenant. * * @return the name of the tenant the user belongs to */ @Nullable public String getTenantName() { return tenantName; } /** * The email address of the user * * @return the email address of the user */ @Nullable public String getEmail() { return email; } /** * The language code of the user. * * @return the two-letter language code of the user */ public String getLang() { return lang; } /** * Determines if the user has the requested permissions * * @param permissions the permissions to check * @return true if the user has all the requested permissions, false otherwise */ public boolean hasPermissions(String... permissions) { for (String permission : permissions) { if (!hasPermission(permission)) { return false; } } return true; } /** * Determines if the user has the given permission. *

* If the permission starts with an "!", the check is inverted. * * @param permission the permission to check * @return true if the user has the permission, false otherwise */ public boolean hasPermission(String permission) { if (Strings.isEmpty(permission)) { return true; } if (permission.startsWith("!")) { return permissions == null || !permissions.contains(permission.substring(1)); } else { return permissions != null && permissions.contains(permission); } } /** * Asserts that the user has the given permission. *

* If the user does not have the given permission, an exception is thrown. * * @param permission the permission to check */ public void assertPermission(String permission) { if (!hasPermission(permission)) { throw Exceptions.createHandled() .withNLSKey("UserInfo.missingPermission") .set("permission", permission) .handle(); } } /** * Determines if the user is logged in. * * @return true if the user has the permission {@link #PERMISSION_LOGGED_IN}, false otherwise */ public boolean isLoggedIn() { return hasPermission(PERMISSION_LOGGED_IN); } /** * Fetches the underlying user object of the given type. * * @param clazz the excepted type of the user object * @param the excepted type of the user object * @return the underlying user object or null if no object is present or if it has a non matching type */ @SuppressWarnings("unchecked") @Nullable public T getUserObject(Class clazz) { if (userSupplier == null) { return null; } Object user = userSupplier.apply(this); if (user != null && clazz.isAssignableFrom(user.getClass())) { return (T) user; } return null; } @Override public boolean is(@Nonnull Class type) { Transformable userObject = getUserObject(Transformable.class); if (userObject != null) { return userObject.is(type); } return super.is(type); } @SuppressWarnings("unchecked") @Override public Optional tryAs(@Nonnull Class adapterType) { Transformable userObject = getUserObject(Transformable.class); if (userObject != null) { return userObject.tryAs(adapterType); } return super.tryAs(adapterType); } /** * Returns a set of all permissions granted to the user. * * @return all permissions granted to the user. */ public Set getPermissions() { return Collections.unmodifiableSet(permissions); } /** * Obtains the user specific config. *

* This can be used to make parts of the system behave specific to the current scope, current tenant and user. * * @return the config object which contains all settings of the current scope, current tenant and user. */ public Config getConfig() { if (configSupplier == null) { return UserContext.getCurrentScope().getConfig(); } else { return configSupplier.apply(this); } } /** * Returns the value present for the given config key. *

* This is boilerplate for {@code Value.of(getConfig().getObject(key))}. * * @param key the config key to fetch * @return the value present for the key. If the value does not exist, an empty Value is returned. */ @Nonnull public Value getConfigValue(@Nonnull String key) { try { return Value.of(getConfig().getAnyRef(key)); } catch (ConfigException e) { Exceptions.handle(e); return Value.EMPTY; } } /** * Returns the string present for the given config key. *

* This is boilerplate for {@code getConfigValue(key).asString()}. * * @param key the config key to fetch * @return the string present for the key. If the value does not exist, an empty string is returned. */ @Nonnull public String getConfigString(@Nonnull String key) { return getConfigValue(key).asString(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy