package com.yiboshi.science.config.security;

import com.yiboshi.science.service.SystemSetService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter;
import org.springframework.security.oauth2.provider.token.TokenStore;

import javax.sql.DataSource;

/**
 * @author qyh
 */
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private DataSource dataSource;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private UserDetailsService userDetailsService;

    private  ClientDetailsService clientDetailsService;

    @Autowired
    private SystemSetService systemSetService;


    public AuthorizationServerConfig(ClientDetailsService clientDetailsService) {
        this.clientDetailsService = clientDetailsService;
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.tokenKeyAccess("permitAll()")
                .checkTokenAccess("isAuthenticated()");
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
//     clients.inMemory()
//             .withClient("srp")
//             .secret(new BCryptPasswordEncoder().encode("user123"))
//             .authorizedGrantTypes("password", "refresh_token") //主要是这里，开始了密码模式
//             .refreshTokenValiditySeconds(2592000)
//             .accessTokenValiditySeconds(86400)
//             .scopes("all");
        clients.jdbc(dataSource);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(tokenStore);
        // 密码模式必须要配置这个
        endpoints.authenticationManager(authenticationManager);
        endpoints.userDetailsService(userDetailsService);
        endpoints.tokenServices(tokenServices());
    }

    public AuthorizationTokenService tokenServices() {
        //DefaultTokenServices services = new DefaultTokenServices();
        //新建一个TokenService继承并重写DefaultTokenServices中的方法，保证每次登录都会删除原来的token，达到一个账户不允许多端登录的效果
        AuthorizationTokenService services = new AuthorizationTokenService(systemSetService);
        //设置令牌2个小时过期，单位：秒
//        services.setAccessTokenValiditySeconds(accessTokenValidity == null ? 60 * 60 * 2 : accessTokenValidity);
        //设置刷新token的过期时间，单位：秒
//        services.setRefreshTokenValiditySeconds(refreshTokenValidity == null ? 60 * 60 * 24 * 30 : refreshTokenValidity);
        services.setSupportRefreshToken(true);
        services.setReuseRefreshToken(false);
        services.setTokenStore(tokenStore);
        services.setClientDetailsService(clientDetailsService);
//        services.setTokenEnhancer(accessTokenEnhancer);
        return services;
    }
}
