Search in sources :

Example 1 with EnvironmentPropertyMapper

use of com.infiniteautomation.mango.util.EnvironmentPropertyMapper in project ma-core-public by infiniteautomation.

the class DefaultUserMapper method mapUser.

@Override
public User mapUser(OAuth2UserRequest userRequest, OAuth2User oAuth2User) {
    if (log.isDebugEnabled()) {
        log.debug("Syncing OAuth2 user {} to Mango user", oAuth2User);
    }
    ClientRegistration clientRegistration = userRequest.getClientRegistration();
    StandardClaimAccessor accessor = toAccessor(oAuth2User);
    String registrationId = clientRegistration.getRegistrationId();
    EnvironmentPropertyMapper userMapping = mapperFactory.forRegistrationId(registrationId, "userMapping.");
    Optional<String> issuerOptional = userMapping.map("issuer.fixed");
    if (!issuerOptional.isPresent()) {
        issuerOptional = userMapping.map("issuer", accessor::getClaimAsString);
    }
    String issuer = issuerOptional.orElseThrow(() -> new IllegalStateException("Issuer is required"));
    String subject = userMapping.map("subject", accessor::getClaimAsString).orElseThrow(() -> new IllegalStateException("Subject is required"));
    LinkedAccount linkedAccount = new OAuth2LinkedAccount(issuer, subject);
    User user = usersService.getUserForLinkedAccount(linkedAccount).orElseGet(() -> {
        // only synchronize the username when creating the user
        String usernamePrefix = userMapping.map("username.prefix").orElse("");
        String usernameSuffix = userMapping.map("username.suffix").orElse("");
        String username = userMapping.map("username", accessor::getClaimAsString).map(un -> usernamePrefix + un + usernameSuffix).orElse(// user will get a random XID for a username if claim is missing
        null);
        User newUser = new User();
        newUser.setUsername(username);
        newUser.setPassword(LOCKED_PASSWORD);
        // in case role sync is not turned on
        newUser.setRoles(Collections.singleton(PermissionHolder.USER_ROLE));
        return newUser;
    });
    String emailPrefix = userMapping.map("email.prefix").orElse("");
    String emailSuffix = userMapping.map("email.suffix").orElse("");
    String email = userMapping.map("email", accessor::getClaimAsString).map(e -> emailPrefix + e + emailSuffix).orElse(// validation will fail if email is not set
    null);
    user.setEmail(email);
    userMapping.map("name", accessor::getClaimAsString).ifPresent(user::setName);
    userMapping.map("phone", accessor::getClaimAsString).ifPresent(user::setPhone);
    userMapping.map("locale", accessor::getClaimAsString).ifPresent(user::setLocale);
    userMapping.map("timezone", accessor::getClaimAsString).ifPresent(user::setTimezone);
    if (userMapping.map("oauth2.client.default.userMapping.roles.sync", Boolean.class).orElse(true)) {
        String rolePrefix = userMapping.map("roles.prefix").orElse("");
        String roleSuffix = userMapping.map("roles.suffix").orElse("");
        Set<String> ignoreRoles = Arrays.stream(userMapping.map("roles.ignore", String[].class).orElse(new String[0])).collect(Collectors.toSet());
        Stream<String> oauthRoles = userMapping.map("roles", accessor::getClaimAsStringList).orElseGet(ArrayList::new).stream().filter(r -> !ignoreRoles.contains(r)).map(r -> userMapping.map("roles.map." + r).orElse(rolePrefix + r + roleSuffix));
        Stream<String> addRoles = Arrays.stream(userMapping.map("roles.add", String[].class).orElse(new String[0]));
        Set<Role> roles = Stream.concat(oauthRoles, addRoles).map(roleService::getOrInsert).map(RoleVO::getRole).collect(Collectors.toCollection(HashSet::new));
        // ensure user role is present
        roles.add(PermissionHolder.USER_ROLE);
        user.setRoles(roles);
    }
    if (user.isNew()) {
        usersService.insertUserForLinkedAccount(user, linkedAccount);
    } else {
        usersService.update(user.getId(), user);
    }
    return user;
}
Also used : Arrays(java.util.Arrays) OidcUser(org.springframework.security.oauth2.core.oidc.user.OidcUser) Role(com.serotonin.m2m2.vo.role.Role) OAuth2UserRequest(org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest) LoggerFactory(org.slf4j.LoggerFactory) Autowired(org.springframework.beans.factory.annotation.Autowired) PermissionHolder(com.serotonin.m2m2.vo.permission.PermissionHolder) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) UsersService(com.infiniteautomation.mango.spring.service.UsersService) RoleVO(com.serotonin.m2m2.vo.role.RoleVO) StandardClaimAccessor(org.springframework.security.oauth2.core.oidc.StandardClaimAccessor) Logger(org.slf4j.Logger) LinkedAccount(com.serotonin.m2m2.vo.LinkedAccount) Set(java.util.Set) Collectors(java.util.stream.Collectors) ClientRegistration(org.springframework.security.oauth2.client.registration.ClientRegistration) Component(org.springframework.stereotype.Component) Stream(java.util.stream.Stream) EnvironmentPropertyMapper(com.infiniteautomation.mango.util.EnvironmentPropertyMapper) ConditionalOnProperty(com.infiniteautomation.mango.spring.ConditionalOnProperty) OAuth2User(org.springframework.security.oauth2.core.user.OAuth2User) Optional(java.util.Optional) LOCKED_PASSWORD(com.serotonin.m2m2.db.dao.UserDao.LOCKED_PASSWORD) OAuth2LinkedAccount(com.serotonin.m2m2.vo.OAuth2LinkedAccount) Collections(java.util.Collections) User(com.serotonin.m2m2.vo.User) RoleService(com.infiniteautomation.mango.spring.service.RoleService) OidcUser(org.springframework.security.oauth2.core.oidc.user.OidcUser) OAuth2User(org.springframework.security.oauth2.core.user.OAuth2User) User(com.serotonin.m2m2.vo.User) LinkedAccount(com.serotonin.m2m2.vo.LinkedAccount) OAuth2LinkedAccount(com.serotonin.m2m2.vo.OAuth2LinkedAccount) OAuth2LinkedAccount(com.serotonin.m2m2.vo.OAuth2LinkedAccount) Role(com.serotonin.m2m2.vo.role.Role) StandardClaimAccessor(org.springframework.security.oauth2.core.oidc.StandardClaimAccessor) EnvironmentPropertyMapper(com.infiniteautomation.mango.util.EnvironmentPropertyMapper) ClientRegistration(org.springframework.security.oauth2.client.registration.ClientRegistration)

