Browse Source

Refactoring to review. Added tenantId and customerId. Added email tenant name strategy

pull/2717/head
Volodymyr Babak 6 years ago
committed by Andrew Shvayka
parent
commit
8dbc550fd3
  1. 4
      application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java
  2. 42
      application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java
  3. 18
      application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/BasicOAuth2ClientMapper.java
  4. 20
      application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CustomOAuth2ClientMapper.java
  5. 90
      application/src/main/resources/thingsboard.yml
  6. 4
      common/dao-api/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2User.java
  7. 2
      dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2Client.java
  8. 2
      dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ClientMapperConfig.java
  9. 12
      dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2Configuration.java
  10. 11
      dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ServiceImpl.java

4
application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java

@ -200,10 +200,10 @@ public class ThingsboardSecurityConfiguration extends WebSecurityConfigurerAdapt
.addFilterBefore(buildRefreshTokenProcessingFilter(), UsernamePasswordAuthenticationFilter.class) .addFilterBefore(buildRefreshTokenProcessingFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(buildWsJwtTokenAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class) .addFilterBefore(buildWsJwtTokenAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterAfter(rateLimitProcessingFilter, UsernamePasswordAuthenticationFilter.class); .addFilterAfter(rateLimitProcessingFilter, UsernamePasswordAuthenticationFilter.class);
if (oauth2Configuration.isEnabled()) { if (oauth2Configuration != null && oauth2Configuration.isEnabled()) {
http.oauth2Login() http.oauth2Login()
.loginPage("/oauth2Login") .loginPage("/oauth2Login")
.loginProcessingUrl(oauth2Configuration.getClients().values().iterator().next().getLoginProcessingUrl()) .loginProcessingUrl(oauth2Configuration.getLoginProcessingUrl())
.successHandler(oauth2AuthenticationSuccessHandler); .successHandler(oauth2AuthenticationSuccessHandler);
} }
} }

42
application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/BaseOAuth2ClientMapper.java → application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java

@ -36,9 +36,11 @@ import org.thingsboard.server.service.security.model.UserPrincipal;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j @Slf4j
public abstract class BaseOAuth2ClientMapper { public abstract class AbstractOAuth2ClientMapper {
@Autowired @Autowired
private UserService userService; private UserService userService;
@ -49,6 +51,8 @@ public abstract class BaseOAuth2ClientMapper {
@Autowired @Autowired
private CustomerService customerService; private CustomerService customerService;
private final Lock userCreationLock = new ReentrantLock();
protected SecurityUser getOrCreateSecurityUserFromOAuth2User(OAuth2User oauth2User, boolean allowUserCreation) { protected SecurityUser getOrCreateSecurityUserFromOAuth2User(OAuth2User oauth2User, boolean allowUserCreation) {
UserPrincipal principal = new UserPrincipal(UserPrincipal.Type.USER_NAME, oauth2User.getEmail()); UserPrincipal principal = new UserPrincipal(UserPrincipal.Type.USER_NAME, oauth2User.getEmail());
@ -59,18 +63,30 @@ public abstract class BaseOAuth2ClientMapper {
} }
if (user == null) { if (user == null) {
user = new User(); userCreationLock.lock();
if (StringUtils.isEmpty(oauth2User.getCustomerName())) { try {
user.setAuthority(Authority.TENANT_ADMIN); user = userService.findUserByEmail(TenantId.SYS_TENANT_ID, oauth2User.getEmail());
} else { if (user == null) {
user.setAuthority(Authority.CUSTOMER_USER); user = new User();
if (oauth2User.getCustomerId() == null && StringUtils.isEmpty(oauth2User.getCustomerName())) {
user.setAuthority(Authority.TENANT_ADMIN);
} else {
user.setAuthority(Authority.CUSTOMER_USER);
}
TenantId tenantId = oauth2User.getTenantId() != null ?
oauth2User.getTenantId() : getTenantId(oauth2User.getTenantName());
user.setTenantId(tenantId);
CustomerId customerId = oauth2User.getCustomerId() != null ?
oauth2User.getCustomerId() : getCustomerId(user.getTenantId(), oauth2User.getCustomerName());
user.setCustomerId(customerId);
user.setEmail(oauth2User.getEmail());
user.setFirstName(oauth2User.getFirstName());
user.setLastName(oauth2User.getLastName());
user = userService.saveUser(user);
}
} finally {
userCreationLock.unlock();
} }
user.setTenantId(getTenantId(oauth2User.getTenantName()));
user.setCustomerId(getCustomerId(user.getTenantId(), oauth2User.getCustomerName()));
user.setEmail(oauth2User.getEmail());
user.setFirstName(oauth2User.getFirstName());
user.setLastName(oauth2User.getLastName());
user = userService.saveUser(user);
} }
try { try {
@ -78,7 +94,7 @@ public abstract class BaseOAuth2ClientMapper {
return (SecurityUser) new UsernamePasswordAuthenticationToken(securityUser, null, securityUser.getAuthorities()).getPrincipal(); return (SecurityUser) new UsernamePasswordAuthenticationToken(securityUser, null, securityUser.getAuthorities()).getPrincipal();
} catch (Exception e) { } catch (Exception e) {
log.error("Can't get or create security user from oauth2 user", e); log.error("Can't get or create security user from oauth2 user", e);
throw e; throw new RuntimeException("Can't get or create security user from oauth2 user", e);
} }
} }

18
application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/BasicOAuth2ClientMapper.java

@ -28,7 +28,13 @@ import java.util.Map;
@Service(value = "basicOAuth2ClientMapper") @Service(value = "basicOAuth2ClientMapper")
@Slf4j @Slf4j
public class BasicOAuth2ClientMapper extends BaseOAuth2ClientMapper implements OAuth2ClientMapper { public class BasicOAuth2ClientMapper extends AbstractOAuth2ClientMapper implements OAuth2ClientMapper {
private static final String START_PLACEHOLDER_PREFIX = "%{";
private static final String END_PLACEHOLDER_PREFIX = "}";
private static final String EMAIL_TENANT_STRATEGY = "email";
private static final String DOMAIN_TENANT_STRATEGY = "domain";
private static final String CUSTOM_TENANT_STRATEGY = "custom";
@Override @Override
public SecurityUser getOrCreateUserByClientPrincipal(OAuth2AuthenticationToken token, OAuth2ClientMapperConfig config) { public SecurityUser getOrCreateUserByClientPrincipal(OAuth2AuthenticationToken token, OAuth2ClientMapperConfig config) {
@ -46,7 +52,7 @@ public class BasicOAuth2ClientMapper extends BaseOAuth2ClientMapper implements O
oauth2User.setFirstName(firstName); oauth2User.setFirstName(firstName);
} }
if (!StringUtils.isEmpty(config.getBasic().getCustomerNameStrategyPattern())) { if (!StringUtils.isEmpty(config.getBasic().getCustomerNameStrategyPattern())) {
StrSubstitutor sub = new StrSubstitutor(attributes, "${", "}"); StrSubstitutor sub = new StrSubstitutor(attributes, START_PLACEHOLDER_PREFIX, END_PLACEHOLDER_PREFIX);
String customerName = sub.replace(config.getBasic().getCustomerNameStrategyPattern()); String customerName = sub.replace(config.getBasic().getCustomerNameStrategyPattern());
oauth2User.setCustomerName(customerName); oauth2User.setCustomerName(customerName);
} }
@ -55,11 +61,13 @@ public class BasicOAuth2ClientMapper extends BaseOAuth2ClientMapper implements O
private String getTenantName(Map<String, Object> attributes, OAuth2ClientMapperConfig config) { private String getTenantName(Map<String, Object> attributes, OAuth2ClientMapperConfig config) {
switch (config.getBasic().getTenantNameStrategy()) { switch (config.getBasic().getTenantNameStrategy()) {
case "domain": case EMAIL_TENANT_STRATEGY:
return getStringAttributeByKey(attributes, config.getBasic().getEmailAttributeKey());
case DOMAIN_TENANT_STRATEGY:
String email = getStringAttributeByKey(attributes, config.getBasic().getEmailAttributeKey()); String email = getStringAttributeByKey(attributes, config.getBasic().getEmailAttributeKey());
return email.substring(email .indexOf("@") + 1); return email.substring(email .indexOf("@") + 1);
case "custom": case CUSTOM_TENANT_STRATEGY:
StrSubstitutor sub = new StrSubstitutor(attributes, "${", "}"); StrSubstitutor sub = new StrSubstitutor(attributes, START_PLACEHOLDER_PREFIX, END_PLACEHOLDER_PREFIX);
return sub.replace(config.getBasic().getTenantNameStrategyPattern()); return sub.replace(config.getBasic().getTenantNameStrategyPattern());
default: default:
throw new RuntimeException("Tenant Name Strategy with type " + config.getBasic().getTenantNameStrategy() + " is not supported!"); throw new RuntimeException("Tenant Name Strategy with type " + config.getBasic().getTenantNameStrategy() + " is not supported!");

20
application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CustomOAuth2ClientMapper.java

@ -15,6 +15,8 @@
*/ */
package org.thingsboard.server.service.security.auth.oauth2; package org.thingsboard.server.service.security.auth.oauth2;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
@ -27,7 +29,9 @@ import org.thingsboard.server.service.security.model.SecurityUser;
@Service(value = "customOAuth2ClientMapper") @Service(value = "customOAuth2ClientMapper")
@Slf4j @Slf4j
public class CustomOAuth2ClientMapper extends BaseOAuth2ClientMapper implements OAuth2ClientMapper { public class CustomOAuth2ClientMapper extends AbstractOAuth2ClientMapper implements OAuth2ClientMapper {
private static final ObjectMapper json = new ObjectMapper();
private RestTemplateBuilder restTemplateBuilder = new RestTemplateBuilder(); private RestTemplateBuilder restTemplateBuilder = new RestTemplateBuilder();
@ -42,6 +46,18 @@ public class CustomOAuth2ClientMapper extends BaseOAuth2ClientMapper implements
restTemplateBuilder = restTemplateBuilder.basicAuthentication(custom.getUsername(), custom.getPassword()); restTemplateBuilder = restTemplateBuilder.basicAuthentication(custom.getUsername(), custom.getPassword());
} }
RestTemplate restTemplate = restTemplateBuilder.build(); RestTemplate restTemplate = restTemplateBuilder.build();
return restTemplate.postForEntity(custom.getUrl(), token.getPrincipal(), OAuth2User.class).getBody(); String request;
try {
request = json.writeValueAsString(token.getPrincipal());
} catch (JsonProcessingException e) {
log.error("Can't convert principal to JSON string", e);
throw new RuntimeException("Can't convert principal to JSON string", e);
}
try {
return restTemplate.postForEntity(custom.getUrl(), request, OAuth2User.class).getBody();
} catch (Exception e) {
log.error("Can't connect to custom mapper endpoint", e);
throw new RuntimeException("Can't connect to custom mapper endpoint", e);
}
} }
} }

90
application/src/main/resources/thingsboard.yml

@ -98,72 +98,40 @@ security:
# Time allowed to claim the device in milliseconds # Time allowed to claim the device in milliseconds
duration: "${SECURITY_CLAIM_DURATION:60000}" # 1 minute, note this value must equal claimDevices.timeToLiveInMinutes value duration: "${SECURITY_CLAIM_DURATION:60000}" # 1 minute, note this value must equal claimDevices.timeToLiveInMinutes value
basic: basic:
enabled: false enabled: "${SECURITY_BASIC_ENABLED:false}"
oauth2: oauth2:
enabled: true enabled: "${SECURITY_OAUTH2_ENABLED:false}"
loginProcessingUrl: "${SECURITY_OAUTH2_LOGIN_PROCESSING_URL:/login/oauth2/code/}"
clients: clients:
schwarz: default:
registrationId: A loginButtonLabel: "${SECURITY_OAUTH2_DEFAULT_LOGIN_BUTTON_LABEL:Default}" # Label that going to be show on login screen
loginButtonLabel: Auth0 # loginButtonIcon: "${SECURITY_OAUTH2_DEFAULT_LOGIN_BUTTON_ICON:}" # Icon that going to be show on login screen. Material design icon ID (https://material.angularjs.org/latest/api/directive/mdIcon)
loginButtonIcon: clientName: "${SECURITY_OAUTH2_DEFAULT_CLIENT_NAME:ClientName}"
clientName: Test app clientId: "${SECURITY_OAUTH2_DEFAULT_CLIENT_ID:}"
clientId: dVH9reqyqiXIG7M2wmamb0ySue8zaM4g clientSecret: "${SECURITY_OAUTH2_DEFAULT_CLIENT_SECRET:}"
clientSecret: EYAfAGxwkwoeYnb2o2cDgaWZB5k97OStpZQPPvcMMD-SVH2BuughTGeBazXtF5I6 accessTokenUri: "${SECURITY_OAUTH2_DEFAULT_ACCESS_TOKEN_URI:}"
accessTokenUri: https://dev-r9m8ht0k.auth0.com/oauth/token authorizationUri: "${SECURITY_OAUTH2_DEFAULT_AUTHORIZATION_URI:}"
authorizationUri: https://dev-r9m8ht0k.auth0.com/authorize scope: "${SECURITY_OAUTH2_DEFAULT_SCOPE:}"
scope: openid,profile,email redirectUriTemplate: "${SECURITY_OAUTH2_DEFAULT_REDIRECT_URI_TEMPLATE:http://localhost:8080/login/oauth2/code/}" # Must be in sync with security.oauth2.loginProcessingUrl
redirectUriTemplate: http://localhost:8080/login/oauth2/code/ jwkSetUri: "${SECURITY_OAUTH2_DEFAULT_JWK_SET_URI:}"
loginProcessingUrl: /login/oauth2/code/ authorizationGrantType: "${SECURITY_OAUTH2_DEFAULT_AUTHORIZATION_GRANT_TYPE:authorization_code}" # authorization_code, implicit, refresh_token or client_credentials
jwkSetUri: https://dev-r9m8ht0k.auth0.com/.well-known/jwks.json clientAuthenticationMethod: "${SECURITY_OAUTH2_DEFAULT_CLIENT_AUTHENTICATION_METHOD:post}" # basic or post
authorizationGrantType: authorization_code # authorization_code, implicit, refresh_token, client_credentials userInfoUri: "${SECURITY_OAUTH2_DEFAULT_USER_INFO_URI:}"
clientAuthenticationMethod: post # basic, post userNameAttributeName: "${SECURITY_OAUTH2_DEFAULT_USER_NAME_ATTRIBUTE_NAME:email}"
userInfoUri: https://dev-r9m8ht0k.auth0.com/userinfo
userNameAttributeName: email
mapperConfig: mapperConfig:
type: custom # basic or custom type: "${SECURITY_OAUTH2_DEFAULT_MAPPER_TYPE:basic}" # basic or custom
basic: basic:
allowUserCreation: true # required allowUserCreation: "${SECURITY_OAUTH2_DEFAULT_MAPPER_BASIC_ALLOW_USER_CREATION:true}" # Allows to create user if it not exists
emailAttributeKey: email # required emailAttributeKey: "${SECURITY_OAUTH2_DEFAULT_MAPPER_BASIC_EMAIL_ATTRIBUTE_KEY:email}" # Attribute key to use as email for the user
firstNameAttributeKey: firstNameAttributeKey: "${SECURITY_OAUTH2_DEFAULT_MAPPER_BASIC_FIRST_NAME_ATTRIBUTE_KEY:}"
lastNameAttributeKey: lastNameAttributeKey: "${SECURITY_OAUTH2_DEFAULT_MAPPER_BASIC_LAST_NAME_ATTRIBUTE_KEY:}"
tenantNameStrategy: domain # domain or custom tenantNameStrategy: "${SECURITY_OAUTH2_DEFAULT_MAPPER_BASIC_TENANT_NAME_STRATEGY:domain}" # domain, email or custom
tenantNameStrategyPattern: tenantNameStrategyPattern: "${SECURITY_OAUTH2_DEFAULT_MAPPER_BASIC_TENANT_NAME_STRATEGY_PATTERN:}"
customerNameStrategyPattern: customerNameStrategyPattern: "${SECURITY_OAUTH2_DEFAULT_MAPPER_BASIC_CUSTOMER_NAME_STRATEGY_PATTERN:}"
custom: custom:
url: http://localhost:9090/oauth2/mapper url: "${SECURITY_OAUTH2_DEFAULT_MAPPER_CUSTOM_URL:}"
username: admin username: "${SECURITY_OAUTH2_DEFAULT_MAPPER_CUSTOM_USERNAME:}"
password: bababa password: "${SECURITY_OAUTH2_DEFAULT_MAPPER_CUSTOM_PASSWORD:}"
auth0:
registrationId: B
loginButtonLabel: Schwarz #
loginButtonIcon: mdi:google
clientName: Thingsboard Dev Test Q
clientId: 5f5c0998-1d9b-4679-9610-6108fb91af2a
clientSecret: h_kXVb7Ee1LgDDinix_nkAh_owWX7YCO783NNteF9AIOqlTWu2L03YoFjv5KL8yRVyx4uYAE-r_N3tFbupE8Kw
accessTokenUri: https://federation-q.auth.schwarz/nidp/oauth/nam/token
authorizationUri: https://federation-q.auth.schwarz/nidp/oauth/nam/authz
scope: openid,profile,email,siam
redirectUriTemplate: http://localhost:8080/login/oauth2/code/
loginProcessingUrl: /login/oauth2/code/
jwkSetUri: https://federation-q.auth.schwarz/nidp/oauth/nam/keys
authorizationGrantType: authorization_code # authorization_code, implicit, refresh_token, client_credentials
clientAuthenticationMethod: post # basic, post
userInfoUri: https://federation-q.auth.schwarz/nidp/oauth/nam/userinfo
userNameAttributeName: mail
mapperConfig:
type: basic # simple or custom
basic:
allowUserCreation: true # required
emailAttributeKey: CloudLoginName # required
firstNameAttributeKey: givenName
lastNameAttributeKey: sn
tenantNameStrategy: custom # domain or custom
tenantNameStrategyPattern: LOL ${region}
customerNameStrategyPattern: GGG ${countrycode}
custom:
url: http://localhost:9090/oauth2/mapper
username: test
password: test
# Dashboard parameters # Dashboard parameters
dashboard: dashboard:

4
common/dao-api/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2User.java

@ -16,11 +16,15 @@
package org.thingsboard.server.dao.oauth2; package org.thingsboard.server.dao.oauth2;
import lombok.Data; import lombok.Data;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
@Data @Data
public class OAuth2User { public class OAuth2User {
private String tenantName; private String tenantName;
private TenantId tenantId;
private String customerName; private String customerName;
private CustomerId customerId;
private String email; private String email;
private String firstName; private String firstName;
private String lastName; private String lastName;

2
dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2Client.java

@ -20,7 +20,6 @@ import lombok.Data;
@Data @Data
public class OAuth2Client { public class OAuth2Client {
private String registrationId;
private String loginButtonLabel; private String loginButtonLabel;
private String loginButtonIcon; private String loginButtonIcon;
private String clientName; private String clientName;
@ -31,7 +30,6 @@ public class OAuth2Client {
private String scope; private String scope;
private String redirectUriTemplate; private String redirectUriTemplate;
private String jwkSetUri; private String jwkSetUri;
private String loginProcessingUrl;
private String authorizationGrantType; private String authorizationGrantType;
private String clientAuthenticationMethod; private String clientAuthenticationMethod;
private String userInfoUri; private String userInfoUri;

2
dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ClientMapperConfig.java

@ -21,8 +21,8 @@ import lombok.Data;
public class OAuth2ClientMapperConfig { public class OAuth2ClientMapperConfig {
private String type; private String type;
private CustomOAuth2ClientMapperConfig custom;
private BasicOAuth2ClientMapperConfig basic; private BasicOAuth2ClientMapperConfig basic;
private CustomOAuth2ClientMapperConfig custom;
@Data @Data
public static class BasicOAuth2ClientMapperConfig { public static class BasicOAuth2ClientMapperConfig {

12
dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2Configuration.java

@ -40,13 +40,15 @@ import java.util.Map;
public class OAuth2Configuration { public class OAuth2Configuration {
private boolean enabled; private boolean enabled;
private String loginProcessingUrl;
private Map<String, OAuth2Client> clients = new HashMap<>(); private Map<String, OAuth2Client> clients = new HashMap<>();
@Bean @Bean
public ClientRegistrationRepository clientRegistrationRepository() { public ClientRegistrationRepository clientRegistrationRepository() {
List<ClientRegistration> result = new ArrayList<>(); List<ClientRegistration> result = new ArrayList<>();
for (OAuth2Client client : clients.values()) { for (Map.Entry<String, OAuth2Client> entry : clients.entrySet()) {
ClientRegistration registration = ClientRegistration.withRegistrationId(client.getRegistrationId()) OAuth2Client client = entry.getValue();
ClientRegistration registration = ClientRegistration.withRegistrationId(entry.getKey())
.clientId(client.getClientId()) .clientId(client.getClientId())
.authorizationUri(client.getAuthorizationUri()) .authorizationUri(client.getAuthorizationUri())
.clientSecret(client.getClientSecret()) .clientSecret(client.getClientSecret())
@ -68,9 +70,9 @@ public class OAuth2Configuration {
public OAuth2Client getClientByRegistrationId(String registrationId) { public OAuth2Client getClientByRegistrationId(String registrationId) {
OAuth2Client result = null; OAuth2Client result = null;
if (clients != null && !clients.isEmpty()) { if (clients != null && !clients.isEmpty()) {
for (OAuth2Client client : clients.values()) { for (String key : clients.keySet()) {
if (client.getRegistrationId().equals(registrationId)) { if (key.equals(registrationId)) {
result = client; result = clients.get(key);
break; break;
} }
} }

11
dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ServiceImpl.java

@ -23,6 +23,7 @@ import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
@Slf4j @Slf4j
@Service @Service
@ -33,15 +34,15 @@ public class OAuth2ServiceImpl implements OAuth2Service {
@Override @Override
public List<OAuth2ClientInfo> getOAuth2Clients() { public List<OAuth2ClientInfo> getOAuth2Clients() {
if (!oauth2Configuration.isEnabled()) { if (oauth2Configuration == null || !oauth2Configuration.isEnabled()) {
return Collections.emptyList(); return Collections.emptyList();
} }
List<OAuth2ClientInfo> result = new ArrayList<>(); List<OAuth2ClientInfo> result = new ArrayList<>();
for (OAuth2Client c : oauth2Configuration.getClients().values()) { for (Map.Entry<String, OAuth2Client> entry : oauth2Configuration.getClients().entrySet()) {
OAuth2ClientInfo client = new OAuth2ClientInfo(); OAuth2ClientInfo client = new OAuth2ClientInfo();
client.setName(c.getLoginButtonLabel()); client.setName(entry.getValue().getLoginButtonLabel());
client.setUrl(String.format("/oauth2/authorization/%s", c.getRegistrationId())); client.setUrl(String.format("/oauth2/authorization/%s", entry.getKey()));
client.setIcon(c.getLoginButtonIcon()); client.setIcon(entry.getValue().getLoginButtonIcon());
result.add(client); result.add(client);
} }
return result; return result;

Loading…
Cancel
Save