Package ch.rswk.meta.engine
Class UserService
java.lang.Object
com.google.common.util.concurrent.AbstractIdleService
ch.rswk.meta.engine.AbstractEngineIdleService<UserService.UserServiceConfig>
ch.rswk.meta.engine.UserService
- All Implemented Interfaces:
EngineServices.ConfigurableService<UserService.UserServiceConfig>,EngineServices.InfoProvidingService,com.google.common.util.concurrent.Service,com.yubico.webauthn.CredentialRepository
@Singleton
public class UserService
extends AbstractEngineIdleService<UserService.UserServiceConfig>
implements com.yubico.webauthn.CredentialRepository
UserService provides CRUD functionality for all user entities. Uses a
LuceneService to store the user entities.
Provides authentication, authorization, verification and other access control functionality.
Passwords are stored using SCrypt (implemented by
wg/scrypt). Passwords are optional, since it's possible to use
OTP or WebAuthn. OTPs are 6 digit
strings like 123 456 and can use SMS, e-mail, webhook or
TOTP. OTPs can also be used as a second factor.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate classstatic final recordprivate classstatic final recordprivate static final recordprivate static enumprivate static final recordprivate static final recordprivate static final recordstatic final recordstatic final recordprivate classprivate static final recordstatic final recordstatic final recordstatic final recordstatic final recordstatic final recordstatic final recordstatic final recordstatic final recordstatic final recordprivate static final recordstatic final recordstatic final recordstatic enumNested classes/interfaces inherited from interface com.google.common.util.concurrent.Service
com.google.common.util.concurrent.Service.Listener, com.google.common.util.concurrent.Service.State -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate static final Protocol.ErrorReplyFactoryprivate static final Protocol.ErrorReplyFactoryprivate static final intprivate com.codahale.metrics.Meterprivate com.codahale.metrics.Meterprivate SecretKeyprivate com.codahale.metrics.Meterprivate final BackupServiceprivate static final Durationprivate static final com.google.common.base.CharMatcherprivate com.codahale.metrics.Meterprivate final Map<String, ClientListEntry> private static final Protocol.ErrorReplyFactoryprivate static final com.fasterxml.jackson.databind.ObjectReaderprivate com.github.benmanes.caffeine.cache.AsyncLoadingCache<String, Optional<MetaUserConfig>> private com.codahale.metrics.Meterprivate com.codahale.metrics.Meterprivate static final Protocol.ErrorReplyFactoryprivate com.codahale.metrics.Meterprivate final com.google.common.collect.Multiset<String> private com.codahale.metrics.Meterprivate final GatewayServiceprivate static final Protocol.ErrorReplyFactoryprivate static final com.fasterxml.jackson.databind.ObjectReaderprivate com.github.benmanes.caffeine.cache.AsyncLoadingCache<String, Optional<MetaUserGroup>> private com.codahale.metrics.Meterprivate com.codahale.metrics.Meterprivate com.codahale.metrics.Meterprivate static final Protocol.ErrorReplyFactoryprivate static final Protocol.ErrorReplyFactoryprivate static final Protocol.ErrorReplyFactoryprivate static final Protocol.ErrorReplyFactoryprivate static final Protocol.ErrorReplyFactoryprivate static final org.slf4j.Loggerprivate com.codahale.metrics.Meterprivate com.codahale.metrics.Meterprivate final LuceneServiceprivate static final Protocol.ErrorReplyFactoryprivate static final Protocol.ErrorReplyFactoryprivate static final Protocol.ErrorReplyFactoryprivate static final Protocol.ErrorReplyFactoryprivate static final intprivate static final Protocol.ErrorReplyFactoryprivate static final Stringprivate static final Protocol.ErrorReplyFactoryprivate com.github.benmanes.caffeine.cache.Cache<String, UserService.OtpChallenge> private com.codahale.metrics.Meterprivate com.codahale.metrics.Timerprivate Patternprivate static final SecureRandomprivate com.codahale.metrics.Meterprivate com.codahale.metrics.Meterprivate com.codahale.metrics.Meterprivate com.codahale.metrics.Meterprivate com.codahale.metrics.Meterprivate static final Protocol.ErrorReplyFactoryprivate static final Stringprivate com.github.benmanes.caffeine.cache.Cache<String, OffsetDateTime> private SecretKeyprivate com.codahale.metrics.Meterprivate static final intprivate static final Stringstatic final longprivate com.codahale.metrics.Meterprivate static final Protocol.ErrorReplyFactoryprivate static final Protocol.ErrorReplyFactorystatic final Stringprivate static final Stringstatic final Stringprivate static final Stringprivate static final Stringprivate static final com.fasterxml.jackson.databind.ObjectReaderprivate com.github.benmanes.caffeine.cache.AsyncLoadingCache<String, Optional<UserService.UserCacheEntry>> private com.codahale.metrics.Meterprivate com.codahale.metrics.Meterprivate com.github.benmanes.caffeine.cache.Cache<String, UserService.PendingUserValidation> private com.codahale.metrics.Meterprivate com.github.benmanes.caffeine.cache.Cache<String, com.google.common.util.concurrent.SettableFuture<Void>> private com.codahale.metrics.Meterprivate com.codahale.metrics.Meterprivate com.codahale.metrics.Meterprivate com.codahale.metrics.Meterprivate static final Protocol.ErrorReplyFactoryprivate static final com.fasterxml.jackson.core.type.TypeReference<com.yubico.webauthn.data.PublicKeyCredential<com.yubico.webauthn.data.AuthenticatorAssertionResponse, com.yubico.webauthn.data.ClientAssertionExtensionOutputs>> private static final Stringprivate static final com.google.common.base.CharMatcherprivate static final com.fasterxml.jackson.databind.ObjectMapperprivate static final Protocol.ErrorReplyFactoryprivate static final com.fasterxml.jackson.core.type.TypeReference<com.yubico.webauthn.data.PublicKeyCredential<com.yubico.webauthn.data.AuthenticatorAttestationResponse, com.yubico.webauthn.data.ClientRegistrationExtensionOutputs>> private static final Stringprivate com.github.benmanes.caffeine.cache.Cache<String, com.yubico.webauthn.AssertionRequest> private com.github.benmanes.caffeine.cache.Cache<String, com.yubico.webauthn.data.PublicKeyCredentialCreationOptions> private com.yubico.webauthn.RelyingPartyprivate static final Protocol.ErrorReplyFactoryprivate final com.google.common.util.concurrent.Monitorprivate com.codahale.metrics.Meterprivate static final Protocol.ErrorReplyFactoryprivate com.codahale.metrics.MeterFields inherited from class ch.rswk.meta.engine.AbstractEngineIdleService
runtime -
Constructor Summary
ConstructorsConstructorDescriptionUserService(BackupService backupService, UserService.UserServiceConfig config, GatewayService gatewayService, LuceneService luceneService, EngineRuntime runtime) -
Method Summary
Modifier and TypeMethodDescriptioncom.google.common.util.concurrent.ListenableFuture<AuthReply> auth(String clientId, String ipAddress, AuthRequest request, String user) com.google.common.util.concurrent.ListenableFuture<AuthTokenReply> authToken(String clientId, String ipAddress, AuthTokenRequest request, String user) private Optional<ErrorReplyException> checkAttempts(int attempts, String identifier) checkAttempts(String... identifiers) com.google.common.util.concurrent.ListenableFuture<UserConfigSearchReply> configSearch(UserConfigSearchRequest request) static com.google.common.util.concurrent.ListenableFuture<Void> configSearchRecursive(Executor executor, Function<UserConfigSearchReply, com.google.common.util.concurrent.ListenableFuture<?>> replyConsumer, UserConfigSearchRequest request, Function<UserConfigSearchRequest, com.google.common.util.concurrent.ListenableFuture<UserConfigSearchReply>> service) com.google.common.util.concurrent.ListenableFuture<UserConfigWriteReply> configWrite(UserConfigWriteRequest request) private voidprivate com.google.common.util.concurrent.ListenableFuture<Void> deleteConfigs(String query) private voidprivate LuceneService.SearchResultexecuteLuceneGroupSearch(LuceneService.LuceneContext context, UserGroupSearchRequest request) private LuceneService.SearchResultexecuteLuceneUserSearch(LuceneService.LuceneContext context, UserSearchRequest request) findUserForHandle(com.yubico.webauthn.data.ByteArray userHandle) private Optional<ErrorReply> finishWebAuthnAssertion(AuthRequest.AuthRequestWebAuthnAssertionReply assertionReply, String clientId, @Nullable String ipAddress, String user) private Optional<MetaUser.MetaUserWebAuthn> finishWebAuthnRegistration(UserWriteRequest.UserWriteRequestWebAuthnReply createReply, String user) private StringforgeEmailAndPhoneQuery(@Nullable String email, String emailField, @Nullable String phone, String phoneField) static StringgenerateScryptHash(int cpu, int memory, String secret) static UserService.GeneratedOtpgenerateScryptOtp(int scryptCpu, int scryptMemory) generateToken(UserService.TokenRequest request) static StringgenerateTotp(long offset, String totpKey) generateTotp generates a totp from the given key based on the current time plus offset.static Stringcom.google.common.util.concurrent.ListenableFuture<UserService.UserTokenReply> generateUserToken(@Nullable String clientId, String ipAddress, UserService.UserTokenRequest request) generateUserToken authenticates the given user/password and generates a token containing all grants for user and its groups.com.google.common.util.concurrent.ListenableFuture<Optional<MetaUserConfig>> getCachedConfig(String configId) com.google.common.util.concurrent.ListenableFuture<Optional<MetaUserGroup>> getCachedGroup(String group) com.google.common.util.concurrent.ListenableFuture<Optional<UserService.UserCacheEntry>> getCachedUser(String user) com.google.common.util.concurrent.ListenableFuture<ClientListReply> getClientList(ClientListRequest request) Set<com.yubico.webauthn.data.PublicKeyCredentialDescriptor> getCredentialIdsForUsername(String username) Optional<com.yubico.webauthn.data.ByteArray> getUserHandleForUsername(String username) getUsernameForUserHandle(com.yubico.webauthn.data.ByteArray userHandle) private static MetaUsergetUserWithAddedAndRemovedGrants(UserWriteUpdateRequest request, UserSearchReply searchReply) com.google.common.util.concurrent.ListenableFuture<UserGroupSearchReply> groupSearch(UserGroupSearchRequest request) static com.google.common.util.concurrent.ListenableFuture<Void> groupSearchRecursive(Executor executor, Function<UserGroupSearchReply, com.google.common.util.concurrent.ListenableFuture<?>> replyConsumer, UserGroupSearchRequest request, Function<UserGroupSearchRequest, com.google.common.util.concurrent.ListenableFuture<UserGroupSearchReply>> service) com.google.common.util.concurrent.ListenableFuture<UserGroupWriteReply> groupWrite(UserGroupWriteRequest request) com.google.common.util.concurrent.ListenableFuture<UserGroupWriteUpdateReply> private static booleanhasRequiredGrants(io.jsonwebtoken.Claims claims, @Nullable Map<String, Integer> requiredGrants) com.google.common.util.concurrent.ListenableFuture<Boolean> hasUserPermission(int permission, String userName, String... keys) hasUserPermission checks if user has required permission for at least onf of keys.com.google.common.util.concurrent.ListenableFuture<Boolean> private com.google.common.util.concurrent.ListenableFuture<UserService.UserConfigResult> loadUserConfigs(Set<String> groups, String user) com.google.common.util.concurrent.ListenableFuture<LoginReply> login(String clientId, String ipAddress, LoginRequest request) private com.google.common.util.concurrent.ListenableFuture<LoginReply> loginWithPassword(String clientId, String ipAddress, @Nullable String locale, @Nullable String password, @Nullable String login) private com.google.common.util.concurrent.ListenableFuture<LoginReply> loginWithToken(String clientId, String ipAddress, String token) com.google.common.util.concurrent.ListenableFuture<LogoutReply> logout(String clientId, LogoutRequest request) Optional<com.yubico.webauthn.RegisteredCredential> lookup(com.yubico.webauthn.data.ByteArray credentialId, com.yubico.webauthn.data.ByteArray userHandle) Set<com.yubico.webauthn.RegisteredCredential> lookupAll(com.yubico.webauthn.data.ByteArray credentialId) lookupUserByPhoneAndEmail(String email, String phone) private UserGroupSearchReplyprivate static @Nullable MetaUsernewMaskedUser(@Nullable MetaUser user) private static @Nullable MetaUser.MetaUserWebAuthnnewMaskedWebAuthn(@Nullable MetaUser.MetaUserWebAuthn webAuthn) private UserSearchReplynewUserSearchReply(boolean mask, LuceneService.SearchResult result) private com.google.common.util.concurrent.ListenableFuture<UserConfigWriteReply> processConfigWrite(UserConfigWriteRequest request) private com.google.common.util.concurrent.ListenableFuture<UserGroupWriteReply> processGroupWrite(UserGroupWriteRequest request) private com.google.common.util.concurrent.ListenableFuture<UserGroupWriteUpdateReply> private com.google.common.util.concurrent.ListenableFuture<UserWriteReply> processUserWrite(UserWriteRequest request) private com.google.common.util.concurrent.ListenableFuture<UserWriteUpdateReply> voidrecordFailedAttempt(@Nullable String clientId, @Nullable String ipAddress, String source, @Nullable String user) com.google.common.util.concurrent.ListenableFuture<RecoverUserReply> recoverUser(String clientId, String ipAddress, RecoverUserRequest request) com.google.common.util.concurrent.ListenableFuture<ResetPasswordReply> resetPassword(String clientId, String ipAddress, ResetPasswordRequest request) private static Stringprivate static StringsanitizeOtp(String otp) private static @Nullable StringsanitizeWebAuthnDisplayName(String displayName) protected voidshutDown()private com.google.common.util.concurrent.ListenableFuture<Void> startOtpChallenge(String clientId, UserService.UserServiceContactConfig contact, String ipAddress, @Nullable String locale, UserService.OtpChallengeType type, String user, MetaUser.MetaUserOtp userOtp) protected voidstartUp()com.google.common.util.concurrent.ListenableFuture<Void> startVerifyOtp(String clientId, @Nullable UserService.UserServiceContactConfig contact, String ipAddress, @Nullable String locale, String user, MetaUser.MetaUserOtp userOtp) startWebAuthnAssertion(String clientId, String user) startWebAuthnRegistration(String displayName, @Nullable String existingUserHandle, String user) com.google.common.util.concurrent.ListenableFuture<String> startWebhookAuth(String authRef) voidupdateClientList(ClientListEntry entry) private voidupdateUserCache(String user) com.google.common.util.concurrent.ListenableFuture<UserSearchReply> userSearch(UserSearchRequest request) protected com.google.common.util.concurrent.ListenableFuture<UserSearchReply> userSearchInternal(boolean mask, UserSearchRequest request) static com.google.common.util.concurrent.ListenableFuture<Void> userSearchRecursive(Executor executor, Function<UserSearchReply, com.google.common.util.concurrent.ListenableFuture<?>> replyConsumer, UserSearchRequest request, Function<UserSearchRequest, com.google.common.util.concurrent.ListenableFuture<UserSearchReply>> service) com.google.common.util.concurrent.ListenableFuture<UserWriteReply> userWrite(@Nullable String clientId, boolean enforce, @Nullable String ipAddress, UserWriteRequest request) userWrite processesUserWriteRequest.protected com.google.common.util.concurrent.ListenableFuture<UserWriteReply> userWriteInternal(@Nullable String clientId, boolean enforce, boolean hashed, @Nullable String ipAddress, boolean mask, UserWriteRequest request) com.google.common.util.concurrent.ListenableFuture<UserWriteUpdateReply> userWriteUpdate(UserWriteUpdateRequest request) private static UserService.PasswordValidationvalidatePassword(String existingPassword, boolean hashed, String password, @Nullable Pattern passwordRegex, int scryptCpu, int scryptMemory) private static UserService.OtpValidationvalidateUserOtp(@Nullable UserService.UserServiceEnforceConfig enforceConfig, @Nullable MetaUser.MetaUserOtp existingUserOtp, boolean hashed, @Nullable UserService.PendingUserValidation pendingUserValidation, @Nullable MetaUser.MetaUserOtp userOtp) validateUserWrite(@Nullable String clientId, boolean enforce, boolean hashed, @Nullable String ipAddress, UserWriteRequest request, MetaUser user, @Nullable UserService.UserCacheEntry cacheEntry, String userName) private Optional<ErrorReply> verifyOtpChallenge(String clientId, String ipAddress, String otp, UserService.OtpChallengeType type, String user) private booleanverifyPassword(@Nullable String password, MetaUser user) booleanverifyScryptHash(@Nullable String hash, @Nullable String secret) booleanverifyScryptOtp(@Nullable String hash, @Nullable String otp) verifyToken(@Nullable String clientId, String ipAddress, UserService.VerifyTokenRequest request) static booleanverifyTotp(int acceptedCodes, String totpKey, @Nullable String totp) verifyTotp generates codes from the given key and compares them to the given totp.booleanverifyTotp(String totpKey, @Nullable String totp) voidverifyWebhookAuth(String authRef, String otp) private voidwriteGroup(WriteAction action, @Nullable MetaUserGroup existingGroup, MetaUserGroup group, org.apache.lucene.index.IndexWriter writer) private voidwriteUser(WriteAction action, @Nullable org.apache.lucene.document.Document document, String userName, org.apache.lucene.index.IndexWriter writer) Methods inherited from class ch.rswk.meta.engine.AbstractEngineIdleService
configClass, configReference, onConfigWatcherNotification, serviceId, serviceNameMethods inherited from class com.google.common.util.concurrent.AbstractIdleService
addListener, awaitRunning, awaitRunning, awaitRunning, awaitTerminated, awaitTerminated, awaitTerminated, executor, failureCause, isRunning, startAsync, state, stopAsync, toStringMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitMethods inherited from interface ch.rswk.meta.engine.EngineServices.ConfigurableService
config, handleConfigWatcherNotification, onConfigChangedMethods inherited from interface ch.rswk.meta.engine.EngineServices.InfoProvidingService
getServiceInfo
-
Field Details
-
LOG
private static final org.slf4j.Logger LOG -
TOTP_VALIDITY
public static final long TOTP_VALIDITY- See Also:
-
USER_CONFIG_EMAIL
- See Also:
-
USER_CONFIG_PHONE
- See Also:
-
ATTEMPTS_EXCEEDED_ERROR
-
AUTH_ERROR
-
AUTH_TOKEN_EXPIRATION
private static final int AUTH_TOKEN_EXPIRATION- See Also:
-
CLEANUP_SCHEDULE
-
CLIENT_NAME_OR_VERSION_MATCHER
private static final com.google.common.base.CharMatcher CLIENT_NAME_OR_VERSION_MATCHER -
CONFIG_ALREADY_EXISTS_ERROR
-
CONFIG_READER
private static final com.fasterxml.jackson.databind.ObjectReader CONFIG_READER -
DELETE_ADMIN_GROUP_ERROR
-
GROUP_ALREADY_EXISTS_ERROR
-
GROUP_READER
private static final com.fasterxml.jackson.databind.ObjectReader GROUP_READER -
INVALID_CONFIG_ERROR
-
INVALID_GROUP_ERROR
-
INVALID_OTP_ERROR
-
INVALID_PASSWORD_ERROR
-
INVALID_USER_ERROR
-
MISSING_SUBJECT_ERROR
-
NO_GROUP_FOR_UPDATE_ERROR
-
NO_USER_FOR_UPDATE_ERROR
-
NO_VERIFY_REQUEST_ERROR
-
OTP_BOUND
private static final int OTP_BOUND- See Also:
-
OTP_DELIVERY_FAILED_ERROR
-
OTP_SEPARATOR
- See Also:
-
OTP_VERIFICATION_ERROR
-
RANDOM
-
SEARCH_ERROR
-
TOKEN_DESERIALIZER
-
TOKEN_ISSUER
-
TOKEN_SERIALIZER
-
TOTP_ACCEPTED_CODES
private static final int TOTP_ACCEPTED_CODES- See Also:
-
TOTP_RETURN_DIGITS
- See Also:
-
UPDATE_ERROR
-
USER_ALREADY_EXISTS_ERROR
-
USER_CONFIG_GROUP_QUERY_FORMAT
- See Also:
-
USER_CONFIG_QUERY_FORMAT
- See Also:
-
USER_GROUP_MEMBER_QUERY_FORMAT
- See Also:
-
USER_READER
private static final com.fasterxml.jackson.databind.ObjectReader USER_READER -
WEBAUTHN_ASSERTION_ERROR
-
WEBAUTHN_ASSERTION_TYPE
private static final com.fasterxml.jackson.core.type.TypeReference<com.yubico.webauthn.data.PublicKeyCredential<com.yubico.webauthn.data.AuthenticatorAssertionResponse,com.yubico.webauthn.data.ClientAssertionExtensionOutputs>> WEBAUTHN_ASSERTION_TYPE -
WEBAUTHN_CREDENTIAL_QUERY_FORMAT
- See Also:
-
WEBAUTHN_DISPLAY_NAME_MATCHER
private static final com.google.common.base.CharMatcher WEBAUTHN_DISPLAY_NAME_MATCHER -
WEBAUTHN_MAPPER
private static final com.fasterxml.jackson.databind.ObjectMapper WEBAUTHN_MAPPER -
WEBAUTHN_REGISTRATION_ERROR
-
WEBAUTHN_REGISTRATION_TYPE
private static final com.fasterxml.jackson.core.type.TypeReference<com.yubico.webauthn.data.PublicKeyCredential<com.yubico.webauthn.data.AuthenticatorAttestationResponse,com.yubico.webauthn.data.ClientRegistrationExtensionOutputs>> WEBAUTHN_REGISTRATION_TYPE -
WEBAUTHN_USER_HANDLE_QUERY_FORMAT
- See Also:
-
WEBHOOK_ERROR
-
WRITE_ERROR
-
backupService
-
clients
-
disconnectedClientIds
-
failedAttempts
-
gatewayService
-
luceneService
-
webhookAuthFutures
-
webhookAuthMonitor
private final com.google.common.util.concurrent.Monitor webhookAuthMonitor -
authContact
-
authErrorMeter
private com.codahale.metrics.Meter authErrorMeter -
authMeter
private com.codahale.metrics.Meter authMeter -
authTokenKey
-
authTokenMeter
private com.codahale.metrics.Meter authTokenMeter -
clientListMeter
private com.codahale.metrics.Meter clientListMeter -
configCache
private com.github.benmanes.caffeine.cache.AsyncLoadingCache<String,Optional<MetaUserConfig>> configCache -
configSearchMeter
private com.codahale.metrics.Meter configSearchMeter -
configWriteMeter
private com.codahale.metrics.Meter configWriteMeter -
failedAttemptMeter
private com.codahale.metrics.Meter failedAttemptMeter -
failedTokenMeter
private com.codahale.metrics.Meter failedTokenMeter -
groupCache
private com.github.benmanes.caffeine.cache.AsyncLoadingCache<String,Optional<MetaUserGroup>> groupCache -
groupSearchMeter
private com.codahale.metrics.Meter groupSearchMeter -
groupUpdateMeter
private com.codahale.metrics.Meter groupUpdateMeter -
groupWriteMeter
private com.codahale.metrics.Meter groupWriteMeter -
loginMeter
private com.codahale.metrics.Meter loginMeter -
logoutMeter
private com.codahale.metrics.Meter logoutMeter -
otpCache
-
otpExpiredMeter
private com.codahale.metrics.Meter otpExpiredMeter -
otpTimer
private com.codahale.metrics.Timer otpTimer -
passwordRegex
-
recoverContact
-
recoverErrorMeter
private com.codahale.metrics.Meter recoverErrorMeter -
recoverMeter
private com.codahale.metrics.Meter recoverMeter -
resetContact
-
resetPasswordErrorMeter
private com.codahale.metrics.Meter resetPasswordErrorMeter -
resetPasswordMeter
private com.codahale.metrics.Meter resetPasswordMeter -
scryptMeter
private com.codahale.metrics.Meter scryptMeter -
tokenInvalidationCache
-
tokenKey
-
tokenMeter
private com.codahale.metrics.Meter tokenMeter -
totpMeter
private com.codahale.metrics.Meter totpMeter -
userCache
private com.github.benmanes.caffeine.cache.AsyncLoadingCache<String,Optional<UserService.UserCacheEntry>> userCache -
userSearchMeter
private com.codahale.metrics.Meter userSearchMeter -
userUpdateMeter
private com.codahale.metrics.Meter userUpdateMeter -
userValidationCache
private com.github.benmanes.caffeine.cache.Cache<String,UserService.PendingUserValidation> userValidationCache -
userWriteMeter
private com.codahale.metrics.Meter userWriteMeter -
verifyContact
-
verifyOtpCache
-
verifyOtpErrorMeter
private com.codahale.metrics.Meter verifyOtpErrorMeter -
verifyOtpMeter
private com.codahale.metrics.Meter verifyOtpMeter -
verifyTokenErrorMeter
private com.codahale.metrics.Meter verifyTokenErrorMeter -
verifyTokenMeter
private com.codahale.metrics.Meter verifyTokenMeter -
webAuthnAssertionCache
private com.github.benmanes.caffeine.cache.Cache<String,com.yubico.webauthn.AssertionRequest> webAuthnAssertionCache -
webAuthnRegistrationCache
private com.github.benmanes.caffeine.cache.Cache<String,com.yubico.webauthn.data.PublicKeyCredentialCreationOptions> webAuthnRegistrationCache -
webAuthnRelyingParty
private com.yubico.webauthn.RelyingParty webAuthnRelyingParty -
webhookAuthReceived
-
webhookMeter
private com.codahale.metrics.Meter webhookMeter -
writeErrorMeter
private com.codahale.metrics.Meter writeErrorMeter
-
-
Constructor Details
-
UserService
@Inject public UserService(BackupService backupService, UserService.UserServiceConfig config, GatewayService gatewayService, @Named("User") LuceneService luceneService, EngineRuntime runtime)
-
-
Method Details
-
auth
public com.google.common.util.concurrent.ListenableFuture<AuthReply> auth(String clientId, String ipAddress, AuthRequest request, String user) -
checkAttempts
-
checkAttempts
-
finishWebAuthnAssertion
private Optional<ErrorReply> finishWebAuthnAssertion(AuthRequest.AuthRequestWebAuthnAssertionReply assertionReply, String clientId, @Nullable String ipAddress, String user) -
recordFailedAttempt
-
verifyOtpChallenge
private Optional<ErrorReply> verifyOtpChallenge(String clientId, String ipAddress, String otp, UserService.OtpChallengeType type, String user) -
verifyTotp
verifyTotp generates codes from the given key and compares them to the given totp.- Parameters:
acceptedCodes- number of accepted codes. 1 = only the current code is accepted, 2 = current and one past code is accepted, and so on. One future code is always accepted
-
sanitizeOtp
-
generateTotp
generateTotp generates a totp from the given key based on the current time plus offset.- Parameters:
offset- positive or negative time step offset. 0 = current time step, 1 = future time step, and so on. Time step is based onTOTP_VALIDITY- See Also:
-
verifyScryptOtp
-
verifyScryptHash
-
getCachedUser
public com.google.common.util.concurrent.ListenableFuture<Optional<UserService.UserCacheEntry>> getCachedUser(String user) -
loadUserConfigs
private com.google.common.util.concurrent.ListenableFuture<UserService.UserConfigResult> loadUserConfigs(Set<String> groups, String user) -
configSearch
public com.google.common.util.concurrent.ListenableFuture<UserConfigSearchReply> configSearch(UserConfigSearchRequest request) -
updateClientList
-
authToken
public com.google.common.util.concurrent.ListenableFuture<AuthTokenReply> authToken(String clientId, String ipAddress, AuthTokenRequest request, String user) throws ErrorReplyException - Throws:
ErrorReplyException
-
generateToken
- Throws:
ErrorReplyException
-
configSearchRecursive
public static com.google.common.util.concurrent.ListenableFuture<Void> configSearchRecursive(Executor executor, Function<UserConfigSearchReply, com.google.common.util.concurrent.ListenableFuture<?>> replyConsumer, UserConfigSearchRequest request, Function<UserConfigSearchRequest, com.google.common.util.concurrent.ListenableFuture<UserConfigSearchReply>> service) -
configWrite
public com.google.common.util.concurrent.ListenableFuture<UserConfigWriteReply> configWrite(UserConfigWriteRequest request) -
getCachedConfig
public com.google.common.util.concurrent.ListenableFuture<Optional<MetaUserConfig>> getCachedConfig(String configId) -
processConfigWrite
private com.google.common.util.concurrent.ListenableFuture<UserConfigWriteReply> processConfigWrite(UserConfigWriteRequest request) -
finishWebAuthnRegistration
private Optional<MetaUser.MetaUserWebAuthn> finishWebAuthnRegistration(UserWriteRequest.UserWriteRequestWebAuthnReply createReply, String user) -
generateTotpKey
-
generateUserToken
public com.google.common.util.concurrent.ListenableFuture<UserService.UserTokenReply> generateUserToken(@Nullable String clientId, String ipAddress, UserService.UserTokenRequest request) throws ErrorReplyException generateUserToken authenticates the given user/password and generates a token containing all grants for user and its groups. Use this for system/technical users with limited permissions.- Throws:
ErrorReplyException- missing user name, user has OTP/WebAuthn or authentication fails
-
verifyPassword
-
groupSearch
public com.google.common.util.concurrent.ListenableFuture<UserGroupSearchReply> groupSearch(UserGroupSearchRequest request) -
executeLuceneGroupSearch
private LuceneService.SearchResult executeLuceneGroupSearch(LuceneService.LuceneContext context, UserGroupSearchRequest request) throws org.apache.lucene.queryparser.flexible.core.QueryNodeException, IOException - Throws:
org.apache.lucene.queryparser.flexible.core.QueryNodeExceptionIOException
-
newGroupSearchReply
-
getClientList
public com.google.common.util.concurrent.ListenableFuture<ClientListReply> getClientList(ClientListRequest request) -
getCredentialIdsForUsername
-
getUserHandleForUsername
-
getUsernameForUserHandle
-
lookup
public Optional<com.yubico.webauthn.RegisteredCredential> lookup(com.yubico.webauthn.data.ByteArray credentialId, com.yubico.webauthn.data.ByteArray userHandle) - Specified by:
lookupin interfacecom.yubico.webauthn.CredentialRepository
-
lookupAll
public Set<com.yubico.webauthn.RegisteredCredential> lookupAll(com.yubico.webauthn.data.ByteArray credentialId) - Specified by:
lookupAllin interfacecom.yubico.webauthn.CredentialRepository
-
findUserForHandle
-
userSearchInternal
protected com.google.common.util.concurrent.ListenableFuture<UserSearchReply> userSearchInternal(boolean mask, UserSearchRequest request) -
executeLuceneUserSearch
private LuceneService.SearchResult executeLuceneUserSearch(LuceneService.LuceneContext context, UserSearchRequest request) throws org.apache.lucene.queryparser.flexible.core.QueryNodeException, IOException - Throws:
org.apache.lucene.queryparser.flexible.core.QueryNodeExceptionIOException
-
newUserSearchReply
-
newMaskedUser
-
newMaskedWebAuthn
private static @Nullable MetaUser.MetaUserWebAuthn newMaskedWebAuthn(@Nullable MetaUser.MetaUserWebAuthn webAuthn) -
groupSearchRecursive
public static com.google.common.util.concurrent.ListenableFuture<Void> groupSearchRecursive(Executor executor, Function<UserGroupSearchReply, com.google.common.util.concurrent.ListenableFuture<?>> replyConsumer, UserGroupSearchRequest request, Function<UserGroupSearchRequest, com.google.common.util.concurrent.ListenableFuture<UserGroupSearchReply>> service) -
groupWrite
public com.google.common.util.concurrent.ListenableFuture<UserGroupWriteReply> groupWrite(UserGroupWriteRequest request) -
getCachedGroup
public com.google.common.util.concurrent.ListenableFuture<Optional<MetaUserGroup>> getCachedGroup(String group) -
processGroupWrite
private com.google.common.util.concurrent.ListenableFuture<UserGroupWriteReply> processGroupWrite(UserGroupWriteRequest request) -
deleteConfigs
-
writeGroup
private void writeGroup(WriteAction action, @Nullable MetaUserGroup existingGroup, MetaUserGroup group, org.apache.lucene.index.IndexWriter writer) -
updateUserCache
-
groupWriteUpdate
public com.google.common.util.concurrent.ListenableFuture<UserGroupWriteUpdateReply> groupWriteUpdate(UserGroupWriteUpdateRequest request) -
processGroupWriteUpdate
private com.google.common.util.concurrent.ListenableFuture<UserGroupWriteUpdateReply> processGroupWriteUpdate(UserGroupWriteUpdateRequest request) -
hasRequiredGrants
-
hasUserPermission
-
isMember
-
login
public com.google.common.util.concurrent.ListenableFuture<LoginReply> login(String clientId, String ipAddress, LoginRequest request) -
loginWithPassword
-
loginWithToken
private com.google.common.util.concurrent.ListenableFuture<LoginReply> loginWithToken(String clientId, String ipAddress, String token) -
logout
public com.google.common.util.concurrent.ListenableFuture<LogoutReply> logout(String clientId, LogoutRequest request) -
processUserWrite
private com.google.common.util.concurrent.ListenableFuture<UserWriteReply> processUserWrite(UserWriteRequest request) -
recoverUser
public com.google.common.util.concurrent.ListenableFuture<RecoverUserReply> recoverUser(String clientId, String ipAddress, RecoverUserRequest request) -
lookupUserByPhoneAndEmail
-
forgeEmailAndPhoneQuery
-
resetPassword
public com.google.common.util.concurrent.ListenableFuture<ResetPasswordReply> resetPassword(String clientId, String ipAddress, ResetPasswordRequest request) -
sanitizeClientNameOrVersion
-
sanitizeWebAuthnDisplayName
-
startUp
- Overrides:
startUpin classAbstractEngineIdleService<UserService.UserServiceConfig>- Throws:
Exception
-
deleteDisconnectedClientIds
private void deleteDisconnectedClientIds() -
decrementFailedAttempts
private void decrementFailedAttempts() -
shutDown
- Overrides:
shutDownin classAbstractEngineIdleService<UserService.UserServiceConfig>- Throws:
Exception
-
startVerifyOtp
public com.google.common.util.concurrent.ListenableFuture<Void> startVerifyOtp(String clientId, @Nullable UserService.UserServiceContactConfig contact, String ipAddress, @Nullable String locale, String user, MetaUser.MetaUserOtp userOtp) -
startOtpChallenge
private com.google.common.util.concurrent.ListenableFuture<Void> startOtpChallenge(String clientId, UserService.UserServiceContactConfig contact, String ipAddress, @Nullable String locale, UserService.OtpChallengeType type, String user, MetaUser.MetaUserOtp userOtp) -
generateScryptOtp
-
generateScryptHash
-
startWebAuthnAssertion
private LoginReply.LoginReplyWebAuthnAssertionRequest startWebAuthnAssertion(String clientId, String user) -
startWebAuthnRegistration
private UserWriteReply.UserWriteReplyWebAuthnRequest startWebAuthnRegistration(String displayName, @Nullable String existingUserHandle, String user) -
startWebhookAuth
public com.google.common.util.concurrent.ListenableFuture<String> startWebhookAuth(String authRef) throws ErrorReplyException - Throws:
ErrorReplyException
-
userSearch
public com.google.common.util.concurrent.ListenableFuture<UserSearchReply> userSearch(UserSearchRequest request) -
userSearchRecursive
public static com.google.common.util.concurrent.ListenableFuture<Void> userSearchRecursive(Executor executor, Function<UserSearchReply, com.google.common.util.concurrent.ListenableFuture<?>> replyConsumer, UserSearchRequest request, Function<UserSearchRequest, com.google.common.util.concurrent.ListenableFuture<UserSearchReply>> service) -
userWrite
public com.google.common.util.concurrent.ListenableFuture<UserWriteReply> userWrite(@Nullable String clientId, boolean enforce, @Nullable String ipAddress, UserWriteRequest request) userWrite processesUserWriteRequest. Some write operations require a second call to userWrite with additional parameters.For WebAuthn, a second request is required with a valid
UserWriteRequest.UserWriteRequestWebAuthnReply.- Parameters:
clientId- optional, if provided andMetaUser.MetaUserOtphas changed, a second request for OTP verification is requiredenforce- if true, then anyUserService.UserServiceEnforceConfigoptions are going to be enforcedipAddress- optional, must be provied together with clientId for OTP verification
-
userWriteInternal
protected com.google.common.util.concurrent.ListenableFuture<UserWriteReply> userWriteInternal(@Nullable String clientId, boolean enforce, boolean hashed, @Nullable String ipAddress, boolean mask, UserWriteRequest request) -
userWriteUpdate
public com.google.common.util.concurrent.ListenableFuture<UserWriteUpdateReply> userWriteUpdate(UserWriteUpdateRequest request) -
processUserWriteUpdate
private com.google.common.util.concurrent.ListenableFuture<UserWriteUpdateReply> processUserWriteUpdate(UserWriteUpdateRequest request) -
getUserWithAddedAndRemovedGrants
private static MetaUser getUserWithAddedAndRemovedGrants(UserWriteUpdateRequest request, UserSearchReply searchReply) -
writeUser
private void writeUser(WriteAction action, @Nullable org.apache.lucene.document.Document document, String userName, org.apache.lucene.index.IndexWriter writer) -
validatePassword
private static UserService.PasswordValidation validatePassword(String existingPassword, boolean hashed, String password, @Nullable Pattern passwordRegex, int scryptCpu, int scryptMemory) -
validateUserOtp
private static UserService.OtpValidation validateUserOtp(@Nullable UserService.UserServiceEnforceConfig enforceConfig, @Nullable MetaUser.MetaUserOtp existingUserOtp, boolean hashed, @Nullable UserService.PendingUserValidation pendingUserValidation, @Nullable MetaUser.MetaUserOtp userOtp) -
validateUserWrite
private UserService.UserWriteValidationResult validateUserWrite(@Nullable String clientId, boolean enforce, boolean hashed, @Nullable String ipAddress, UserWriteRequest request, MetaUser user, @Nullable UserService.UserCacheEntry cacheEntry, String userName) -
verifyOtp
-
verifyToken
public UserService.VerifyTokenReply verifyToken(@Nullable String clientId, String ipAddress, UserService.VerifyTokenRequest request) -
verifyTotp
-
verifyWebhookAuth
- Throws:
ErrorReplyException
-