Conversation
# Conflicts: # build.gradle
FireMasterK
left a comment
There was a problem hiding this comment.
One thing I don't like is there's too much business logic in ServerLaunche, I would ideally like to move it to a new file like OidcHandlers.java or to the existing UserHandlers class.
|
I have cleaned up the code and made sure everything works. Here are a few things worth mentioning:
Please let me know if there are any questions or concerns. I have tested this and from my view this could be merged edit: Found the alternative for |
src/main/java/me/kavin/piped/server/handlers/auth/UserHandlers.java
Outdated
Show resolved
Hide resolved
src/main/java/me/kavin/piped/server/handlers/auth/UserHandlers.java
Outdated
Show resolved
Hide resolved
| for (int i = 0; i < Constants.OIDC_PROVIDERS.size(); i++) { | ||
| OidcProvider curr = Constants.OIDC_PROVIDERS.get(i); | ||
| if (curr == null || !curr.name.equals(provider)) continue; | ||
| return curr; | ||
| } |
There was a problem hiding this comment.
| for (int i = 0; i < Constants.OIDC_PROVIDERS.size(); i++) { | |
| OidcProvider curr = Constants.OIDC_PROVIDERS.get(i); | |
| if (curr == null || !curr.name.equals(provider)) continue; | |
| return curr; | |
| } | |
| for (OidcProvider curr : Constants.OIDC_PROVIDERS) { | |
| if (curr != null && curr.name.equals(provider)) return curr; | |
| } | |
| .state(new State(state)) | ||
| .nonce(data.getOidNonce()).build(); | ||
|
|
||
| if (redirectUri.equals(Constants.FRONTEND_URL + "/login")) { |
There was a problem hiding this comment.
We probably shouldn't hardcode the url path here, maybe it makes sense to parse the domain of the redirectUri and see if equals Constants.FRONTEND_URL? Or we could just do a redirectUri.startsWith(Constants.FRONTEND_URL + "/").
| return HttpResponse.ok200().withHtml( | ||
| "<!DOCTYPE html><html style=\"color-scheme: dark light;\"><body>" + | ||
| "<h3>Warning:</h3> You are trying to give <pre style=\"font-size: 1.2rem;\">" + | ||
| redirectUri + |
There was a problem hiding this comment.
redirectUri needs to be HTML escaped or checked if it's a real URL, otherwise that would allow HTML injection.
|
|
||
| OidcData data = DatabaseHelper.getOidcData(authResponse.getState().toString()); | ||
| if (data == null) { | ||
| return HttpResponse.ofCode(400).withHtml( |
There was a problem hiding this comment.
Since we don't provide any styling or color-scheme: dark light;, withPlainText would probably be better to not become flashed in dark mode
| AuthorizationCode code = authResponse.getAuthorizationCode(); | ||
|
|
||
| if (code == null) { | ||
| return HttpResponse.ofCode(400).withHtml( |
| return HttpResponse.ofCode(400).withHtml("Received a bad token. Please try again"); | ||
| } catch (JOSEException e) { | ||
| System.err.println("Token processing error: " + e); | ||
| return HttpResponse.ofCode(500).withHtml("Internal processing error. Please try again"); |
| UserInfoResponse userInfoResponse = UserInfoResponse.parse(ur.toHTTPRequest().send()); | ||
|
|
||
| if (!userInfoResponse.indicatesSuccess()) { | ||
| return HttpResponse.ofCode(500).withHtml( |
|
|
||
| cr.select(root).where(root.get("sub").in(sub)); | ||
|
|
||
| OidcUserData dbuser = s.createQuery(cr).uniqueResult(); |
There was a problem hiding this comment.
nit:
| OidcUserData dbuser = s.createQuery(cr).uniqueResult(); | |
| OidcUserData dbUser = s.createQuery(cr).uniqueResult(); |
| for (OidcProvider oidcProvider : Constants.OIDC_PROVIDERS) { | ||
| if (oidcProvider.name.equals(oidcUserData.getProvider())) { | ||
| provider = oidcProvider; | ||
| break; | ||
| } | ||
| } |
There was a problem hiding this comment.
| for (OidcProvider oidcProvider : Constants.OIDC_PROVIDERS) { | |
| if (oidcProvider.name.equals(oidcUserData.getProvider())) { | |
| provider = oidcProvider; | |
| break; | |
| } | |
| } | |
| provider = ServerLauncher.getOidcProvider(oicdUserDate.getProvider()); |
| AuthenticationSuccessResponse sr = parseOidcUri(requestUri); | ||
|
|
||
| OidcData data = DatabaseHelper.getOidcData(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" | ||
| ); | ||
| } | ||
|
|
||
| String redirect = data.data.split("\\|")[1]; | ||
| String session = data.data.split("\\|")[0]; | ||
|
|
||
| URI callback = new URI(Constants.PUBLIC_URL + "/oidc/" + provider.name + "/delete"); | ||
| AuthorizationCode code = sr.getAuthorizationCode(); | ||
|
|
||
| if (code == null) { | ||
| return HttpResponse.ofCode(400).withHtml( | ||
| "Your oidc provider sent an invalid code. Try again or contact your oidc admin" | ||
| ); | ||
| } | ||
|
|
||
| AuthorizationGrant codeGrant = new AuthorizationCodeGrant(code, callback, data.getOidVerifier()); | ||
|
|
||
| ClientAuthentication clientAuth = new ClientSecretBasic(provider.clientID, provider.clientSecret); | ||
|
|
||
| TokenRequest tokenRequest = new TokenRequest.Builder(provider.tokenUri, clientAuth, codeGrant).build(); | ||
| TokenResponse tokenResponse = OIDCTokenResponseParser.parse(tokenRequest.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(); | ||
|
|
||
| JWT idToken = JWTParser.parse(successResponse.getOIDCTokens().getIDTokenString()); | ||
|
|
||
| IDTokenClaimsSet claims; | ||
| try { | ||
| claims = provider.validator.validate(idToken, data.getOidNonce()); | ||
| } catch (BadJOSEException e) { | ||
| System.err.println("Invalid token received: " + e); | ||
| return HttpResponse.ofCode(400).withHtml("Received a bad token. Please try again"); | ||
| } catch (JOSEException e) { | ||
| System.err.println("Token processing error: " + e); | ||
| return HttpResponse.ofCode(500).withHtml("Internal processing error. Please try again"); | ||
| } |
There was a problem hiding this comment.
That's just a lot of duplicate code from oidcLoginCallback, it would certainly make sense to refactor the common code into a new method.
see TeamPiped/Piped#2571