Example 2 with EnvironmentPropertyMapper

use of com.infiniteautomation.mango.util.EnvironmentPropertyMapper in project ma-core-public by infiniteautomation.

the class OAuth2Configuration method clientRegistrationRepository.

@Bean
public ClientRegistrationRepository clientRegistrationRepository(Environment env, RegistrationPropertyMapperFactory mapperFactory) {
    return new InMemoryClientRegistrationRepository(Arrays.stream(env.getRequiredProperty("oauth2.client.registrationIds", String[].class)).map(registrationId -> {
        ClientRegistration.Builder builder = null;
        // lookup a provider, defaults to the same name as the registration
        String providerId = env.getProperty("oauth2.client.registration." + registrationId + ".provider", registrationId);
        try {
            builder = CommonOAuth2Provider.valueOf(providerId.toUpperCase(Locale.ROOT)).getBuilder(registrationId);
        } catch (IllegalArgumentException e) {
        // dont care
        }
        if (builder == null) {
            builder = ClientRegistration.withRegistrationId(registrationId);
        }
        // set URL to redirect back to Mango
        builder.redirectUri("{baseUrl}/oauth2/callback/{registrationId}");
        EnvironmentPropertyMapper propertyMapper = mapperFactory.forRegistrationId(registrationId);
        propertyMapper.map("authorizationUri").ifPresent(builder::authorizationUri);
        propertyMapper.map("tokenUri").ifPresent(builder::tokenUri);
        propertyMapper.map("jwkSetUri").ifPresent(builder::jwkSetUri);
        propertyMapper.map("issuerUri").ifPresent(builder::issuerUri);
        propertyMapper.map("userInfoUri").ifPresent(builder::userInfoUri);
        propertyMapper.map("userInfoAuthenticationMethod", AuthenticationMethod.class).ifPresent(builder::userInfoAuthenticationMethod);
        propertyMapper.map("userNameAttributeName").ifPresent(builder::userNameAttributeName);
        propertyMapper.map("clientAuthenticationMethod", ClientAuthenticationMethod.class).ifPresent(builder::clientAuthenticationMethod);
        propertyMapper.map("authorizationGrantType", AuthorizationGrantType.class).ifPresent(builder::authorizationGrantType);
        propertyMapper.map("scope", String[].class).ifPresent(builder::scope);
        propertyMapper.map("clientName").ifPresent(builder::clientName);
        propertyMapper.map("clientId").ifPresent(builder::clientId);
        propertyMapper.map("clientSecret").ifPresent(builder::clientSecret);
        propertyMapper.map("redirectUri").ifPresent(builder::redirectUri);
        return builder.build();
    }).collect(Collectors.toList()));
}
Also used : EnvironmentPropertyMapper(com.infiniteautomation.mango.util.EnvironmentPropertyMapper) ClientRegistration(org.springframework.security.oauth2.client.registration.ClientRegistration) AuthorizationGrantType(org.springframework.security.oauth2.core.AuthorizationGrantType) InMemoryClientRegistrationRepository(org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository) ClientAuthenticationMethod(org.springframework.security.oauth2.core.ClientAuthenticationMethod) AuthenticationMethod(org.springframework.security.oauth2.core.AuthenticationMethod) ClientAuthenticationMethod(org.springframework.security.oauth2.core.ClientAuthenticationMethod) Bean(org.springframework.context.annotation.Bean)

Aggregations

EnvironmentPropertyMapper (com.infiniteautomation.mango.util.EnvironmentPropertyMapper)2 ClientRegistration (org.springframework.security.oauth2.client.registration.ClientRegistration)2 ConditionalOnProperty (com.infiniteautomation.mango.spring.ConditionalOnProperty)1 RoleService (com.infiniteautomation.mango.spring.service.RoleService)1 UsersService (com.infiniteautomation.mango.spring.service.UsersService)1 LOCKED_PASSWORD (com.serotonin.m2m2.db.dao.UserDao.LOCKED_PASSWORD)1 LinkedAccount (com.serotonin.m2m2.vo.LinkedAccount)1 OAuth2LinkedAccount (com.serotonin.m2m2.vo.OAuth2LinkedAccount)1 User (com.serotonin.m2m2.vo.User)1 PermissionHolder (com.serotonin.m2m2.vo.permission.PermissionHolder)1 Role (com.serotonin.m2m2.vo.role.Role)1 RoleVO (com.serotonin.m2m2.vo.role.RoleVO)1 ArrayList (java.util.ArrayList)1 Arrays (java.util.Arrays)1 Collections (java.util.Collections)1 HashSet (java.util.HashSet)1 Optional (java.util.Optional)1 Set (java.util.Set)1 Collectors (java.util.stream.Collectors)1 Stream (java.util.stream.Stream)1