mirror of
https://github.com/TeamPiped/Piped-Backend.git
synced 2025-01-10 03:20:30 +05:30
Implement account deletion and cleanup some code
This commit is contained in:
parent
9b7246a029
commit
e7f2187b47
@ -18,7 +18,7 @@ dependencies {
|
|||||||
implementation 'org.bouncycastle:bcprov-jdk15on:1.70'
|
implementation 'org.bouncycastle:bcprov-jdk15on:1.70'
|
||||||
implementation 'com.github.FireMasterK.NewPipeExtractor:NewPipeExtractor:48beff184a9792c4787cfa05fce577c3adf89f56'
|
implementation 'com.github.FireMasterK.NewPipeExtractor:NewPipeExtractor:48beff184a9792c4787cfa05fce577c3adf89f56'
|
||||||
implementation 'com.github.FireMasterK:nanojson:9f4af3b739cc13f3d0d9d4b758bbe2b2ae7119d7'
|
implementation 'com.github.FireMasterK:nanojson:9f4af3b739cc13f3d0d9d4b758bbe2b2ae7119d7'
|
||||||
implementation 'com.nimbusds:oauth2-oidc-sdk:11.5.0'
|
implementation 'com.nimbusds:oauth2-oidc-sdk:11.5'
|
||||||
implementation 'com.fasterxml.jackson.core:jackson-core:2.15.2'
|
implementation 'com.fasterxml.jackson.core:jackson-core:2.15.2'
|
||||||
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.15.2'
|
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.15.2'
|
||||||
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2'
|
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2'
|
||||||
|
@ -2,10 +2,10 @@ package me.kavin.piped.server;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.nimbusds.jwt.JWTClaimsSet;
|
||||||
import com.nimbusds.oauth2.sdk.*;
|
import com.nimbusds.oauth2.sdk.*;
|
||||||
import com.nimbusds.oauth2.sdk.auth.ClientAuthentication;
|
import com.nimbusds.oauth2.sdk.auth.ClientAuthentication;
|
||||||
import com.nimbusds.oauth2.sdk.auth.ClientSecretBasic;
|
import com.nimbusds.oauth2.sdk.auth.ClientSecretBasic;
|
||||||
import com.nimbusds.oauth2.sdk.id.Identifier;
|
|
||||||
import com.nimbusds.oauth2.sdk.id.State;
|
import com.nimbusds.oauth2.sdk.id.State;
|
||||||
import com.nimbusds.openid.connect.sdk.*;
|
import com.nimbusds.openid.connect.sdk.*;
|
||||||
import com.nimbusds.openid.connect.sdk.claims.UserInfo;
|
import com.nimbusds.openid.connect.sdk.claims.UserInfo;
|
||||||
@ -28,6 +28,7 @@ import me.kavin.piped.server.handlers.auth.UserHandlers;
|
|||||||
import me.kavin.piped.utils.ErrorResponse;
|
import me.kavin.piped.utils.ErrorResponse;
|
||||||
import me.kavin.piped.utils.*;
|
import me.kavin.piped.utils.*;
|
||||||
import me.kavin.piped.utils.obj.MatrixHelper;
|
import me.kavin.piped.utils.obj.MatrixHelper;
|
||||||
|
import me.kavin.piped.utils.obj.OidcData;
|
||||||
import me.kavin.piped.utils.obj.OidcProvider;
|
import me.kavin.piped.utils.obj.OidcProvider;
|
||||||
import me.kavin.piped.utils.obj.federation.FederatedVideoInfo;
|
import me.kavin.piped.utils.obj.federation.FederatedVideoInfo;
|
||||||
import me.kavin.piped.utils.resp.*;
|
import me.kavin.piped.utils.resp.*;
|
||||||
@ -43,6 +44,8 @@ import org.xml.sax.InputSource;
|
|||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -58,6 +61,7 @@ public class ServerLauncher extends MultithreadedHttpServerLauncher {
|
|||||||
|
|
||||||
private static final HttpHeader FILE_NAME = HttpHeaders.of("x-file-name");
|
private static final HttpHeader FILE_NAME = HttpHeaders.of("x-file-name");
|
||||||
private static final HttpHeader LAST_ETAG = HttpHeaders.of("x-last-etag");
|
private static final HttpHeader LAST_ETAG = HttpHeaders.of("x-last-etag");
|
||||||
|
private static final Map<String, OidcData> PENDING_OIDC = new HashMap<>();
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
Executor executor() {
|
Executor executor() {
|
||||||
@ -285,7 +289,7 @@ public class ServerLauncher extends MultithreadedHttpServerLauncher {
|
|||||||
String function = request.getPathParameter("function");
|
String function = request.getPathParameter("function");
|
||||||
OidcProvider provider = getOidcProvider(request.getPathParameter("provider"));
|
OidcProvider provider = getOidcProvider(request.getPathParameter("provider"));
|
||||||
if (provider == null)
|
if (provider == null)
|
||||||
return HttpResponse.ofCode(500).withHtml("Can't find the provider on the server.");
|
return HttpResponse.ofCode(500).withHtml("Can't find the provider on the server");
|
||||||
|
|
||||||
URI callback = new URI(Constants.PUBLIC_URL + "/oidc/" + provider.name + "/callback");
|
URI callback = new URI(Constants.PUBLIC_URL + "/oidc/" + provider.name + "/callback");
|
||||||
|
|
||||||
@ -294,62 +298,62 @@ public class ServerLauncher extends MultithreadedHttpServerLauncher {
|
|||||||
String redirectUri = request.getQueryParameter("redirect");
|
String redirectUri = request.getQueryParameter("redirect");
|
||||||
|
|
||||||
if (StringUtils.isBlank(redirectUri)) {
|
if (StringUtils.isBlank(redirectUri)) {
|
||||||
return HttpResponse.ofCode(400).withHtml("Missing redirect parameter");
|
return HttpResponse.ofCode(400).withHtml("redirect is a required parameter");
|
||||||
}
|
}
|
||||||
|
|
||||||
State state = new State(new Identifier(24) + "." + redirectUri);
|
OidcData data = new OidcData(redirectUri);
|
||||||
Nonce nonce = new Nonce();
|
String state = data.getState();
|
||||||
|
|
||||||
|
PENDING_OIDC.put(state, data);
|
||||||
|
|
||||||
AuthenticationRequest oidcRequest = new AuthenticationRequest.Builder(
|
AuthenticationRequest oidcRequest = new AuthenticationRequest.Builder(
|
||||||
new ResponseType("code"),
|
new ResponseType("code"),
|
||||||
new Scope("openid"),
|
new Scope("openid"),
|
||||||
provider.clientID,
|
provider.clientID, callback).endpointURI(provider.authUri)
|
||||||
callback)
|
.state(new State(state)).nonce(data.nonce).build();
|
||||||
.endpointURI(provider.authUri)
|
|
||||||
.state(state)
|
|
||||||
.nonce(nonce)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
if (redirectUri.equals(Constants.FRONTEND_URL + "/login")) {
|
if (redirectUri.equals(Constants.FRONTEND_URL + "/login")) {
|
||||||
return HttpResponse.redirect302(oidcRequest.toURI().toString());
|
return HttpResponse.redirect302(oidcRequest.toURI().toString());
|
||||||
}
|
}
|
||||||
return HttpResponse.ok200().withHtml(
|
return HttpResponse.ok200().withHtml(
|
||||||
"<!DOCTYPE html><html style= \"color: white;background: #0f0f0f;\"><body>"
|
"<!DOCTYPE html><html style=\"color-scheme: dark light;\"><body>" +
|
||||||
+ "<h3>Warning:</h3> You are trying to give <pre style=\"font-size: 1.2rem;\">"
|
"<h3>Warning:</h3> You are trying to give <pre style=\"font-size: 1.2rem;\">" +
|
||||||
+ redirectUri
|
redirectUri +
|
||||||
+ "</pre> access to your Piped account. If you wish to continue click <a style=\"text-decoration: underline;color: inherit;\"href=\""
|
"</pre> access to your Piped account. If you wish to continue click " +
|
||||||
+ oidcRequest.toURI().toString()
|
"<a style=\"text-decoration: underline;color: inherit;\"href=\"" +
|
||||||
+ "\">here</a></body></html>");
|
oidcRequest.toURI().toString() +
|
||||||
|
"\">here</a></body></html>");
|
||||||
}
|
}
|
||||||
case "callback" -> {
|
case "callback" -> {
|
||||||
ClientAuthentication clientAuth = new ClientSecretBasic(provider.clientID, provider.clientSecret);
|
ClientAuthentication clientAuth = new ClientSecretBasic(provider.clientID, provider.clientSecret);
|
||||||
|
|
||||||
AuthenticationResponse response = AuthenticationResponseParser.parse(
|
AuthenticationSuccessResponse sr = parseOidcUri(URI.create(request.getFullUrl()));
|
||||||
URI.create(request.getFullUrl())
|
|
||||||
);
|
|
||||||
|
|
||||||
if (response instanceof AuthenticationErrorResponse) {
|
OidcData data = PENDING_OIDC.get(sr.getState().toString());
|
||||||
// The OpenID provider returned an error
|
if (data == null) {
|
||||||
System.err.println(response.toErrorResponse().getErrorObject());
|
return HttpResponse.ofCode(400).withHtml(
|
||||||
return HttpResponse.ofCode(500).withHtml("OpenID provider returned an error:\n\n" + response.toErrorResponse().getErrorObject().toString());
|
"Your oidc provider sent invalid state data. Try again or contact your oidc admin"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
AuthenticationSuccessResponse sr = response.toSuccessResponse();
|
|
||||||
|
|
||||||
AuthorizationCode code = sr.getAuthorizationCode();
|
AuthorizationCode code = sr.getAuthorizationCode();
|
||||||
AuthorizationGrant codeGrant = new AuthorizationCodeGrant(
|
AuthorizationGrant codeGrant = new AuthorizationCodeGrant(code, callback);
|
||||||
code, callback
|
|
||||||
);
|
|
||||||
|
|
||||||
TokenRequest tr = new TokenRequest(provider.tokenUri, clientAuth, codeGrant);
|
TokenRequest tr = new TokenRequest(provider.tokenUri, clientAuth, codeGrant);
|
||||||
TokenResponse tokenResponse = OIDCTokenResponseParser.parse(tr.toHTTPRequest().send());
|
OIDCTokenResponse tokenResponse = (OIDCTokenResponse) OIDCTokenResponseParser.parse(tr.toHTTPRequest().send());
|
||||||
|
|
||||||
if (!tokenResponse.indicatesSuccess()) {
|
if (!tokenResponse.indicatesSuccess()) {
|
||||||
TokenErrorResponse errorResponse = tokenResponse.toErrorResponse();
|
TokenErrorResponse errorResponse = tokenResponse.toErrorResponse();
|
||||||
return HttpResponse.ofCode(500).withHtml("Failure while trying to request token:\n\n" + errorResponse.getErrorObject().getDescription());
|
return HttpResponse.ofCode(500).withHtml("Failure while trying to request token:\n\n" + errorResponse.getErrorObject().getDescription());
|
||||||
}
|
}
|
||||||
|
|
||||||
OIDCTokenResponse successResponse = (OIDCTokenResponse) tokenResponse.toSuccessResponse();
|
OIDCTokenResponse successResponse = tokenResponse.toSuccessResponse();
|
||||||
|
|
||||||
|
if (data.isInvalidNonce((String) successResponse.getOIDCTokens().getIDToken().getJWTClaimsSet().getClaim("nonce"))) {
|
||||||
|
return HttpResponse.ofCode(400).withHtml(
|
||||||
|
"Your oidc provider sent an invalid nonce. Try again or contact your oidc admin"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
UserInfoRequest ur = new UserInfoRequest(provider.userinfoUri, successResponse.getOIDCTokens().getBearerAccessToken());
|
UserInfoRequest ur = new UserInfoRequest(provider.userinfoUri, successResponse.getOIDCTokens().getBearerAccessToken());
|
||||||
UserInfoResponse userInfoResponse = UserInfoResponse.parse(ur.toHTTPRequest().send());
|
UserInfoResponse userInfoResponse = UserInfoResponse.parse(ur.toHTTPRequest().send());
|
||||||
@ -363,11 +367,57 @@ public class ServerLauncher extends MultithreadedHttpServerLauncher {
|
|||||||
UserInfo userInfo = userInfoResponse.toSuccessResponse().getUserInfo();
|
UserInfo userInfo = userInfoResponse.toSuccessResponse().getUserInfo();
|
||||||
|
|
||||||
String sessionId = UserHandlers.oidcCallbackResponse(provider.name, userInfo.getSubject().toString());
|
String sessionId = UserHandlers.oidcCallbackResponse(provider.name, userInfo.getSubject().toString());
|
||||||
|
return HttpResponse.redirect302(data.data + "?session=" + sessionId);
|
||||||
|
}
|
||||||
|
case "delete" -> {
|
||||||
|
ClientAuthentication clientAuth = new ClientSecretBasic(provider.clientID, provider.clientSecret);
|
||||||
|
|
||||||
return HttpResponse.redirect302(sr.getState().toString().split("\\.", 2)[1] + "?session=" + sessionId);
|
AuthenticationSuccessResponse sr = parseOidcUri(URI.create(request.getFullUrl()));
|
||||||
|
|
||||||
|
OidcData data = UserHandlers.PENDING_OIDC.get(sr.getState().toString());
|
||||||
|
if (data == null) {
|
||||||
|
return HttpResponse.ofCode(400).withHtml(
|
||||||
|
"Your oidc provider sent invalid state data. Try again or contact your oidc admin"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
long start = Long.parseLong(data.data.split("\\|")[1]);
|
||||||
|
String session = data.data.split("\\|")[0];
|
||||||
|
|
||||||
|
AuthorizationCode code = sr.getAuthorizationCode();
|
||||||
|
AuthorizationGrant codeGrant = new AuthorizationCodeGrant(code, new URI(Constants.PUBLIC_URL + request.getPath()));
|
||||||
|
|
||||||
|
|
||||||
|
TokenRequest tr = new TokenRequest(provider.tokenUri, clientAuth, codeGrant);
|
||||||
|
TokenResponse tokenResponse = OIDCTokenResponseParser.parse(tr.toHTTPRequest().send());
|
||||||
|
|
||||||
|
if (!tokenResponse.indicatesSuccess()) {
|
||||||
|
TokenErrorResponse errorResponse = tokenResponse.toErrorResponse();
|
||||||
|
return HttpResponse.ofCode(500).withHtml("Failure while trying to request token:\n\n" + errorResponse.getErrorObject().getDescription());
|
||||||
|
}
|
||||||
|
|
||||||
|
OIDCTokenResponse successResponse = (OIDCTokenResponse) tokenResponse.toSuccessResponse();
|
||||||
|
|
||||||
|
JWTClaimsSet claims = successResponse.getOIDCTokens().getIDToken().getJWTClaimsSet();
|
||||||
|
|
||||||
|
if (data.isInvalidNonce((String) claims.getClaim("nonce"))) {
|
||||||
|
return HttpResponse.ofCode(400).withHtml(
|
||||||
|
"Your oidc provider sent an invalid nonce. Please try again or contact your oidc admin."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
long authTime = (long) claims.getClaim("auth_time");
|
||||||
|
|
||||||
|
if (authTime < start) {
|
||||||
|
return HttpResponse.ofCode(500).withHtml(
|
||||||
|
"Your oidc provider didn't verify your identity. Please try again or contact your oidc admin."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return HttpResponse.redirect302(Constants.FRONTEND_URL + "/preferences?deleted=" + UserHandlers.deleteOidcUserResponse(session));
|
||||||
}
|
}
|
||||||
default -> {
|
default -> {
|
||||||
return HttpResponse.ofCode(500).withHtml("Invalid function `" + function + "`.");
|
return HttpResponse.ofCode(500).withHtml("Invalid function `" + function + "`");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -630,6 +680,17 @@ public class ServerLauncher extends MultithreadedHttpServerLauncher {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static AuthenticationSuccessResponse parseOidcUri(URI uri) throws Exception {
|
||||||
|
AuthenticationResponse response = AuthenticationResponseParser.parse(uri);
|
||||||
|
|
||||||
|
if (response instanceof AuthenticationErrorResponse) {
|
||||||
|
// The OpenID provider returned an error
|
||||||
|
System.err.println(response.toErrorResponse().getErrorObject());
|
||||||
|
throw new Exception(response.toErrorResponse().getErrorObject().toString());
|
||||||
|
}
|
||||||
|
return response.toSuccessResponse();
|
||||||
|
}
|
||||||
|
|
||||||
private static String[] getArray(String s) {
|
private static String[] getArray(String s) {
|
||||||
|
|
||||||
if (s == null) {
|
if (s == null) {
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
package me.kavin.piped.server.handlers.auth;
|
package me.kavin.piped.server.handlers.auth;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.nimbusds.oauth2.sdk.ResponseType;
|
||||||
|
import com.nimbusds.oauth2.sdk.Scope;
|
||||||
|
import com.nimbusds.oauth2.sdk.id.State;
|
||||||
|
import com.nimbusds.openid.connect.sdk.AuthenticationRequest;
|
||||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||||
import jakarta.persistence.criteria.CriteriaQuery;
|
import jakarta.persistence.criteria.CriteriaQuery;
|
||||||
import jakarta.persistence.criteria.Root;
|
import jakarta.persistence.criteria.Root;
|
||||||
@ -9,6 +13,8 @@ import me.kavin.piped.utils.DatabaseHelper;
|
|||||||
import me.kavin.piped.utils.DatabaseSessionFactory;
|
import me.kavin.piped.utils.DatabaseSessionFactory;
|
||||||
import me.kavin.piped.utils.ExceptionHandler;
|
import me.kavin.piped.utils.ExceptionHandler;
|
||||||
import me.kavin.piped.utils.RequestUtils;
|
import me.kavin.piped.utils.RequestUtils;
|
||||||
|
import me.kavin.piped.utils.obj.OidcData;
|
||||||
|
import me.kavin.piped.utils.obj.OidcProvider;
|
||||||
import me.kavin.piped.utils.obj.db.User;
|
import me.kavin.piped.utils.obj.db.User;
|
||||||
import me.kavin.piped.utils.resp.*;
|
import me.kavin.piped.utils.resp.*;
|
||||||
import org.apache.commons.codec.digest.DigestUtils;
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
@ -19,6 +25,10 @@ import org.springframework.security.crypto.argon2.Argon2PasswordEncoder;
|
|||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@ -27,6 +37,7 @@ import static me.kavin.piped.consts.Constants.mapper;
|
|||||||
public class UserHandlers {
|
public class UserHandlers {
|
||||||
private static final Argon2PasswordEncoder argon2PasswordEncoder = Argon2PasswordEncoder.defaultsForSpringSecurity_v5_8();
|
private static final Argon2PasswordEncoder argon2PasswordEncoder = Argon2PasswordEncoder.defaultsForSpringSecurity_v5_8();
|
||||||
private static final BCryptPasswordEncoder bcryptPasswordEncoder = new BCryptPasswordEncoder();
|
private static final BCryptPasswordEncoder bcryptPasswordEncoder = new BCryptPasswordEncoder();
|
||||||
|
public static final Map<String, OidcData> PENDING_OIDC = new HashMap<>();
|
||||||
|
|
||||||
public static byte[] registerResponse(String user, String pass) throws Exception {
|
public static byte[] registerResponse(String user, String pass) throws Exception {
|
||||||
|
|
||||||
@ -111,6 +122,7 @@ public class UserHandlers {
|
|||||||
|
|
||||||
public static String oidcCallbackResponse(String provider, String uid) {
|
public static String oidcCallbackResponse(String provider, String uid) {
|
||||||
try (Session s = DatabaseSessionFactory.createSession()) {
|
try (Session s = DatabaseSessionFactory.createSession()) {
|
||||||
|
// TODO: Add oidc provider to database
|
||||||
String dbName = provider + "-" + uid;
|
String dbName = provider + "-" + uid;
|
||||||
CriteriaBuilder cb = s.getCriteriaBuilder();
|
CriteriaBuilder cb = s.getCriteriaBuilder();
|
||||||
CriteriaQuery<User> cr = cb.createQuery(User.class);
|
CriteriaQuery<User> cr = cb.createQuery(User.class);
|
||||||
@ -148,12 +160,21 @@ public class UserHandlers {
|
|||||||
|
|
||||||
String hash = user.getPassword();
|
String hash = user.getPassword();
|
||||||
|
|
||||||
if (hash.equals("")) {
|
if (hash.isEmpty()) {
|
||||||
//TODO: Authorize against oidc provider before deletion
|
//TODO: Get user from oidc table and lookup provider
|
||||||
var tr = s.beginTransaction();
|
OidcProvider provider = Constants.OIDC_PROVIDERS.get(0);
|
||||||
s.remove(user);
|
URI callback = URI.create(String.format("%s/oidc/%s/delete", Constants.PUBLIC_URL, provider.name));
|
||||||
tr.commit();
|
OidcData data = new OidcData(session + "|" + Instant.now().getEpochSecond());
|
||||||
return mapper.writeValueAsBytes(new DeleteUserResponse(user.getUsername()));
|
String state = data.getState();
|
||||||
|
PENDING_OIDC.put(state, data);
|
||||||
|
|
||||||
|
AuthenticationRequest oidcRequest = new AuthenticationRequest.Builder(
|
||||||
|
new ResponseType("code"),
|
||||||
|
new Scope("openid"), provider.clientID, callback).endpointURI(provider.authUri)
|
||||||
|
.state(new State(state)).nonce(data.nonce).maxAge(0).build();
|
||||||
|
|
||||||
|
|
||||||
|
return String.format("{\"redirect\": \"%s\"}", oidcRequest.toURI().toString()).getBytes();
|
||||||
}
|
}
|
||||||
if (!hashMatch(hash, pass))
|
if (!hashMatch(hash, pass))
|
||||||
ExceptionHandler.throwErrorResponse(new IncorrectCredentialsResponse());
|
ExceptionHandler.throwErrorResponse(new IncorrectCredentialsResponse());
|
||||||
@ -166,6 +187,18 @@ public class UserHandlers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String deleteOidcUserResponse(String session) throws IOException {
|
||||||
|
try (Session s = DatabaseSessionFactory.createSession()) {
|
||||||
|
User user = DatabaseHelper.getUserFromSession(session);
|
||||||
|
|
||||||
|
var tr = s.beginTransaction();
|
||||||
|
s.remove(user);
|
||||||
|
tr.commit();
|
||||||
|
|
||||||
|
return user.getUsername();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static byte[] logoutResponse(String session) throws JsonProcessingException {
|
public static byte[] logoutResponse(String session) throws JsonProcessingException {
|
||||||
|
|
||||||
if (StringUtils.isBlank(session))
|
if (StringUtils.isBlank(session))
|
||||||
|
36
src/main/java/me/kavin/piped/utils/obj/OidcData.java
Normal file
36
src/main/java/me/kavin/piped/utils/obj/OidcData.java
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package me.kavin.piped.utils.obj;
|
||||||
|
|
||||||
|
import com.nimbusds.openid.connect.sdk.Nonce;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
public class OidcData {
|
||||||
|
public final Nonce nonce;
|
||||||
|
|
||||||
|
public String data;
|
||||||
|
|
||||||
|
public OidcData(String data) {
|
||||||
|
this.nonce = new Nonce();
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInvalidNonce(String nonce) {
|
||||||
|
return !nonce.equals(this.nonce.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getState() {
|
||||||
|
String value = nonce + data;
|
||||||
|
|
||||||
|
try {
|
||||||
|
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||||
|
byte[] hash = md.digest(value.getBytes(StandardCharsets.UTF_8));
|
||||||
|
return Base64.getEncoder().encodeToString(hash);
|
||||||
|
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
throw new RuntimeException("SHA-256 not supported", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user