Implement discord login
This commit is contained in:
parent
1f34d041b7
commit
5248069a78
@ -38,6 +38,10 @@ dependencies {
|
|||||||
implementation("org.springframework.boot:spring-boot-starter-log4j2")
|
implementation("org.springframework.boot:spring-boot-starter-log4j2")
|
||||||
implementation("org.springframework.boot:spring-boot-starter-oauth2-client")
|
implementation("org.springframework.boot:spring-boot-starter-oauth2-client")
|
||||||
|
|
||||||
|
implementation('io.jsonwebtoken:jjwt-api:0.11.5')
|
||||||
|
implementation('io.jsonwebtoken:jjwt-impl:0.11.5')
|
||||||
|
implementation('io.jsonwebtoken:jjwt-gson:0.11.5')
|
||||||
|
|
||||||
implementation 'org.codehaus.groovy:groovy-all:3.0.8'
|
implementation 'org.codehaus.groovy:groovy-all:3.0.8'
|
||||||
|
|
||||||
implementation 'com.sedmelluq:lavaplayer:1.3.77'
|
implementation 'com.sedmelluq:lavaplayer:1.3.77'
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
package net.Broken.Api;
|
|
||||||
|
|
||||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
|
||||||
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
|
|
||||||
import org.springframework.security.oauth2.core.user.OAuth2User;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v2")
|
|
||||||
public class AuthController {
|
|
||||||
@GetMapping("user")
|
|
||||||
public String helloUser() {
|
|
||||||
return "Hello User";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("admin")
|
|
||||||
public String helloAdmin() {
|
|
||||||
return "Hello Admin";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
28
src/main/java/net/Broken/Api/Controllers/AuthController.java
Normal file
28
src/main/java/net/Broken/Api/Controllers/AuthController.java
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package net.Broken.Api.Controllers;
|
||||||
|
|
||||||
|
import net.Broken.Api.Data.Login;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/v2")
|
||||||
|
public class AuthController {
|
||||||
|
private final AuthenticationManager authenticationManager;
|
||||||
|
|
||||||
|
public AuthController(AuthenticationManager authenticationManager) {
|
||||||
|
this.authenticationManager = authenticationManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("login/discord")
|
||||||
|
public String helloUser(@RequestBody Login login) {
|
||||||
|
Authentication authentication = authenticationManager.authenticate(
|
||||||
|
new UsernamePasswordAuthenticationToken(login.redirectUri(), login.code())
|
||||||
|
);
|
||||||
|
|
||||||
|
return "Hello User";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
5
src/main/java/net/Broken/Api/Data/Login.java
Normal file
5
src/main/java/net/Broken/Api/Data/Login.java
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package net.Broken.Api.Data;
|
||||||
|
|
||||||
|
public record Login (String code, String redirectUri){
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package net.Broken.Api.Security.Data;
|
||||||
|
|
||||||
|
public class AccessTokenResponse {
|
||||||
|
public String access_token;
|
||||||
|
public String token_type;
|
||||||
|
public String expires_in;
|
||||||
|
public String refresh_token;
|
||||||
|
public String scope;
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package net.Broken.Api.Security.Data;
|
||||||
|
|
||||||
|
public class DiscordOauthUserInfo {
|
||||||
|
public String id;
|
||||||
|
public String username;
|
||||||
|
}
|
@ -1,18 +1,47 @@
|
|||||||
package net.Broken.Api.Security;
|
package net.Broken.Api.Security;
|
||||||
|
|
||||||
|
import net.Broken.Api.Security.Data.DiscordOauthUserInfo;
|
||||||
|
import net.Broken.Api.Security.Exception.OAuthLoginFail;
|
||||||
|
import net.Broken.Api.Security.Services.DiscordOauthService;
|
||||||
|
import net.Broken.DB.Entity.UserEntity;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.springframework.security.authentication.AuthenticationProvider;
|
import org.springframework.security.authentication.AuthenticationProvider;
|
||||||
|
import org.springframework.security.authentication.BadCredentialsException;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.AuthenticationException;
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
@Component
|
||||||
public class DiscordAuthenticationProvider implements AuthenticationProvider {
|
public class DiscordAuthenticationProvider implements AuthenticationProvider {
|
||||||
|
private final Logger logger = LogManager.getLogger();
|
||||||
|
private final DiscordOauthService discordOauthService;
|
||||||
|
|
||||||
|
public DiscordAuthenticationProvider(DiscordOauthService discordOauthService) {
|
||||||
|
this.discordOauthService = discordOauthService;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||||
authentication.getCredentials()
|
String redirectUri = authentication.getPrincipal().toString();
|
||||||
return null;
|
String code = authentication.getCredentials().toString();
|
||||||
|
try {
|
||||||
|
String token = discordOauthService.getAccessToken(code, redirectUri);
|
||||||
|
DiscordOauthUserInfo discordOauthUserInfo = discordOauthService.getUserInfo(token);
|
||||||
|
discordOauthService.revokeToken(token);
|
||||||
|
UserEntity userEntity = discordOauthService.loginOrRegisterDiscordUser(discordOauthUserInfo);
|
||||||
|
return new UsernamePasswordAuthenticationToken(userEntity, null, new ArrayList<>());
|
||||||
|
|
||||||
|
} catch (OAuthLoginFail e) {
|
||||||
|
throw new BadCredentialsException("Bad response form Discord Oauth server ! Code expired ?");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supports(Class<?> authentication) {
|
public boolean supports(Class<?> authentication) {
|
||||||
return false;
|
return authentication.equals(UsernamePasswordAuthenticationToken.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
package net.Broken.Api.Security.Exception;
|
||||||
|
|
||||||
|
public class OAuthLoginFail extends Exception{
|
||||||
|
}
|
@ -1,16 +0,0 @@
|
|||||||
package net.Broken.Api.Security;
|
|
||||||
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.RequestEntity;
|
|
||||||
|
|
||||||
class OAuth2UserAgentUtils {
|
|
||||||
static RequestEntity<?> withUserAgent(RequestEntity<?> request) {
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
|
||||||
headers.putAll(request.getHeaders());
|
|
||||||
headers.add(HttpHeaders.USER_AGENT, DISCORD_BOT_USER_AGENT);
|
|
||||||
|
|
||||||
return new RequestEntity<>(request.getBody(), headers, request.getMethod(), request.getUrl());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String DISCORD_BOT_USER_AGENT = "DiscordBot (https://github.com/fourscouts/blog/tree/master/oauth2-discord)";
|
|
||||||
}
|
|
@ -1,31 +1,42 @@
|
|||||||
package net.Broken.Api.Security;
|
package net.Broken.Api.Security;
|
||||||
|
|
||||||
|
import net.Broken.Api.Security.Services.UnauthorizedHandler;
|
||||||
import net.Broken.DB.Repository.UserRepository;
|
import net.Broken.DB.Repository.UserRepository;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||||
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||||
|
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
@Configuration
|
@Configuration
|
||||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
private final UnauthorizedHandler unauthorizedHandler;
|
||||||
private final UserRepository userRepository;
|
public SecurityConfig(UnauthorizedHandler unauthorizedHandler) {
|
||||||
|
this.unauthorizedHandler = unauthorizedHandler;
|
||||||
public SecurityConfig(UserRepository userRepository) {
|
|
||||||
this.userRepository = userRepository;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
http.cors().and().csrf().disable()
|
||||||
http.authorizeRequests()
|
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
|
||||||
|
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
|
||||||
|
.authorizeRequests()
|
||||||
// Our private endpoints
|
// Our private endpoints
|
||||||
.anyRequest().authenticated();
|
.antMatchers("/api/v2/**").permitAll()
|
||||||
|
.anyRequest().permitAll();
|
||||||
|
// http.authenticationProvider(discordAuthenticationProvider);
|
||||||
|
|
||||||
// http.exceptionHandling().authenticationEntryPoint((request, response, authException) -> {
|
// http.exceptionHandling().authenticationEntryPoint((request, response, authException) -> {
|
||||||
// response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
|
// response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
|
||||||
// });
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@Override
|
||||||
|
public AuthenticationManager authenticationManagerBean() throws Exception {
|
||||||
|
return super.authenticationManagerBean();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,140 @@
|
|||||||
|
package net.Broken.Api.Security.Services;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import net.Broken.Api.Security.Data.AccessTokenResponse;
|
||||||
|
import net.Broken.Api.Security.Data.DiscordOauthUserInfo;
|
||||||
|
import net.Broken.Api.Security.Exception.OAuthLoginFail;
|
||||||
|
import net.Broken.DB.Entity.UserEntity;
|
||||||
|
import net.Broken.DB.Repository.UserRepository;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.net.http.HttpClient;
|
||||||
|
import java.net.http.HttpRequest;
|
||||||
|
import java.net.http.HttpResponse;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class DiscordOauthService {
|
||||||
|
|
||||||
|
private final Logger logger = LogManager.getLogger();
|
||||||
|
@Value("${discord.client-id}")
|
||||||
|
private String clientId;
|
||||||
|
|
||||||
|
@Value("${discord.client-secret}")
|
||||||
|
private String clientSecret;
|
||||||
|
|
||||||
|
@Value("${discord.token-endpoint}")
|
||||||
|
private String tokenEndpoint;
|
||||||
|
|
||||||
|
@Value("${discord.tokenRevokeEndpoint}")
|
||||||
|
private String tokenRevokeEndpoint;
|
||||||
|
|
||||||
|
@Value("${discord.userInfoEnpoint}")
|
||||||
|
private String userInfoEnpoint;
|
||||||
|
|
||||||
|
private final UserRepository userRepository;
|
||||||
|
|
||||||
|
public DiscordOauthService(UserRepository userRepository) {
|
||||||
|
this.userRepository = userRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAccessToken(String code, String redirectUrl) throws OAuthLoginFail {
|
||||||
|
logger.debug("[OAUTH] Getting access token");
|
||||||
|
HashMap<String, String> data = new HashMap<>();
|
||||||
|
data.put("client_id", this.clientId);
|
||||||
|
data.put("client_secret", this.clientSecret);
|
||||||
|
data.put("grant_type", "authorization_code");
|
||||||
|
data.put("code", code);
|
||||||
|
data.put("redirect_uri", redirectUrl);
|
||||||
|
try {
|
||||||
|
HttpResponse<String> response = makeFormPost(this.tokenEndpoint, data);
|
||||||
|
if (response.statusCode() != 200) {
|
||||||
|
logger.warn("[OAUTH] Invalid response while getting AccessToken: Status Code: " + response.statusCode() + " Body:" + response.body());
|
||||||
|
throw new OAuthLoginFail();
|
||||||
|
}
|
||||||
|
Gson gson = new Gson();
|
||||||
|
AccessTokenResponse accessTokenResponse = gson.fromJson(response.body(), AccessTokenResponse.class);
|
||||||
|
return accessTokenResponse.access_token;
|
||||||
|
} catch (IOException | InterruptedException e) {
|
||||||
|
logger.catching(e);
|
||||||
|
throw new OAuthLoginFail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DiscordOauthUserInfo getUserInfo(String token) throws OAuthLoginFail {
|
||||||
|
logger.debug("[OAUTH] Getting user info");
|
||||||
|
try {
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(URI.create(this.userInfoEnpoint))
|
||||||
|
.header("Authorization", "Bearer " + token)
|
||||||
|
.GET()
|
||||||
|
.build();
|
||||||
|
HttpClient client = HttpClient.newHttpClient();
|
||||||
|
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
|
if (response.statusCode() != 200) {
|
||||||
|
logger.warn("[OAUTH] Invalid response while getting UserInfo: Status Code: " + response.statusCode() + " Body:" + response.body());
|
||||||
|
throw new OAuthLoginFail();
|
||||||
|
}
|
||||||
|
Gson gson = new Gson();
|
||||||
|
return gson.fromJson(response.body(), DiscordOauthUserInfo.class);
|
||||||
|
} catch (IOException | InterruptedException e) {
|
||||||
|
logger.catching(e);
|
||||||
|
throw new OAuthLoginFail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void revokeToken(String token) {
|
||||||
|
logger.debug("[OAUTH] Revoking access token");
|
||||||
|
HashMap<String, String> data = new HashMap<>();
|
||||||
|
data.put("token", token);
|
||||||
|
try {
|
||||||
|
HttpResponse<String> response = makeFormPost(this.tokenRevokeEndpoint, data);
|
||||||
|
if (response.statusCode() != 200) {
|
||||||
|
logger.warn("OAUTH] Invalid response while token revocation: Status Code: " + response.statusCode() + " Body:" + response.body());
|
||||||
|
}
|
||||||
|
} catch (IOException | InterruptedException e) {
|
||||||
|
logger.catching(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public UserEntity loginOrRegisterDiscordUser(DiscordOauthUserInfo discordOauthUserInfo) {
|
||||||
|
return userRepository
|
||||||
|
.findByJdaId(discordOauthUserInfo.id)
|
||||||
|
.orElseGet(() -> userRepository.save(new UserEntity(discordOauthUserInfo.username, discordOauthUserInfo.id)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getFormString(HashMap<String, String> params) throws UnsupportedEncodingException {
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
boolean first = true;
|
||||||
|
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||||
|
if (first)
|
||||||
|
first = false;
|
||||||
|
else
|
||||||
|
result.append("&");
|
||||||
|
result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
|
||||||
|
result.append("=");
|
||||||
|
result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private HttpResponse<String> makeFormPost(String endpoint, HashMap<String, String> data) throws IOException, InterruptedException {
|
||||||
|
HttpRequest.BodyPublisher body = HttpRequest.BodyPublishers.ofString(getFormString(data));
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(URI.create(tokenEndpoint))
|
||||||
|
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
.POST(body)
|
||||||
|
.build();
|
||||||
|
HttpClient client = HttpClient.newHttpClient();
|
||||||
|
return client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +1,12 @@
|
|||||||
package net.Broken.Api.Security;
|
package net.Broken.Api.Security.Services;
|
||||||
|
|
||||||
import net.Broken.DB.Entity.UserEntity;
|
import net.Broken.Api.Security.DiscordUserPrincipal;
|
||||||
import net.Broken.DB.Repository.UserRepository;
|
import net.Broken.DB.Repository.UserRepository;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class DiscordUserDetailsService implements UserDetailsService {
|
public class DiscordUserDetailsService implements UserDetailsService {
|
||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
@ -20,10 +18,9 @@ public class DiscordUserDetailsService implements UserDetailsService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||||
List<UserEntity> user = userRepository.findByName(username);
|
return new DiscordUserPrincipal(
|
||||||
if(user.isEmpty()){
|
userRepository.findByJdaId(username)
|
||||||
throw new UsernameNotFoundException(username);
|
.orElseThrow(() -> new UsernameNotFoundException(username))
|
||||||
}
|
);
|
||||||
return new DiscordUserPrincipal(user.get(0));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package net.Broken.Api.Security.Services;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class UnauthorizedHandler implements AuthenticationEntryPoint {
|
||||||
|
private final Logger logger = LogManager.getLogger();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
|
||||||
|
logger.error("[API] Unauthorized error: {}", authException.getMessage());
|
||||||
|
|
||||||
|
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||||
|
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||||
|
|
||||||
|
final Map<String, Object> body = new HashMap<>();
|
||||||
|
body.put("status", HttpServletResponse.SC_UNAUTHORIZED);
|
||||||
|
body.put("error", "Unauthorized");
|
||||||
|
body.put("message", authException.getMessage());
|
||||||
|
body.put("path", request.getServletPath());
|
||||||
|
|
||||||
|
final ObjectMapper mapper = new ObjectMapper();
|
||||||
|
mapper.writeValue(response.getOutputStream(), body);
|
||||||
|
}
|
||||||
|
}
|
@ -1,46 +0,0 @@
|
|||||||
package net.Broken.Api.Services;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.http.HttpClient;
|
|
||||||
import java.net.http.HttpRequest;
|
|
||||||
import java.net.http.HttpResponse;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class DiscordOauthService {
|
|
||||||
|
|
||||||
@Value("${discord.client-id}")
|
|
||||||
private String clientId;
|
|
||||||
|
|
||||||
@Value("${discord.client-secret}")
|
|
||||||
private String clientSecret;
|
|
||||||
|
|
||||||
@Value("${discord.token-endpoint}")
|
|
||||||
private String tokenEndpoint;
|
|
||||||
|
|
||||||
public String getAccessToken(String code, String redirectUrl){
|
|
||||||
HashMap<String, String> data = new HashMap<>();
|
|
||||||
data.put("client_id", this.clientId);
|
|
||||||
data.put("client_secret", this.clientSecret);
|
|
||||||
data.put("grant_type", "authorization_code");
|
|
||||||
data.put("code", code);
|
|
||||||
data.put("redirect_uri", redirectUrl);
|
|
||||||
|
|
||||||
Gson gson = new Gson();
|
|
||||||
HttpRequest.BodyPublisher body = HttpRequest.BodyPublishers.ofString(gson.toJson(data));
|
|
||||||
|
|
||||||
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
|
||||||
.uri(URI.create(tokenEndpoint))
|
|
||||||
.header("Content-Type", "application/json")
|
|
||||||
.POST(body)
|
|
||||||
.build();
|
|
||||||
HttpClient client = HttpClient.newHttpClient();
|
|
||||||
client.send(request, HttpResponse.BodyHandlers.ofString());
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
package net.Broken.Api.Services;
|
|
||||||
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
||||||
|
|
||||||
public class DiscordUserDetailService implements UserDetailsService {
|
|
||||||
@Override
|
|
||||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -21,20 +21,15 @@ public class UserEntity {
|
|||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
@Column(unique=true)
|
||||||
private String jdaId;
|
private String jdaId;
|
||||||
|
|
||||||
private String apiToken;
|
|
||||||
|
|
||||||
private boolean isBotAdmin = false;
|
private boolean isBotAdmin = false;
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
@OneToMany(fetch = FetchType.EAGER, mappedBy = "user")
|
@OneToMany(fetch = FetchType.EAGER, mappedBy = "user")
|
||||||
private List<UserStats> userStats;
|
private List<UserStats> userStats;
|
||||||
|
|
||||||
@JsonIgnore
|
|
||||||
private String password;
|
|
||||||
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "user")
|
@OneToMany(mappedBy = "user")
|
||||||
private List<PlaylistEntity> playlists;
|
private List<PlaylistEntity> playlists;
|
||||||
|
|
||||||
@ -42,36 +37,17 @@ public class UserEntity {
|
|||||||
public UserEntity() {
|
public UserEntity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserEntity(PendingUserEntity pendingUserEntity, String apiToken) {
|
public UserEntity(User user) {
|
||||||
this.name = pendingUserEntity.getName();
|
|
||||||
this.jdaId = pendingUserEntity.getJdaId();
|
|
||||||
this.password = pendingUserEntity.getPassword();
|
|
||||||
this.apiToken = apiToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserEntity(User user, PasswordEncoder passwordEncoder) {
|
|
||||||
this.name = user.getName();
|
this.name = user.getName();
|
||||||
this.jdaId = user.getId();
|
this.jdaId = user.getId();
|
||||||
this.apiToken = UserUtils.getInstance().generateApiToken();
|
|
||||||
this.password = passwordEncoder.encode(UserUtils.getInstance().generateCheckToken());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserEntity(String name, String id, PasswordEncoder passwordEncoder) {
|
public UserEntity(String name, String id) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.jdaId = id;
|
this.jdaId = id;
|
||||||
this.apiToken = UserUtils.getInstance().generateApiToken();
|
|
||||||
this.password = passwordEncoder.encode(UserUtils.getInstance().generateCheckToken());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getPassword() {
|
|
||||||
return password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPassword(String password) {
|
|
||||||
this.password = password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getId() {
|
public Integer getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@ -96,14 +72,6 @@ public class UserEntity {
|
|||||||
this.jdaId = jdaId;
|
this.jdaId = jdaId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getApiToken() {
|
|
||||||
return apiToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setApiToken(String apiToken) {
|
|
||||||
this.apiToken = apiToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<PlaylistEntity> getPlaylists() {
|
public List<PlaylistEntity> getPlaylists() {
|
||||||
return playlists;
|
return playlists;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import net.Broken.DB.Entity.UserEntity;
|
|||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Repository for UserEntity
|
* Repository for UserEntity
|
||||||
@ -12,7 +13,5 @@ import java.util.List;
|
|||||||
public interface UserRepository extends CrudRepository<UserEntity, Integer> {
|
public interface UserRepository extends CrudRepository<UserEntity, Integer> {
|
||||||
List<UserEntity> findByName(String name);
|
List<UserEntity> findByName(String name);
|
||||||
|
|
||||||
List<UserEntity> findByJdaId(String jdaId);
|
Optional<UserEntity> findByJdaId(String jdaId);
|
||||||
|
|
||||||
List<UserEntity> findByApiToken(String apiToken);
|
|
||||||
}
|
}
|
||||||
|
@ -43,33 +43,33 @@ public class PlaylistAPIController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@RequestMapping("/myPlaylist")
|
// @RequestMapping("/myPlaylist")
|
||||||
public List<PlaylistEntity> myPlaylist(@CookieValue(value = "token", defaultValue = "") String token) {
|
// public List<PlaylistEntity> myPlaylist(@CookieValue(value = "token", defaultValue = "") String token) {
|
||||||
if (token.isEmpty())
|
// if (token.isEmpty())
|
||||||
return null;
|
// return null;
|
||||||
else {
|
// else {
|
||||||
UserEntity user = userRepository.findByApiToken(token).get(0);
|
// UserEntity user = userRepository.findByApiToken(token).get(0);
|
||||||
return user.getPlaylists();
|
// return user.getPlaylists();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
// @RequestMapping("/createPlaylist")
|
||||||
|
// public ResponseEntity<PlaylistResponseData> createPlaylist(@CookieValue(value = "token", defaultValue = "") String token, @RequestBody CreatePlaylistData data) {
|
||||||
@RequestMapping("/createPlaylist")
|
//
|
||||||
public ResponseEntity<PlaylistResponseData> createPlaylist(@CookieValue(value = "token", defaultValue = "") String token, @RequestBody CreatePlaylistData data) {
|
// if (token.isEmpty())
|
||||||
|
// return new ResponseEntity<>(new PlaylistResponseData("Unknown Token!\nPlease Re-connect.", "token"), HttpStatus.UNAUTHORIZED);
|
||||||
if (token.isEmpty())
|
// else {
|
||||||
return new ResponseEntity<>(new PlaylistResponseData("Unknown Token!\nPlease Re-connect.", "token"), HttpStatus.UNAUTHORIZED);
|
// UserEntity user = userRepository.findByApiToken(token).get(0);
|
||||||
else {
|
// PlaylistEntity playlistEntity = new PlaylistEntity(data.name, user);
|
||||||
UserEntity user = userRepository.findByApiToken(token).get(0);
|
// playlistEntity = playlistRepository.save(playlistEntity);
|
||||||
PlaylistEntity playlistEntity = new PlaylistEntity(data.name, user);
|
// user.addPlaylist(playlistEntity);
|
||||||
playlistEntity = playlistRepository.save(playlistEntity);
|
// userRepository.save(user);
|
||||||
user.addPlaylist(playlistEntity);
|
// return new ResponseEntity<>(new PlaylistResponseData("Ok", playlistEntity), HttpStatus.OK);
|
||||||
userRepository.save(user);
|
// }
|
||||||
return new ResponseEntity<>(new PlaylistResponseData("Ok", playlistEntity), HttpStatus.OK);
|
//
|
||||||
}
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping("/addToPlaylist")
|
@RequestMapping("/addToPlaylist")
|
||||||
public ResponseEntity<PlaylistResponseData> addToPlaylist(@CookieValue(value = "token", defaultValue = "") String token, @RequestBody AddToPlaylistData data) {
|
public ResponseEntity<PlaylistResponseData> addToPlaylist(@CookieValue(value = "token", defaultValue = "") String token, @RequestBody AddToPlaylistData data) {
|
||||||
|
@ -1,171 +0,0 @@
|
|||||||
package net.Broken.RestApi;
|
|
||||||
|
|
||||||
import net.Broken.DB.Entity.UserEntity;
|
|
||||||
import net.Broken.DB.Repository.PendingUserRepository;
|
|
||||||
import net.Broken.DB.Repository.UserRepository;
|
|
||||||
import net.Broken.MainBot;
|
|
||||||
import net.Broken.RestApi.Data.UserManager.GuildInfo;
|
|
||||||
import net.Broken.RestApi.Data.UserManager.UserConnectionData;
|
|
||||||
import net.Broken.RestApi.Data.UserManager.UserInfoData;
|
|
||||||
import net.Broken.Tools.UserManager.Exceptions.PasswordNotMatchException;
|
|
||||||
import net.Broken.Tools.UserManager.Exceptions.UnknownTokenException;
|
|
||||||
import net.Broken.Tools.UserManager.Exceptions.UserNotFoundException;
|
|
||||||
import net.Broken.Tools.UserManager.Oauth;
|
|
||||||
import net.Broken.Tools.UserManager.Stats.GuildStatsPack;
|
|
||||||
import net.Broken.Tools.UserManager.Stats.UserStatsUtils;
|
|
||||||
import net.Broken.Tools.UserManager.UserUtils;
|
|
||||||
import net.dv8tion.jda.api.Permission;
|
|
||||||
import net.dv8tion.jda.api.entities.Guild;
|
|
||||||
import net.dv8tion.jda.api.entities.User;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rest Api controller for /api/userManagement
|
|
||||||
*/
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/userManagement")
|
|
||||||
public class UserManagerAPIController {
|
|
||||||
final
|
|
||||||
PendingUserRepository pendingUserRepository;
|
|
||||||
final
|
|
||||||
UserRepository userRepository;
|
|
||||||
private final PasswordEncoder passwordEncoder;
|
|
||||||
Logger logger = LogManager.getLogger();
|
|
||||||
UserUtils userUtils = UserUtils.getInstance();
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public UserManagerAPIController(PendingUserRepository pendingUserRepository, UserRepository userRepository, PasswordEncoder passwordEncoder) {
|
|
||||||
this.pendingUserRepository = pendingUserRepository;
|
|
||||||
this.userRepository = userRepository;
|
|
||||||
this.passwordEncoder = passwordEncoder;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// @RequestMapping(value = "/preRegister", method = RequestMethod.POST)
|
|
||||||
// public ResponseEntity<CheckResposeData> command(@RequestBody UserInfoData data) {
|
|
||||||
// if (data != null && data.name != null) {
|
|
||||||
// try {
|
|
||||||
// String id = userUtils.sendCheckToken(pendingUserRepository, userRepository, passwordEncoder, data);
|
|
||||||
// return new ResponseEntity<>(new CheckResposeData(true, data.name, "Message sent", id), HttpStatus.OK);
|
|
||||||
// } catch (UserNotFoundException e) {
|
|
||||||
// logger.warn("User \"" + data.name + "\" not found!");
|
|
||||||
// return new ResponseEntity<>(new CheckResposeData(false, data.name, "User not found on server!", ""), HttpStatus.NOT_FOUND);
|
|
||||||
// } catch (PasswordNotMatchException userAlreadyRegistered) {
|
|
||||||
// return new ResponseEntity<>(new CheckResposeData(false, data.name, "User already registered in pending database and password not match!", ""), HttpStatus.NOT_ACCEPTABLE);
|
|
||||||
//
|
|
||||||
// } catch (UserAlreadyRegistered userAlreadyRegistered) {
|
|
||||||
// return new ResponseEntity<>(new CheckResposeData(false, data.name, "User already registered in database!", ""), HttpStatus.NOT_ACCEPTABLE);
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// return new ResponseEntity<>(new CheckResposeData(false, "", "Missing parameter(s)", ""), HttpStatus.BAD_REQUEST);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @RequestMapping(value = "/confirmAccount", method = RequestMethod.POST)
|
|
||||||
// public ResponseEntity<UserConnectionData> confirAccount(@RequestBody ConfirmData data) {
|
|
||||||
// try {
|
|
||||||
// PendingUserEntity pUser = userUtils.confirmCheckToken(pendingUserRepository, Integer.parseInt(data.id), data.checkToken);
|
|
||||||
// UserEntity user = new UserEntity(pUser, userUtils.generateApiToken());
|
|
||||||
// userRepository.save(user);
|
|
||||||
// pendingUserRepository.delete(pUser);
|
|
||||||
//
|
|
||||||
// return new ResponseEntity<>(new UserConnectionData(true, user.getName(), user.getApiToken(), ""), HttpStatus.OK);
|
|
||||||
// } catch (TokenNotMatch tokenNotMatch) {
|
|
||||||
// logger.warn("Pre token not match for " + data.id + "!");
|
|
||||||
// return new ResponseEntity<>(new UserConnectionData(false, "Token not match!", "token"), HttpStatus.NOT_ACCEPTABLE);
|
|
||||||
// } catch (UserNotFoundException e) {
|
|
||||||
// logger.warn("Id not found in DB (" + data.id + ")");
|
|
||||||
// return new ResponseEntity<>(new UserConnectionData(false, "User not found on DB!", "user"), HttpStatus.NOT_ACCEPTABLE);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
@RequestMapping(value = "/requestToken", method = RequestMethod.POST)
|
|
||||||
public ResponseEntity<UserConnectionData> requestToken(@RequestBody UserInfoData data) {
|
|
||||||
try {
|
|
||||||
UserEntity user = userUtils.getUser(userRepository, passwordEncoder, data);
|
|
||||||
return new ResponseEntity<>(new UserConnectionData(true, user.getName(), user.getApiToken(), ""), HttpStatus.OK);
|
|
||||||
|
|
||||||
} catch (UserNotFoundException e) {
|
|
||||||
return new ResponseEntity<>(new UserConnectionData(false, "User not registered!", "user"), HttpStatus.NOT_ACCEPTABLE);
|
|
||||||
} catch (PasswordNotMatchException e) {
|
|
||||||
return new ResponseEntity<>(new UserConnectionData(false, "Wrong user name or password!", "password"), HttpStatus.NOT_ACCEPTABLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(value = "/getGuilds", method = RequestMethod.GET)
|
|
||||||
public ResponseEntity<List<GuildInfo>> getGuilds(@CookieValue("token") String token) {
|
|
||||||
try {
|
|
||||||
UserEntity userE = userUtils.getUserWithApiToken(userRepository, token);
|
|
||||||
User user = MainBot.jda.getUserById(userE.getJdaId());
|
|
||||||
List<GuildInfo> temp = new ArrayList<>();
|
|
||||||
if (user != null) {
|
|
||||||
for (Guild guild : user.getMutualGuilds()) {
|
|
||||||
|
|
||||||
temp.add(new GuildInfo(guild.getName(), guild.getId(), guild.getMember(user).hasPermission(Permission.ADMINISTRATOR), guild.getIconUrl()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ResponseEntity<>(temp, HttpStatus.OK);
|
|
||||||
|
|
||||||
|
|
||||||
} catch (UnknownTokenException e) {
|
|
||||||
logger.catching(e);
|
|
||||||
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@RequestMapping(value = "/oauthLogin", method = RequestMethod.POST)
|
|
||||||
public ResponseEntity<UserConnectionData> oauthLogin(@RequestParam(value = "token") String discordToken) {
|
|
||||||
logger.debug(discordToken);
|
|
||||||
UserEntity user = Oauth.getInstance().getUserEntity(discordToken, userRepository, passwordEncoder);
|
|
||||||
logger.info("OAuth login for " + user.getName());
|
|
||||||
return new ResponseEntity<>(new UserConnectionData(true, user.getName(), user.getApiToken(), ""), HttpStatus.OK);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@RequestMapping(value = "/checkToken", method = RequestMethod.GET)
|
|
||||||
public ResponseEntity checkToken(@CookieValue(value = "token") String token) {
|
|
||||||
try {
|
|
||||||
userUtils.getUserWithApiToken(userRepository, token);
|
|
||||||
return new ResponseEntity(HttpStatus.OK);
|
|
||||||
} catch (UnknownTokenException e) {
|
|
||||||
logger.info("Token check fail");
|
|
||||||
return new ResponseEntity(HttpStatus.UNAUTHORIZED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(value = "/getStatsPack", method = RequestMethod.GET)
|
|
||||||
public ResponseEntity<GuildStatsPack> getStatsPack(@CookieValue(value = "token") String token, @RequestParam(value = "guild") String guildID) {
|
|
||||||
try {
|
|
||||||
UserEntity user = userUtils.getUserWithApiToken(userRepository, token);
|
|
||||||
Guild guild = MainBot.jda.getGuildById(guildID);
|
|
||||||
if (guild == null) {
|
|
||||||
logger.warn("Request whit no guild!");
|
|
||||||
return new ResponseEntity(HttpStatus.BAD_REQUEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ResponseEntity<>(UserStatsUtils.getINSTANCE().getStatPack(user, guildID), HttpStatus.OK);
|
|
||||||
|
|
||||||
|
|
||||||
} catch (UnknownTokenException e) {
|
|
||||||
logger.info("Token check fail");
|
|
||||||
return new ResponseEntity(HttpStatus.UNAUTHORIZED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,75 +0,0 @@
|
|||||||
package net.Broken.Tools.UserManager;
|
|
||||||
|
|
||||||
import net.Broken.DB.Entity.UserEntity;
|
|
||||||
import net.Broken.DB.Repository.UserRepository;
|
|
||||||
import net.Broken.MainBot;
|
|
||||||
import net.dv8tion.jda.api.entities.User;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class Oauth {
|
|
||||||
private static Oauth INSTANCE = new Oauth();
|
|
||||||
Logger logger = LogManager.getLogger();
|
|
||||||
private String baseUrl = "https://discordapp.com/api";
|
|
||||||
private String mePath = "/users/@me";
|
|
||||||
|
|
||||||
public static Oauth getInstance() {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private JSONObject getUserId(String token) {
|
|
||||||
StringBuffer content = new StringBuffer();
|
|
||||||
try {
|
|
||||||
String httpsURL = baseUrl + mePath;
|
|
||||||
URL myUrl = new URL(httpsURL);
|
|
||||||
HttpURLConnection con = (HttpURLConnection) myUrl.openConnection();
|
|
||||||
con.setRequestProperty("Authorization", "Bearer " + token);
|
|
||||||
con.setRequestProperty("User-Agent", "DiscordBot (claptrapbot.com, 0.1)");
|
|
||||||
con.setRequestMethod("GET");
|
|
||||||
logger.debug("Response code: " + con.getResponseCode());
|
|
||||||
BufferedReader in = new BufferedReader(
|
|
||||||
new InputStreamReader(con.getInputStream()));
|
|
||||||
String inputLine;
|
|
||||||
|
|
||||||
while ((inputLine = in.readLine()) != null) {
|
|
||||||
content.append(inputLine);
|
|
||||||
}
|
|
||||||
in.close();
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
JSONObject json = new JSONObject(content.toString());
|
|
||||||
logger.debug(json);
|
|
||||||
|
|
||||||
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public UserEntity getUserEntity(String token, UserRepository userRepository, PasswordEncoder passwordEncoder) {
|
|
||||||
JSONObject discorResponse = getUserId(token);
|
|
||||||
List<UserEntity> userEntitys = userRepository.findByJdaId(discorResponse.getString("id"));
|
|
||||||
if (userEntitys.size() != 0) {
|
|
||||||
return userEntitys.get(0);
|
|
||||||
} else {
|
|
||||||
User jdaUser = MainBot.jda.getUserById(discorResponse.getString("id"));
|
|
||||||
UserEntity user;
|
|
||||||
if (jdaUser == null)
|
|
||||||
user = new UserEntity(discorResponse.getString("username"), discorResponse.getString("id"), passwordEncoder);
|
|
||||||
else
|
|
||||||
user = new UserEntity(MainBot.jda.getUserById(discorResponse.getString("id")), passwordEncoder);
|
|
||||||
user = userRepository.save(user);
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
package net.Broken.Tools.UserManager;
|
|
||||||
|
|
||||||
import net.Broken.DB.Entity.PendingPwdResetEntity;
|
|
||||||
import net.Broken.DB.Entity.UserEntity;
|
|
||||||
import net.Broken.DB.Repository.PendingPwdResetRepository;
|
|
||||||
import net.Broken.DB.Repository.UserRepository;
|
|
||||||
import net.Broken.SpringContext;
|
|
||||||
import net.Broken.Tools.UserManager.Exceptions.TokenNotMatch;
|
|
||||||
import net.Broken.Tools.UserManager.Exceptions.UserNotFoundException;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class PasswordResetUtils {
|
|
||||||
private static PasswordResetUtils INSTANCE = new PasswordResetUtils();
|
|
||||||
private Logger logger = LogManager.getLogger();
|
|
||||||
private PasswordEncoder passwordEncoder;
|
|
||||||
private PendingPwdResetRepository pendingPwdResetRepository;
|
|
||||||
private UserRepository userRepository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private default constructor
|
|
||||||
*/
|
|
||||||
private PasswordResetUtils() {
|
|
||||||
ApplicationContext context = SpringContext.getAppContext();
|
|
||||||
passwordEncoder = (PasswordEncoder) context.getBean("passwordEncoder");
|
|
||||||
pendingPwdResetRepository = (PendingPwdResetRepository) context.getBean("pendingPwdResetRepository");
|
|
||||||
userRepository = (UserRepository) context.getBean("userRepository");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Singleton
|
|
||||||
*
|
|
||||||
* @return Unique PasswordResetUtils instance
|
|
||||||
*/
|
|
||||||
public static PasswordResetUtils getInstance() {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String resetRequest(UserEntity userEntity) {
|
|
||||||
String token = UserUtils.getInstance().generateCheckToken();
|
|
||||||
String encodedToken = passwordEncoder.encode(token);
|
|
||||||
PendingPwdResetEntity entity = new PendingPwdResetEntity(userEntity, encodedToken);
|
|
||||||
pendingPwdResetRepository.save(entity);
|
|
||||||
return encodedToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void changePass(UserEntity userEntity, String token, String newPassword) throws UserNotFoundException, TokenNotMatch {
|
|
||||||
List<PendingPwdResetEntity> dbResults = pendingPwdResetRepository.findByUserEntity(userEntity);
|
|
||||||
if (dbResults.size() == 0)
|
|
||||||
throw new UserNotFoundException();
|
|
||||||
PendingPwdResetEntity pendingPwdReset = dbResults.get(0);
|
|
||||||
if (!passwordEncoder.matches(token, pendingPwdReset.getSecurityToken()))
|
|
||||||
throw new TokenNotMatch();
|
|
||||||
|
|
||||||
userEntity.setPassword(passwordEncoder.encode(newPassword));
|
|
||||||
userRepository.save(userEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -24,6 +24,7 @@ import java.awt.*;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public class UserStatsUtils {
|
public class UserStatsUtils {
|
||||||
|
|
||||||
@ -105,27 +106,16 @@ public class UserStatsUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<UserStats> getUserStats(User user) {
|
public List<UserStats> getUserStats(User user) {
|
||||||
UserEntity userEntity;
|
UserEntity userEntity = userRepository.findByJdaId(user.getId())
|
||||||
List<UserEntity> userList = userRepository.findByJdaId(user.getId());
|
.orElseGet(() -> genUserEntity(user));
|
||||||
if (userList.size() == 0) {
|
|
||||||
logger.debug("User not registered, generate it. User: " + user.getName() + " " + user.getDiscriminator());
|
|
||||||
userEntity = genUserEntity(user);
|
|
||||||
} else
|
|
||||||
userEntity = userList.get(0);
|
|
||||||
|
|
||||||
return getUserStats(userEntity);
|
return getUserStats(userEntity);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public UserStats getGuildUserStats(Member member) {
|
public UserStats getGuildUserStats(Member member) {
|
||||||
List<UserEntity> userEntityList = userRepository.findByJdaId(member.getUser().getId());
|
UserEntity userEntity = userRepository.findByJdaId(member.getUser().getId())
|
||||||
UserEntity userEntity;
|
.orElseGet(() -> genUserEntity(member.getUser()));
|
||||||
if (userEntityList.size() == 0) {
|
|
||||||
logger.debug("UserEntity not found for user " + member.getNickname());
|
|
||||||
userEntity = genUserEntity(member.getUser());
|
|
||||||
} else
|
|
||||||
userEntity = userEntityList.get(0);
|
|
||||||
|
|
||||||
List<UserStats> userStatsList = userStatsRepository.findByUserAndGuildId(userEntity, member.getGuild().getId());
|
List<UserStats> userStatsList = userStatsRepository.findByUserAndGuildId(userEntity, member.getGuild().getId());
|
||||||
if (userStatsList.size() == 0) {
|
if (userStatsList.size() == 0) {
|
||||||
@ -177,7 +167,7 @@ public class UserStatsUtils {
|
|||||||
|
|
||||||
|
|
||||||
private UserEntity genUserEntity(User user) {
|
private UserEntity genUserEntity(User user) {
|
||||||
UserEntity userEntity = new UserEntity(user, passwordEncoder);
|
UserEntity userEntity = new UserEntity(user);
|
||||||
return userRepository.save(userEntity);
|
return userRepository.save(userEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,32 +39,6 @@ public class UserUtils {
|
|||||||
public static UserUtils getInstance() {
|
public static UserUtils getInstance() {
|
||||||
return INSTANCE;
|
return INSTANCE;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Get user Entity
|
|
||||||
*
|
|
||||||
* @param userRepository User DB interface
|
|
||||||
* @param passwordEncoder Password encoder
|
|
||||||
* @param userInfoData Received data
|
|
||||||
* @return User Entity
|
|
||||||
* @throws UserNotFoundException User not found in User DB
|
|
||||||
* @throws PasswordNotMatchException Given password not match
|
|
||||||
*/
|
|
||||||
public UserEntity getUser(UserRepository userRepository, PasswordEncoder passwordEncoder, UserInfoData userInfoData) throws UserNotFoundException, PasswordNotMatchException {
|
|
||||||
List<UserEntity> users = userRepository.findByName(userInfoData.name);
|
|
||||||
if (users.size() < 1) {
|
|
||||||
logger.warn("Login with unknown username: " + userInfoData.name);
|
|
||||||
throw new UserNotFoundException();
|
|
||||||
} else {
|
|
||||||
UserEntity user = users.get(0);
|
|
||||||
if (passwordEncoder.matches(userInfoData.password, user.getPassword())) {
|
|
||||||
logger.info("Login successful for " + user.getName());
|
|
||||||
return user;
|
|
||||||
} else {
|
|
||||||
logger.warn("Login fail for " + user.getName() + ", wrong password!");
|
|
||||||
throw new PasswordNotMatchException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return token's UserEntity
|
* return token's UserEntity
|
||||||
@ -75,36 +49,12 @@ public class UserUtils {
|
|||||||
* @throws UnknownTokenException Can't find token on User DB
|
* @throws UnknownTokenException Can't find token on User DB
|
||||||
*/
|
*/
|
||||||
public UserEntity getUserWithApiToken(UserRepository userRepository, String token) throws UnknownTokenException {
|
public UserEntity getUserWithApiToken(UserRepository userRepository, String token) throws UnknownTokenException {
|
||||||
List<UserEntity> users = userRepository.findByApiToken(token);
|
// List<UserEntity> users = userRepository.findByApiToken(token);
|
||||||
if (users.size() > 0) {
|
// if (users.size() > 0) {
|
||||||
return users.get(0);
|
// return users.get(0);
|
||||||
} else
|
// } else
|
||||||
throw new UnknownTokenException();
|
// throw new UnknownTokenException();
|
||||||
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate API Token
|
|
||||||
*
|
|
||||||
* @return UUID String TODO Find something more secure
|
|
||||||
*/
|
|
||||||
public String generateApiToken() {
|
|
||||||
return UUID.randomUUID().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate short check token
|
|
||||||
*
|
|
||||||
* @return check token as string
|
|
||||||
*/
|
|
||||||
public String generateCheckToken() {
|
|
||||||
SecureRandom random = new SecureRandom();
|
|
||||||
long longToken = Math.abs(random.nextLong());
|
|
||||||
String randomStr = Long.toString(longToken, 16);
|
|
||||||
randomStr = randomStr.substring(0, 4);
|
|
||||||
randomStr = randomStr.toUpperCase();
|
|
||||||
return randomStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -38,4 +38,6 @@ server:
|
|||||||
discord:
|
discord:
|
||||||
client-id: ${CLIENT_ID}
|
client-id: ${CLIENT_ID}
|
||||||
client-secret: ${CLIENT_SECRET}
|
client-secret: ${CLIENT_SECRET}
|
||||||
token-endpoint: https://discord.com/api/oauth2/token
|
token-endpoint: https://discord.com/api/oauth2/token
|
||||||
|
tokenRevokeEndpoint: https://discord.com/api/oauth2/token/revoke
|
||||||
|
userInfoEnpoint: https://discord.com/api/users/@me
|
Loading…
Reference in New Issue
Block a user