109 changed files with 3825 additions and 1112 deletions
File diff suppressed because one or more lines are too long
@ -0,0 +1,22 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.service.security.auth.oauth2; |
|||
|
|||
public interface TbOAuth2ParameterNames { |
|||
|
|||
String CALLBACK_URL_SCHEME = "callback_url_scheme"; |
|||
|
|||
} |
|||
@ -0,0 +1,69 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.service.security.model.token; |
|||
|
|||
import io.jsonwebtoken.Claims; |
|||
import io.jsonwebtoken.ExpiredJwtException; |
|||
import io.jsonwebtoken.Jws; |
|||
import io.jsonwebtoken.Jwts; |
|||
import io.jsonwebtoken.MalformedJwtException; |
|||
import io.jsonwebtoken.SignatureException; |
|||
import io.jsonwebtoken.UnsupportedJwtException; |
|||
import io.micrometer.core.instrument.util.StringUtils; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import java.util.Date; |
|||
import java.util.concurrent.TimeUnit; |
|||
|
|||
@Component |
|||
@Slf4j |
|||
public class OAuth2AppTokenFactory { |
|||
|
|||
private static final String CALLBACK_URL_SCHEME = "callbackUrlScheme"; |
|||
|
|||
private static final long MAX_EXPIRATION_TIME_DIFF_MS = TimeUnit.MINUTES.toMillis(5); |
|||
|
|||
public String validateTokenAndGetCallbackUrlScheme(String appPackage, String appToken, String appSecret) { |
|||
Jws<Claims> jwsClaims; |
|||
try { |
|||
jwsClaims = Jwts.parser().setSigningKey(appSecret).parseClaimsJws(appToken); |
|||
} |
|||
catch (UnsupportedJwtException | MalformedJwtException | IllegalArgumentException | SignatureException ex) { |
|||
throw new IllegalArgumentException("Invalid Application token: ", ex); |
|||
} catch (ExpiredJwtException expiredEx) { |
|||
throw new IllegalArgumentException("Application token expired", expiredEx); |
|||
} |
|||
Claims claims = jwsClaims.getBody(); |
|||
Date expiration = claims.getExpiration(); |
|||
if (expiration == null) { |
|||
throw new IllegalArgumentException("Application token must have expiration date"); |
|||
} |
|||
long timeDiff = expiration.getTime() - System.currentTimeMillis(); |
|||
if (timeDiff > MAX_EXPIRATION_TIME_DIFF_MS) { |
|||
throw new IllegalArgumentException("Application token expiration time can't be longer than 5 minutes"); |
|||
} |
|||
if (!claims.getIssuer().equals(appPackage)) { |
|||
throw new IllegalArgumentException("Application token issuer doesn't match application package"); |
|||
} |
|||
String callbackUrlScheme = claims.get(CALLBACK_URL_SCHEME, String.class); |
|||
if (StringUtils.isEmpty(callbackUrlScheme)) { |
|||
throw new IllegalArgumentException("Application token doesn't have callbackUrlScheme"); |
|||
} |
|||
return callbackUrlScheme; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.id; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonCreator; |
|||
import com.fasterxml.jackson.annotation.JsonProperty; |
|||
|
|||
import java.util.UUID; |
|||
|
|||
public class OAuth2DomainId extends UUIDBased { |
|||
|
|||
@JsonCreator |
|||
public OAuth2DomainId(@JsonProperty("id") UUID id) { |
|||
super(id); |
|||
} |
|||
|
|||
public static OAuth2DomainId fromString(String oauth2DomainId) { |
|||
return new OAuth2DomainId(UUID.fromString(oauth2DomainId)); |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.id; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonCreator; |
|||
import com.fasterxml.jackson.annotation.JsonProperty; |
|||
|
|||
import java.util.UUID; |
|||
|
|||
public class OAuth2MobileId extends UUIDBased { |
|||
|
|||
@JsonCreator |
|||
public OAuth2MobileId(@JsonProperty("id") UUID id) { |
|||
super(id); |
|||
} |
|||
|
|||
public static OAuth2MobileId fromString(String oauth2MobileId) { |
|||
return new OAuth2MobileId(UUID.fromString(oauth2MobileId)); |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.id; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonCreator; |
|||
import com.fasterxml.jackson.annotation.JsonProperty; |
|||
|
|||
import java.util.UUID; |
|||
|
|||
public class OAuth2ParamsId extends UUIDBased { |
|||
|
|||
@JsonCreator |
|||
public OAuth2ParamsId(@JsonProperty("id") UUID id) { |
|||
super(id); |
|||
} |
|||
|
|||
public static OAuth2ParamsId fromString(String oauth2ParamsId) { |
|||
return new OAuth2ParamsId(UUID.fromString(oauth2ParamsId)); |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.id; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonCreator; |
|||
import com.fasterxml.jackson.annotation.JsonProperty; |
|||
|
|||
import java.util.UUID; |
|||
|
|||
public class OAuth2RegistrationId extends UUIDBased { |
|||
|
|||
@JsonCreator |
|||
public OAuth2RegistrationId(@JsonProperty("id") UUID id) { |
|||
super(id); |
|||
} |
|||
|
|||
public static OAuth2RegistrationId fromString(String oauth2RegistrationId) { |
|||
return new OAuth2RegistrationId(UUID.fromString(oauth2RegistrationId)); |
|||
} |
|||
} |
|||
@ -0,0 +1,42 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.oauth2; |
|||
|
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.ToString; |
|||
import org.thingsboard.server.common.data.BaseData; |
|||
import org.thingsboard.server.common.data.id.OAuth2DomainId; |
|||
import org.thingsboard.server.common.data.id.OAuth2ParamsId; |
|||
|
|||
@EqualsAndHashCode(callSuper = true) |
|||
@Data |
|||
@ToString |
|||
@NoArgsConstructor |
|||
public class OAuth2Domain extends BaseData<OAuth2DomainId> { |
|||
|
|||
private OAuth2ParamsId oauth2ParamsId; |
|||
private String domainName; |
|||
private SchemeType domainScheme; |
|||
|
|||
public OAuth2Domain(OAuth2Domain domain) { |
|||
super(domain); |
|||
this.oauth2ParamsId = domain.oauth2ParamsId; |
|||
this.domainName = domain.domainName; |
|||
this.domainScheme = domain.domainScheme; |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.oauth2; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Builder; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.ToString; |
|||
|
|||
@EqualsAndHashCode |
|||
@Data |
|||
@ToString |
|||
@NoArgsConstructor |
|||
@AllArgsConstructor |
|||
@Builder |
|||
public class OAuth2DomainInfo { |
|||
private SchemeType scheme; |
|||
private String name; |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.oauth2; |
|||
|
|||
import lombok.*; |
|||
|
|||
import java.util.List; |
|||
|
|||
@EqualsAndHashCode |
|||
@Data |
|||
@ToString |
|||
@Builder(toBuilder = true) |
|||
@NoArgsConstructor |
|||
@AllArgsConstructor |
|||
public class OAuth2Info { |
|||
private boolean enabled; |
|||
private List<OAuth2ParamsInfo> oauth2ParamsInfos; |
|||
} |
|||
@ -0,0 +1,42 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.oauth2; |
|||
|
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.ToString; |
|||
import org.thingsboard.server.common.data.BaseData; |
|||
import org.thingsboard.server.common.data.id.OAuth2MobileId; |
|||
import org.thingsboard.server.common.data.id.OAuth2ParamsId; |
|||
|
|||
@EqualsAndHashCode(callSuper = true) |
|||
@Data |
|||
@ToString |
|||
@NoArgsConstructor |
|||
public class OAuth2Mobile extends BaseData<OAuth2MobileId> { |
|||
|
|||
private OAuth2ParamsId oauth2ParamsId; |
|||
private String pkgName; |
|||
private String appSecret; |
|||
|
|||
public OAuth2Mobile(OAuth2Mobile mobile) { |
|||
super(mobile); |
|||
this.oauth2ParamsId = mobile.oauth2ParamsId; |
|||
this.pkgName = mobile.pkgName; |
|||
this.appSecret = mobile.appSecret; |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.oauth2; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Builder; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.ToString; |
|||
|
|||
@EqualsAndHashCode |
|||
@Data |
|||
@ToString |
|||
@NoArgsConstructor |
|||
@AllArgsConstructor |
|||
@Builder |
|||
public class OAuth2MobileInfo { |
|||
private String pkgName; |
|||
private String appSecret; |
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.oauth2; |
|||
|
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.ToString; |
|||
import org.thingsboard.server.common.data.BaseData; |
|||
import org.thingsboard.server.common.data.id.OAuth2ParamsId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
|
|||
@EqualsAndHashCode(callSuper = true) |
|||
@Data |
|||
@ToString |
|||
@NoArgsConstructor |
|||
public class OAuth2Params extends BaseData<OAuth2ParamsId> { |
|||
|
|||
private boolean enabled; |
|||
private TenantId tenantId; |
|||
|
|||
public OAuth2Params(OAuth2Params oauth2Params) { |
|||
super(oauth2Params); |
|||
this.enabled = oauth2Params.enabled; |
|||
this.tenantId = oauth2Params.tenantId; |
|||
} |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.oauth2; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Builder; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.ToString; |
|||
|
|||
import java.util.List; |
|||
|
|||
@EqualsAndHashCode |
|||
@Data |
|||
@ToString |
|||
@Builder(toBuilder = true) |
|||
@NoArgsConstructor |
|||
@AllArgsConstructor |
|||
public class OAuth2ParamsInfo { |
|||
|
|||
private List<OAuth2DomainInfo> domainInfos; |
|||
private List<OAuth2MobileInfo> mobileInfos; |
|||
private List<OAuth2RegistrationInfo> clientRegistrations; |
|||
|
|||
} |
|||
@ -0,0 +1,79 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.oauth2; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonProperty; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.ToString; |
|||
import org.thingsboard.server.common.data.HasName; |
|||
import org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo; |
|||
import org.thingsboard.server.common.data.id.OAuth2ParamsId; |
|||
import org.thingsboard.server.common.data.id.OAuth2RegistrationId; |
|||
|
|||
import java.util.List; |
|||
|
|||
@EqualsAndHashCode(callSuper = true) |
|||
@Data |
|||
@ToString(exclude = {"clientSecret"}) |
|||
@NoArgsConstructor |
|||
public class OAuth2Registration extends SearchTextBasedWithAdditionalInfo<OAuth2RegistrationId> implements HasName { |
|||
|
|||
private OAuth2ParamsId oauth2ParamsId; |
|||
private OAuth2MapperConfig mapperConfig; |
|||
private String clientId; |
|||
private String clientSecret; |
|||
private String authorizationUri; |
|||
private String accessTokenUri; |
|||
private List<String> scope; |
|||
private String userInfoUri; |
|||
private String userNameAttributeName; |
|||
private String jwkSetUri; |
|||
private String clientAuthenticationMethod; |
|||
private String loginButtonLabel; |
|||
private String loginButtonIcon; |
|||
private List<PlatformType> platforms; |
|||
|
|||
public OAuth2Registration(OAuth2Registration registration) { |
|||
super(registration); |
|||
this.oauth2ParamsId = registration.oauth2ParamsId; |
|||
this.mapperConfig = registration.mapperConfig; |
|||
this.clientId = registration.clientId; |
|||
this.clientSecret = registration.clientSecret; |
|||
this.authorizationUri = registration.authorizationUri; |
|||
this.accessTokenUri = registration.accessTokenUri; |
|||
this.scope = registration.scope; |
|||
this.userInfoUri = registration.userInfoUri; |
|||
this.userNameAttributeName = registration.userNameAttributeName; |
|||
this.jwkSetUri = registration.jwkSetUri; |
|||
this.clientAuthenticationMethod = registration.clientAuthenticationMethod; |
|||
this.loginButtonLabel = registration.loginButtonLabel; |
|||
this.loginButtonIcon = registration.loginButtonIcon; |
|||
this.platforms = registration.platforms; |
|||
} |
|||
|
|||
@Override |
|||
@JsonProperty(access = JsonProperty.Access.READ_ONLY) |
|||
public String getName() { |
|||
return loginButtonLabel; |
|||
} |
|||
|
|||
@Override |
|||
public String getSearchText() { |
|||
return getName(); |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.oauth2; |
|||
|
|||
public enum PlatformType { |
|||
WEB, ANDROID, IOS |
|||
} |
|||
@ -0,0 +1,45 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.oauth2.deprecated; |
|||
|
|||
import com.fasterxml.jackson.databind.JsonNode; |
|||
import lombok.*; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2MapperConfig; |
|||
|
|||
import java.util.List; |
|||
|
|||
@Deprecated |
|||
@EqualsAndHashCode |
|||
@Data |
|||
@ToString(exclude = {"clientSecret"}) |
|||
@NoArgsConstructor |
|||
@AllArgsConstructor |
|||
@Builder |
|||
public class ClientRegistrationDto { |
|||
private OAuth2MapperConfig mapperConfig; |
|||
private String clientId; |
|||
private String clientSecret; |
|||
private String authorizationUri; |
|||
private String accessTokenUri; |
|||
private List<String> scope; |
|||
private String userInfoUri; |
|||
private String userNameAttributeName; |
|||
private String jwkSetUri; |
|||
private String clientAuthenticationMethod; |
|||
private String loginButtonLabel; |
|||
private String loginButtonIcon; |
|||
private JsonNode additionalInfo; |
|||
} |
|||
@ -0,0 +1,76 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.model.sql; |
|||
|
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import org.thingsboard.server.common.data.id.OAuth2DomainId; |
|||
import org.thingsboard.server.common.data.id.OAuth2ParamsId; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Domain; |
|||
import org.thingsboard.server.common.data.oauth2.SchemeType; |
|||
import org.thingsboard.server.dao.model.BaseSqlEntity; |
|||
import org.thingsboard.server.dao.model.ModelConstants; |
|||
|
|||
import javax.persistence.Column; |
|||
import javax.persistence.Entity; |
|||
import javax.persistence.EnumType; |
|||
import javax.persistence.Enumerated; |
|||
import javax.persistence.Table; |
|||
import java.util.UUID; |
|||
|
|||
@Data |
|||
@EqualsAndHashCode(callSuper = true) |
|||
@Entity |
|||
@Table(name = ModelConstants.OAUTH2_DOMAIN_COLUMN_FAMILY_NAME) |
|||
public class OAuth2DomainEntity extends BaseSqlEntity<OAuth2Domain> { |
|||
|
|||
@Column(name = ModelConstants.OAUTH2_PARAMS_ID_PROPERTY) |
|||
private UUID oauth2ParamsId; |
|||
|
|||
@Column(name = ModelConstants.OAUTH2_DOMAIN_NAME_PROPERTY) |
|||
private String domainName; |
|||
|
|||
@Enumerated(EnumType.STRING) |
|||
@Column(name = ModelConstants.OAUTH2_DOMAIN_SCHEME_PROPERTY) |
|||
private SchemeType domainScheme; |
|||
|
|||
public OAuth2DomainEntity() { |
|||
super(); |
|||
} |
|||
|
|||
public OAuth2DomainEntity(OAuth2Domain domain) { |
|||
if (domain.getId() != null) { |
|||
this.setUuid(domain.getId().getId()); |
|||
} |
|||
this.setCreatedTime(domain.getCreatedTime()); |
|||
if (domain.getOauth2ParamsId() != null) { |
|||
this.oauth2ParamsId = domain.getOauth2ParamsId().getId(); |
|||
} |
|||
this.domainName = domain.getDomainName(); |
|||
this.domainScheme = domain.getDomainScheme(); |
|||
} |
|||
|
|||
@Override |
|||
public OAuth2Domain toData() { |
|||
OAuth2Domain domain = new OAuth2Domain(); |
|||
domain.setId(new OAuth2DomainId(id)); |
|||
domain.setCreatedTime(createdTime); |
|||
domain.setOauth2ParamsId(new OAuth2ParamsId(oauth2ParamsId)); |
|||
domain.setDomainName(domainName); |
|||
domain.setDomainScheme(domainScheme); |
|||
return domain; |
|||
} |
|||
} |
|||
@ -0,0 +1,72 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.model.sql; |
|||
|
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import org.thingsboard.server.common.data.id.OAuth2MobileId; |
|||
import org.thingsboard.server.common.data.id.OAuth2ParamsId; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Mobile; |
|||
import org.thingsboard.server.dao.model.BaseSqlEntity; |
|||
import org.thingsboard.server.dao.model.ModelConstants; |
|||
|
|||
import javax.persistence.Column; |
|||
import javax.persistence.Entity; |
|||
import javax.persistence.Table; |
|||
import java.util.UUID; |
|||
|
|||
@Data |
|||
@EqualsAndHashCode(callSuper = true) |
|||
@Entity |
|||
@Table(name = ModelConstants.OAUTH2_MOBILE_COLUMN_FAMILY_NAME) |
|||
public class OAuth2MobileEntity extends BaseSqlEntity<OAuth2Mobile> { |
|||
|
|||
@Column(name = ModelConstants.OAUTH2_PARAMS_ID_PROPERTY) |
|||
private UUID oauth2ParamsId; |
|||
|
|||
@Column(name = ModelConstants.OAUTH2_PKG_NAME_PROPERTY) |
|||
private String pkgName; |
|||
|
|||
@Column(name = ModelConstants.OAUTH2_APP_SECRET_PROPERTY) |
|||
private String appSecret; |
|||
|
|||
public OAuth2MobileEntity() { |
|||
super(); |
|||
} |
|||
|
|||
public OAuth2MobileEntity(OAuth2Mobile mobile) { |
|||
if (mobile.getId() != null) { |
|||
this.setUuid(mobile.getId().getId()); |
|||
} |
|||
this.setCreatedTime(mobile.getCreatedTime()); |
|||
if (mobile.getOauth2ParamsId() != null) { |
|||
this.oauth2ParamsId = mobile.getOauth2ParamsId().getId(); |
|||
} |
|||
this.pkgName = mobile.getPkgName(); |
|||
this.appSecret = mobile.getAppSecret(); |
|||
} |
|||
|
|||
@Override |
|||
public OAuth2Mobile toData() { |
|||
OAuth2Mobile mobile = new OAuth2Mobile(); |
|||
mobile.setId(new OAuth2MobileId(id)); |
|||
mobile.setCreatedTime(createdTime); |
|||
mobile.setOauth2ParamsId(new OAuth2ParamsId(oauth2ParamsId)); |
|||
mobile.setPkgName(pkgName); |
|||
mobile.setAppSecret(appSecret); |
|||
return mobile; |
|||
} |
|||
} |
|||
@ -0,0 +1,65 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.model.sql; |
|||
|
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.NoArgsConstructor; |
|||
import org.thingsboard.server.common.data.id.OAuth2ParamsId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Params; |
|||
import org.thingsboard.server.dao.model.BaseSqlEntity; |
|||
import org.thingsboard.server.dao.model.ModelConstants; |
|||
|
|||
import javax.persistence.Column; |
|||
import javax.persistence.Entity; |
|||
import javax.persistence.Table; |
|||
import java.util.UUID; |
|||
|
|||
@Data |
|||
@EqualsAndHashCode(callSuper = true) |
|||
@Entity |
|||
@Table(name = ModelConstants.OAUTH2_PARAMS_COLUMN_FAMILY_NAME) |
|||
@NoArgsConstructor |
|||
public class OAuth2ParamsEntity extends BaseSqlEntity<OAuth2Params> { |
|||
|
|||
@Column(name = ModelConstants.OAUTH2_PARAMS_ENABLED_PROPERTY) |
|||
private Boolean enabled; |
|||
|
|||
@Column(name = ModelConstants.OAUTH2_PARAMS_TENANT_ID_PROPERTY) |
|||
private UUID tenantId; |
|||
|
|||
public OAuth2ParamsEntity(OAuth2Params oauth2Params) { |
|||
if (oauth2Params.getId() != null) { |
|||
this.setUuid(oauth2Params.getUuidId()); |
|||
} |
|||
this.setCreatedTime(oauth2Params.getCreatedTime()); |
|||
this.enabled = oauth2Params.isEnabled(); |
|||
if (oauth2Params.getTenantId() != null) { |
|||
this.tenantId = oauth2Params.getTenantId().getId(); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public OAuth2Params toData() { |
|||
OAuth2Params oauth2Params = new OAuth2Params(); |
|||
oauth2Params.setId(new OAuth2ParamsId(id)); |
|||
oauth2Params.setCreatedTime(createdTime); |
|||
oauth2Params.setTenantId(new TenantId(tenantId)); |
|||
oauth2Params.setEnabled(enabled); |
|||
return oauth2Params; |
|||
} |
|||
} |
|||
@ -0,0 +1,221 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.model.sql; |
|||
|
|||
import com.fasterxml.jackson.databind.JsonNode; |
|||
import io.micrometer.core.instrument.util.StringUtils; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import org.hibernate.annotations.Type; |
|||
import org.hibernate.annotations.TypeDef; |
|||
import org.thingsboard.server.common.data.id.OAuth2ParamsId; |
|||
import org.thingsboard.server.common.data.id.OAuth2RegistrationId; |
|||
import org.thingsboard.server.common.data.oauth2.MapperType; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2BasicMapperConfig; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2CustomMapperConfig; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2MapperConfig; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Registration; |
|||
import org.thingsboard.server.common.data.oauth2.PlatformType; |
|||
import org.thingsboard.server.common.data.oauth2.TenantNameStrategyType; |
|||
import org.thingsboard.server.dao.model.BaseSqlEntity; |
|||
import org.thingsboard.server.dao.model.ModelConstants; |
|||
import org.thingsboard.server.dao.util.mapping.JsonStringType; |
|||
|
|||
import javax.persistence.Column; |
|||
import javax.persistence.Entity; |
|||
import javax.persistence.EnumType; |
|||
import javax.persistence.Enumerated; |
|||
import javax.persistence.Table; |
|||
import java.util.Arrays; |
|||
import java.util.Collections; |
|||
import java.util.UUID; |
|||
import java.util.stream.Collectors; |
|||
|
|||
@Data |
|||
@EqualsAndHashCode(callSuper = true) |
|||
@Entity |
|||
@TypeDef(name = "json", typeClass = JsonStringType.class) |
|||
@Table(name = ModelConstants.OAUTH2_REGISTRATION_COLUMN_FAMILY_NAME) |
|||
public class OAuth2RegistrationEntity extends BaseSqlEntity<OAuth2Registration> { |
|||
|
|||
@Column(name = ModelConstants.OAUTH2_PARAMS_ID_PROPERTY) |
|||
private UUID oauth2ParamsId; |
|||
@Column(name = ModelConstants.OAUTH2_CLIENT_ID_PROPERTY) |
|||
private String clientId; |
|||
@Column(name = ModelConstants.OAUTH2_CLIENT_SECRET_PROPERTY) |
|||
private String clientSecret; |
|||
@Column(name = ModelConstants.OAUTH2_AUTHORIZATION_URI_PROPERTY) |
|||
private String authorizationUri; |
|||
@Column(name = ModelConstants.OAUTH2_TOKEN_URI_PROPERTY) |
|||
private String tokenUri; |
|||
@Column(name = ModelConstants.OAUTH2_SCOPE_PROPERTY) |
|||
private String scope; |
|||
@Column(name = ModelConstants.OAUTH2_PLATFORMS_PROPERTY) |
|||
private String platforms; |
|||
@Column(name = ModelConstants.OAUTH2_USER_INFO_URI_PROPERTY) |
|||
private String userInfoUri; |
|||
@Column(name = ModelConstants.OAUTH2_USER_NAME_ATTRIBUTE_NAME_PROPERTY) |
|||
private String userNameAttributeName; |
|||
@Column(name = ModelConstants.OAUTH2_JWK_SET_URI_PROPERTY) |
|||
private String jwkSetUri; |
|||
@Column(name = ModelConstants.OAUTH2_CLIENT_AUTHENTICATION_METHOD_PROPERTY) |
|||
private String clientAuthenticationMethod; |
|||
@Column(name = ModelConstants.OAUTH2_LOGIN_BUTTON_LABEL_PROPERTY) |
|||
private String loginButtonLabel; |
|||
@Column(name = ModelConstants.OAUTH2_LOGIN_BUTTON_ICON_PROPERTY) |
|||
private String loginButtonIcon; |
|||
@Column(name = ModelConstants.OAUTH2_ALLOW_USER_CREATION_PROPERTY) |
|||
private Boolean allowUserCreation; |
|||
@Column(name = ModelConstants.OAUTH2_ACTIVATE_USER_PROPERTY) |
|||
private Boolean activateUser; |
|||
@Enumerated(EnumType.STRING) |
|||
@Column(name = ModelConstants.OAUTH2_MAPPER_TYPE_PROPERTY) |
|||
private MapperType type; |
|||
@Column(name = ModelConstants.OAUTH2_EMAIL_ATTRIBUTE_KEY_PROPERTY) |
|||
private String emailAttributeKey; |
|||
@Column(name = ModelConstants.OAUTH2_FIRST_NAME_ATTRIBUTE_KEY_PROPERTY) |
|||
private String firstNameAttributeKey; |
|||
@Column(name = ModelConstants.OAUTH2_LAST_NAME_ATTRIBUTE_KEY_PROPERTY) |
|||
private String lastNameAttributeKey; |
|||
@Enumerated(EnumType.STRING) |
|||
@Column(name = ModelConstants.OAUTH2_TENANT_NAME_STRATEGY_PROPERTY) |
|||
private TenantNameStrategyType tenantNameStrategy; |
|||
@Column(name = ModelConstants.OAUTH2_TENANT_NAME_PATTERN_PROPERTY) |
|||
private String tenantNamePattern; |
|||
@Column(name = ModelConstants.OAUTH2_CUSTOMER_NAME_PATTERN_PROPERTY) |
|||
private String customerNamePattern; |
|||
@Column(name = ModelConstants.OAUTH2_DEFAULT_DASHBOARD_NAME_PROPERTY) |
|||
private String defaultDashboardName; |
|||
@Column(name = ModelConstants.OAUTH2_ALWAYS_FULL_SCREEN_PROPERTY) |
|||
private Boolean alwaysFullScreen; |
|||
@Column(name = ModelConstants.OAUTH2_MAPPER_URL_PROPERTY) |
|||
private String url; |
|||
@Column(name = ModelConstants.OAUTH2_MAPPER_USERNAME_PROPERTY) |
|||
private String username; |
|||
@Column(name = ModelConstants.OAUTH2_MAPPER_PASSWORD_PROPERTY) |
|||
private String password; |
|||
@Column(name = ModelConstants.OAUTH2_MAPPER_SEND_TOKEN_PROPERTY) |
|||
private Boolean sendToken; |
|||
|
|||
@Type(type = "json") |
|||
@Column(name = ModelConstants.OAUTH2_ADDITIONAL_INFO_PROPERTY) |
|||
private JsonNode additionalInfo; |
|||
|
|||
public OAuth2RegistrationEntity() { |
|||
super(); |
|||
} |
|||
|
|||
public OAuth2RegistrationEntity(OAuth2Registration registration) { |
|||
if (registration.getId() != null) { |
|||
this.setUuid(registration.getId().getId()); |
|||
} |
|||
this.setCreatedTime(registration.getCreatedTime()); |
|||
if (registration.getOauth2ParamsId() != null) { |
|||
this.oauth2ParamsId = registration.getOauth2ParamsId().getId(); |
|||
} |
|||
this.clientId = registration.getClientId(); |
|||
this.clientSecret = registration.getClientSecret(); |
|||
this.authorizationUri = registration.getAuthorizationUri(); |
|||
this.tokenUri = registration.getAccessTokenUri(); |
|||
this.scope = registration.getScope().stream().reduce((result, element) -> result + "," + element).orElse(""); |
|||
this.platforms = registration.getPlatforms() != null ? registration.getPlatforms().stream().map(Enum::name).reduce((result, element) -> result + "," + element).orElse("") : ""; |
|||
this.userInfoUri = registration.getUserInfoUri(); |
|||
this.userNameAttributeName = registration.getUserNameAttributeName(); |
|||
this.jwkSetUri = registration.getJwkSetUri(); |
|||
this.clientAuthenticationMethod = registration.getClientAuthenticationMethod(); |
|||
this.loginButtonLabel = registration.getLoginButtonLabel(); |
|||
this.loginButtonIcon = registration.getLoginButtonIcon(); |
|||
this.additionalInfo = registration.getAdditionalInfo(); |
|||
OAuth2MapperConfig mapperConfig = registration.getMapperConfig(); |
|||
if (mapperConfig != null) { |
|||
this.allowUserCreation = mapperConfig.isAllowUserCreation(); |
|||
this.activateUser = mapperConfig.isActivateUser(); |
|||
this.type = mapperConfig.getType(); |
|||
OAuth2BasicMapperConfig basicConfig = mapperConfig.getBasic(); |
|||
if (basicConfig != null) { |
|||
this.emailAttributeKey = basicConfig.getEmailAttributeKey(); |
|||
this.firstNameAttributeKey = basicConfig.getFirstNameAttributeKey(); |
|||
this.lastNameAttributeKey = basicConfig.getLastNameAttributeKey(); |
|||
this.tenantNameStrategy = basicConfig.getTenantNameStrategy(); |
|||
this.tenantNamePattern = basicConfig.getTenantNamePattern(); |
|||
this.customerNamePattern = basicConfig.getCustomerNamePattern(); |
|||
this.defaultDashboardName = basicConfig.getDefaultDashboardName(); |
|||
this.alwaysFullScreen = basicConfig.isAlwaysFullScreen(); |
|||
} |
|||
OAuth2CustomMapperConfig customConfig = mapperConfig.getCustom(); |
|||
if (customConfig != null) { |
|||
this.url = customConfig.getUrl(); |
|||
this.username = customConfig.getUsername(); |
|||
this.password = customConfig.getPassword(); |
|||
this.sendToken = customConfig.isSendToken(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public OAuth2Registration toData() { |
|||
OAuth2Registration registration = new OAuth2Registration(); |
|||
registration.setId(new OAuth2RegistrationId(id)); |
|||
registration.setCreatedTime(createdTime); |
|||
registration.setOauth2ParamsId(new OAuth2ParamsId(oauth2ParamsId)); |
|||
registration.setAdditionalInfo(additionalInfo); |
|||
registration.setMapperConfig( |
|||
OAuth2MapperConfig.builder() |
|||
.allowUserCreation(allowUserCreation) |
|||
.activateUser(activateUser) |
|||
.type(type) |
|||
.basic( |
|||
(type == MapperType.BASIC || type == MapperType.GITHUB) ? |
|||
OAuth2BasicMapperConfig.builder() |
|||
.emailAttributeKey(emailAttributeKey) |
|||
.firstNameAttributeKey(firstNameAttributeKey) |
|||
.lastNameAttributeKey(lastNameAttributeKey) |
|||
.tenantNameStrategy(tenantNameStrategy) |
|||
.tenantNamePattern(tenantNamePattern) |
|||
.customerNamePattern(customerNamePattern) |
|||
.defaultDashboardName(defaultDashboardName) |
|||
.alwaysFullScreen(alwaysFullScreen) |
|||
.build() |
|||
: null |
|||
) |
|||
.custom( |
|||
type == MapperType.CUSTOM ? |
|||
OAuth2CustomMapperConfig.builder() |
|||
.url(url) |
|||
.username(username) |
|||
.password(password) |
|||
.sendToken(sendToken) |
|||
.build() |
|||
: null |
|||
) |
|||
.build() |
|||
); |
|||
registration.setClientId(clientId); |
|||
registration.setClientSecret(clientSecret); |
|||
registration.setAuthorizationUri(authorizationUri); |
|||
registration.setAccessTokenUri(tokenUri); |
|||
registration.setScope(Arrays.asList(scope.split(","))); |
|||
registration.setPlatforms(StringUtils.isNotEmpty(platforms) ? Arrays.stream(platforms.split(",")) |
|||
.map(str -> PlatformType.valueOf(str)).collect(Collectors.toList()) : Collections.emptyList()); |
|||
registration.setUserInfoUri(userInfoUri); |
|||
registration.setUserNameAttributeName(userNameAttributeName); |
|||
registration.setJwkSetUri(jwkSetUri); |
|||
registration.setClientAuthenticationMethod(clientAuthenticationMethod); |
|||
registration.setLoginButtonLabel(loginButtonLabel); |
|||
registration.setLoginButtonIcon(loginButtonIcon); |
|||
return registration; |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.oauth2; |
|||
|
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Domain; |
|||
import org.thingsboard.server.dao.Dao; |
|||
|
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
public interface OAuth2DomainDao extends Dao<OAuth2Domain> { |
|||
|
|||
List<OAuth2Domain> findByOAuth2ParamsId(UUID oauth2ParamsId); |
|||
|
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.oauth2; |
|||
|
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Mobile; |
|||
import org.thingsboard.server.dao.Dao; |
|||
|
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
public interface OAuth2MobileDao extends Dao<OAuth2Mobile> { |
|||
|
|||
List<OAuth2Mobile> findByOAuth2ParamsId(UUID oauth2ParamsId); |
|||
|
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.oauth2; |
|||
|
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Params; |
|||
import org.thingsboard.server.dao.Dao; |
|||
|
|||
public interface OAuth2ParamsDao extends Dao<OAuth2Params> { |
|||
void deleteAll(); |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.oauth2; |
|||
|
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Registration; |
|||
import org.thingsboard.server.common.data.oauth2.PlatformType; |
|||
import org.thingsboard.server.common.data.oauth2.SchemeType; |
|||
import org.thingsboard.server.dao.Dao; |
|||
|
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
public interface OAuth2RegistrationDao extends Dao<OAuth2Registration> { |
|||
|
|||
List<OAuth2Registration> findEnabledByDomainSchemesDomainNameAndPkgNameAndPlatformType(List<SchemeType> domainSchemes, String domainName, String pkgName, PlatformType platformType); |
|||
|
|||
List<OAuth2Registration> findByOAuth2ParamsId(UUID oauth2ParamsId); |
|||
|
|||
String findAppSecret(UUID id, String pkgName); |
|||
|
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.sql.oauth2; |
|||
|
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.data.repository.CrudRepository; |
|||
import org.springframework.stereotype.Component; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Domain; |
|||
import org.thingsboard.server.dao.DaoUtil; |
|||
import org.thingsboard.server.dao.model.sql.OAuth2DomainEntity; |
|||
import org.thingsboard.server.dao.oauth2.OAuth2DomainDao; |
|||
import org.thingsboard.server.dao.sql.JpaAbstractDao; |
|||
|
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
@Component |
|||
@RequiredArgsConstructor |
|||
public class JpaOAuth2DomainDao extends JpaAbstractDao<OAuth2DomainEntity, OAuth2Domain> implements OAuth2DomainDao { |
|||
|
|||
private final OAuth2DomainRepository repository; |
|||
|
|||
@Override |
|||
protected Class<OAuth2DomainEntity> getEntityClass() { |
|||
return OAuth2DomainEntity.class; |
|||
} |
|||
|
|||
@Override |
|||
protected CrudRepository<OAuth2DomainEntity, UUID> getCrudRepository() { |
|||
return repository; |
|||
} |
|||
|
|||
@Override |
|||
public List<OAuth2Domain> findByOAuth2ParamsId(UUID oauth2ParamsId) { |
|||
return DaoUtil.convertDataList(repository.findByOauth2ParamsId(oauth2ParamsId)); |
|||
} |
|||
|
|||
} |
|||
|
|||
@ -0,0 +1,52 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.sql.oauth2; |
|||
|
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.data.repository.CrudRepository; |
|||
import org.springframework.stereotype.Component; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Mobile; |
|||
import org.thingsboard.server.dao.DaoUtil; |
|||
import org.thingsboard.server.dao.model.sql.OAuth2MobileEntity; |
|||
import org.thingsboard.server.dao.oauth2.OAuth2MobileDao; |
|||
import org.thingsboard.server.dao.sql.JpaAbstractDao; |
|||
|
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
@Component |
|||
@RequiredArgsConstructor |
|||
public class JpaOAuth2MobileDao extends JpaAbstractDao<OAuth2MobileEntity, OAuth2Mobile> implements OAuth2MobileDao { |
|||
|
|||
private final OAuth2MobileRepository repository; |
|||
|
|||
@Override |
|||
protected Class<OAuth2MobileEntity> getEntityClass() { |
|||
return OAuth2MobileEntity.class; |
|||
} |
|||
|
|||
@Override |
|||
protected CrudRepository<OAuth2MobileEntity, UUID> getCrudRepository() { |
|||
return repository; |
|||
} |
|||
|
|||
@Override |
|||
public List<OAuth2Mobile> findByOAuth2ParamsId(UUID oauth2ParamsId) { |
|||
return DaoUtil.convertDataList(repository.findByOauth2ParamsId(oauth2ParamsId)); |
|||
} |
|||
|
|||
} |
|||
|
|||
@ -0,0 +1,47 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.sql.oauth2; |
|||
|
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.data.repository.CrudRepository; |
|||
import org.springframework.stereotype.Component; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Params; |
|||
import org.thingsboard.server.dao.model.sql.OAuth2ParamsEntity; |
|||
import org.thingsboard.server.dao.oauth2.OAuth2ParamsDao; |
|||
import org.thingsboard.server.dao.sql.JpaAbstractDao; |
|||
|
|||
import java.util.UUID; |
|||
|
|||
@Component |
|||
@RequiredArgsConstructor |
|||
public class JpaOAuth2ParamsDao extends JpaAbstractDao<OAuth2ParamsEntity, OAuth2Params> implements OAuth2ParamsDao { |
|||
private final OAuth2ParamsRepository repository; |
|||
|
|||
@Override |
|||
protected Class<OAuth2ParamsEntity> getEntityClass() { |
|||
return OAuth2ParamsEntity.class; |
|||
} |
|||
|
|||
@Override |
|||
protected CrudRepository<OAuth2ParamsEntity, UUID> getCrudRepository() { |
|||
return repository; |
|||
} |
|||
|
|||
@Override |
|||
public void deleteAll() { |
|||
repository.deleteAll(); |
|||
} |
|||
} |
|||
@ -0,0 +1,64 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.sql.oauth2; |
|||
|
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.data.repository.CrudRepository; |
|||
import org.springframework.stereotype.Component; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Registration; |
|||
import org.thingsboard.server.common.data.oauth2.PlatformType; |
|||
import org.thingsboard.server.common.data.oauth2.SchemeType; |
|||
import org.thingsboard.server.dao.DaoUtil; |
|||
import org.thingsboard.server.dao.model.sql.OAuth2RegistrationEntity; |
|||
import org.thingsboard.server.dao.oauth2.OAuth2RegistrationDao; |
|||
import org.thingsboard.server.dao.sql.JpaAbstractDao; |
|||
|
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
@Component |
|||
@RequiredArgsConstructor |
|||
public class JpaOAuth2RegistrationDao extends JpaAbstractDao<OAuth2RegistrationEntity, OAuth2Registration> implements OAuth2RegistrationDao { |
|||
|
|||
private final OAuth2RegistrationRepository repository; |
|||
|
|||
@Override |
|||
protected Class<OAuth2RegistrationEntity> getEntityClass() { |
|||
return OAuth2RegistrationEntity.class; |
|||
} |
|||
|
|||
@Override |
|||
protected CrudRepository<OAuth2RegistrationEntity, UUID> getCrudRepository() { |
|||
return repository; |
|||
} |
|||
|
|||
@Override |
|||
public List<OAuth2Registration> findEnabledByDomainSchemesDomainNameAndPkgNameAndPlatformType(List<SchemeType> domainSchemes, String domainName, String pkgName, PlatformType platformType) { |
|||
return DaoUtil.convertDataList(repository.findEnabledByDomainSchemesDomainNameAndPkgNameAndPlatformType(domainSchemes, domainName, pkgName, |
|||
platformType != null ? "%" + platformType.name() + "%" : null)); |
|||
} |
|||
|
|||
@Override |
|||
public List<OAuth2Registration> findByOAuth2ParamsId(UUID oauth2ParamsId) { |
|||
return DaoUtil.convertDataList(repository.findByOauth2ParamsId(oauth2ParamsId)); |
|||
} |
|||
|
|||
@Override |
|||
public String findAppSecret(UUID id, String pkgName) { |
|||
return repository.findAppSecret(id, pkgName); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.sql.oauth2; |
|||
|
|||
import org.springframework.data.repository.CrudRepository; |
|||
import org.thingsboard.server.dao.model.sql.OAuth2DomainEntity; |
|||
|
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
public interface OAuth2DomainRepository extends CrudRepository<OAuth2DomainEntity, UUID> { |
|||
|
|||
List<OAuth2DomainEntity> findByOauth2ParamsId(UUID oauth2ParamsId); |
|||
|
|||
} |
|||
|
|||
@ -0,0 +1,28 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.sql.oauth2; |
|||
|
|||
import org.springframework.data.repository.CrudRepository; |
|||
import org.thingsboard.server.dao.model.sql.OAuth2MobileEntity; |
|||
|
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
public interface OAuth2MobileRepository extends CrudRepository<OAuth2MobileEntity, UUID> { |
|||
|
|||
List<OAuth2MobileEntity> findByOauth2ParamsId(UUID oauth2ParamsId); |
|||
|
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.sql.oauth2; |
|||
|
|||
import org.springframework.data.repository.CrudRepository; |
|||
import org.thingsboard.server.dao.model.sql.OAuth2ParamsEntity; |
|||
|
|||
import java.util.UUID; |
|||
|
|||
public interface OAuth2ParamsRepository extends CrudRepository<OAuth2ParamsEntity, UUID> { |
|||
} |
|||
@ -0,0 +1,53 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.sql.oauth2; |
|||
|
|||
import org.springframework.data.jpa.repository.Query; |
|||
import org.springframework.data.repository.CrudRepository; |
|||
import org.springframework.data.repository.query.Param; |
|||
import org.thingsboard.server.common.data.oauth2.SchemeType; |
|||
import org.thingsboard.server.dao.model.sql.OAuth2RegistrationEntity; |
|||
|
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
public interface OAuth2RegistrationRepository extends CrudRepository<OAuth2RegistrationEntity, UUID> { |
|||
|
|||
@Query("SELECT reg " + |
|||
"FROM OAuth2RegistrationEntity reg " + |
|||
"LEFT JOIN OAuth2ParamsEntity params on reg.oauth2ParamsId = params.id " + |
|||
"LEFT JOIN OAuth2DomainEntity domain on reg.oauth2ParamsId = domain.oauth2ParamsId " + |
|||
"WHERE params.enabled = true " + |
|||
"AND domain.domainName = :domainName " + |
|||
"AND domain.domainScheme IN (:domainSchemes) " + |
|||
"AND (:pkgName IS NULL OR EXISTS (SELECT mobile FROM OAuth2MobileEntity mobile WHERE mobile.oauth2ParamsId = reg.oauth2ParamsId AND mobile.pkgName = :pkgName)) " + |
|||
"AND (:platformFilter IS NULL OR reg.platforms IS NULL OR reg.platforms = '' OR reg.platforms LIKE :platformFilter)") |
|||
List<OAuth2RegistrationEntity> findEnabledByDomainSchemesDomainNameAndPkgNameAndPlatformType(@Param("domainSchemes") List<SchemeType> domainSchemes, |
|||
@Param("domainName") String domainName, |
|||
@Param("pkgName") String pkgName, |
|||
@Param("platformFilter") String platformFilter); |
|||
|
|||
List<OAuth2RegistrationEntity> findByOauth2ParamsId(UUID oauth2ParamsId); |
|||
|
|||
@Query("SELECT mobile.appSecret " + |
|||
"FROM OAuth2MobileEntity mobile " + |
|||
"LEFT JOIN OAuth2RegistrationEntity reg on mobile.oauth2ParamsId = reg.oauth2ParamsId " + |
|||
"WHERE reg.id = :registrationId " + |
|||
"AND mobile.pkgName = :pkgName") |
|||
String findAppSecret(@Param("registrationId") UUID id, |
|||
@Param("pkgName") String pkgName); |
|||
|
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0 |
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
:host{ |
|||
.fields-group { |
|||
padding: 8px; |
|||
margin: 10px 0; |
|||
border: 1px groove rgba(0, 0, 0, .25); |
|||
border-radius: 4px; |
|||
|
|||
legend { |
|||
color: rgba(0, 0, 0, .7); |
|||
} |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue