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

com.feingto.cloud.domain.oauth2.ClientDetail Maven / Gradle / Ivy

There is a newer version: 2.3.5.RELEASE
Show newest version
package com.feingto.cloud.domain.oauth2;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.feingto.cloud.constants.Constants;
import com.feingto.cloud.domain.BaseEntity;
import com.feingto.cloud.domain.converters.SetPersistenceConverters;
import com.feingto.cloud.kit.reflection.BeanConvertKit;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
import org.springframework.util.Assert;

import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author longfei
 */
@Data
@EqualsAndHashCode(of = "clientId", callSuper = false)
@Accessors(chain = true)
@Entity
@Table(name = "oauth_client_detail")
@DynamicUpdate
public class ClientDetail extends BaseEntity {
    private static final long serialVersionUID = 1698363237742833368L;

    /**
     * 应用名称
     */
    @Column(length = 64)
    private String name;

    /**
     * 应用Key
     */
    @NotBlank(message = "应用Key不能为空")
    @Column(length = 64, unique = true, nullable = false)
    private String clientId;

    /**
     * 应用Secret
     */
    @NotBlank(message = "应用Secret不能为空")
    @Column(length = 64, nullable = false)
    private String clientSecret;

    /**
     * AccessToken有效秒数(1 hour = 3600 s, 1 day = 86400 s)
     */
    @Column
    private Integer accessTokenValidity;

    /**
     * RefreshToken有效秒数(30 days = 2592000 s)
     */
    @Column
    private Integer refreshTokenValidity;

    /**
     * 应用授权用户
     */
    @Column(length = 64)
    private String username;

    /**
     * 授权类型集合
     */
    @Convert(converter = SetPersistenceConverters.class)
    @Column
    private Set authorizedGrantTypes = new HashSet<>();

    /**
     * 资源ID集合
     */
    @Convert(converter = SetPersistenceConverters.class)
    @Column
    private Set resourceIds = new HashSet<>();

    /**
     * 应用权限集合
     */
    @Convert(converter = SetPersistenceConverters.class)
    @Column
    private Set authorities = new HashSet<>();

    /**
     * 回调URI(域名不带参数,授权码模式的redirect_uri参数必须是同域内的uri)
     */
    @Column
    private String redirectUri;

    /**
     * 应用授权作用域
     */
    @JsonIgnoreProperties(value = {"id", "clientDetail"}, allowSetters = true)
    @Fetch(FetchMode.SUBSELECT)
    @OneToMany(mappedBy = "clientDetail", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
    private Set clientDetailScopes = new HashSet<>();

    /**
     * 应用授权API
     */
    @JsonIgnoreProperties(value = {"id", "clientDetail"}, allowSetters = true)
    @Fetch(FetchMode.SUBSELECT)
    @OneToMany(mappedBy = "clientDetail", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
    private Set clientDetailApis = new HashSet<>();

    /**
     * 应用全部自动授权作用域
     */
    @Transient
    private boolean autoApproveAll = false;

    @Transient
    private Collection accessTokens = new ArrayList<>();

    public ClientDetail setClientDetailScopes(Set clientDetailScopes) {
        Optional.ofNullable(clientDetailScopes)
                .map(c -> {
                    this.clientDetailScopes.clear();
                    this.clientDetailScopes.addAll(c);
                    this.clientDetailScopes.forEach(item -> item.setClientDetail(this));
                    return c;
                })
                .orElseGet(() -> this.clientDetailScopes = null);
        return this;
    }

    public ClientDetail setClientDetailApis(Set clientDetailApis) {
        Optional.ofNullable(clientDetailApis)
                .map(c -> {
                    this.clientDetailApis.clear();
                    this.clientDetailApis.addAll(c);
                    this.clientDetailApis.forEach(item -> item.setClientDetail(this));
                    return c;
                })
                .orElseGet(() -> this.clientDetailApis = null);
        return this;
    }

    public static Function transform = clientDetail -> {
        Assert.notNull(clientDetail, "clientDetail can't be null");
        BaseClientDetails clientDetails = BeanConvertKit.convert(clientDetail, BaseClientDetails.class);
        Assert.notNull(clientDetails, "clientDetails can't be null");
        clientDetails.setAccessTokenValiditySeconds(clientDetail.getAccessTokenValidity());
        clientDetails.setRefreshTokenValiditySeconds(clientDetail.getRefreshTokenValidity());
        if (CollectionUtils.isNotEmpty(clientDetail.getAuthorities())) {
            clientDetails.setAuthorities(clientDetail.getAuthorities().stream()
                    .map(authority -> new SimpleGrantedAuthority(prefixAuthorityName(authority)))
                    .collect(Collectors.toSet()));
        }
        if (StringUtils.isNoneBlank(clientDetail.getRedirectUri())) {
            clientDetails.setRegisteredRedirectUri(Sets.newHashSet(clientDetail.getRedirectUri()));
        }
        if (CollectionUtils.isNotEmpty(clientDetail.getClientDetailScopes())) {
            clientDetails.setScope(clientDetail.getClientDetailScopes().stream()
                    .map(ClientDetailScope::getScope)
                    .map(Scope::getValue)
                    .collect(Collectors.toSet()));
            clientDetails.setAutoApproveScopes(clientDetail.getClientDetailScopes().stream()
                    .filter(ClientDetailScope::isAutoApprove)
                    .map(clientDetailScope -> clientDetailScope.getScope().getValue())
                    .collect(Collectors.toSet()));
        }
        Map additionalInformation = Maps.newHashMap();
        if (Objects.nonNull(clientDetail.getClientDetailApis())) {
            additionalInformation.put("apiIds", clientDetail.getClientDetailApis());
        }
        if (StringUtils.isNoneBlank(clientDetail.getUsername())) {
            additionalInformation.put("username", clientDetail.getUsername());
        }
        clientDetails.setAdditionalInformation(additionalInformation);
        return clientDetails;
    };

    public static ClientDetail wrap(ClientDetail clientDetail) {
        clientDetail.setClientSecret(null);
        clientDetail.getAuthorities().forEach(authority ->
                authority = eliminateAuthorityName(prefixAuthorityName(authority)));
        return clientDetail;
    }

    private static String prefixAuthorityName(String authorityName) {
        if (StringUtils.isNoneBlank(authorityName) && !authorityName.startsWith(Constants.AUTH_PREFIX)) {
            return Constants.AUTH_PREFIX + authorityName;
        }
        return authorityName;
    }

    private static String eliminateAuthorityName(String authorityName) {
        if (StringUtils.isNoneBlank(authorityName) && authorityName.startsWith(Constants.AUTH_PREFIX)) {
            return StringUtils.substringAfter(authorityName, Constants.AUTH_PREFIX);
        }
        return authorityName;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy