Skip to content

Commit

Permalink
Ensure each public method in the HubManager enforce authorization
Browse files Browse the repository at this point in the history
  • Loading branch information
mackdk authored and mcalmer committed Jan 21, 2025
1 parent 52dfaae commit 7899f50
Show file tree
Hide file tree
Showing 8 changed files with 521 additions and 180 deletions.
265 changes: 170 additions & 95 deletions java/code/src/com/suse/manager/hub/HubManager.java

Large diffs are not rendered by default.

35 changes: 13 additions & 22 deletions java/code/src/com/suse/manager/hub/IssSparkHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import com.suse.manager.model.hub.IssRole;
import com.suse.manager.webui.utils.gson.ResultJson;
import com.suse.manager.webui.utils.token.Token;
import com.suse.manager.webui.utils.token.TokenParser;
import com.suse.manager.webui.utils.token.TokenParsingException;

import com.google.gson.reflect.TypeToken;
Expand Down Expand Up @@ -62,21 +61,26 @@ public static Route usingTokenAuthentication(RouteWithIssToken route) {
}

String serializedToken = authorization.substring(7);
Token token = parseToken(serializedToken);
IssAccessToken issuedToken = HUB_FACTORY.lookupIssuedToken(serializedToken);

if (issuedToken == null || token == null || issuedToken.isExpired() || !issuedToken.isValid()) {
if (issuedToken == null || issuedToken.isExpired() || !issuedToken.isValid()) {
response.status(HttpServletResponse.SC_UNAUTHORIZED);
return json(response, ResultJson.error("Invalid token provided"), new TypeToken<>() { });
}

try {
Token token = issuedToken.getParsedToken();
String fqdn = token.getClaim("fqdn", String.class);
return route.handle(request, response, token, fqdn);
if (fqdn == null || !fqdn.equals(issuedToken.getServerFqdn())) {
response.status(HttpServletResponse.SC_UNAUTHORIZED);
return json(response, ResultJson.error("Invalid token provided"), new TypeToken<>() { });
}

return route.handle(request, response, issuedToken);
}
catch (TokenParsingException ex) {
response.status(HttpServletResponse.SC_BAD_REQUEST);
return json(response, ResultJson.error("Invalid token provided: missing claim"), new TypeToken<>() { });
response.status(HttpServletResponse.SC_UNAUTHORIZED);
return json(response, ResultJson.error("Invalid token provided"), new TypeToken<>() { });
}
finally {
var authenticationService = AuthenticationServiceFactory.getInstance().getAuthenticationService();
Expand Down Expand Up @@ -113,7 +117,8 @@ public static RouteWithIssToken allowingOnlyUnregistered(RouteWithIssToken route
}

private static RouteWithIssToken allowingOnly(List<IssRole> allowedRoles, RouteWithIssToken route) {
return (request, response, token, fqdn) -> {
return (request, response, issAccessToken) -> {
String fqdn = issAccessToken.getServerFqdn();
Optional<IssHub> issHub = HUB_FACTORY.lookupIssHubByFqdn(fqdn);
Optional<IssPeripheral> issPeripheral = HUB_FACTORY.lookupIssPeripheralByFqdn(fqdn);

Expand All @@ -124,7 +129,7 @@ private static RouteWithIssToken allowingOnly(List<IssRole> allowedRoles, RouteW

}

return route.handle(request, response, token, fqdn);
return route.handle(request, response, issAccessToken);
};
}

Expand All @@ -146,18 +151,4 @@ private static boolean isRouteForbidden(List<IssRole> allowedRoles, boolean isHu

return false;
}

private static Token parseToken(String serializedToken) {
try {
return new TokenParser()
.usingServerSecret()
.verifyingNotBefore()
.verifyingExpiration()
.parse(serializedToken);
}
catch (TokenParsingException ex) {
LOGGER.debug("Unable to parse token {}. Request will be rejected.", serializedToken, ex);
return null;
}
}
}
7 changes: 3 additions & 4 deletions java/code/src/com/suse/manager/hub/RouteWithIssToken.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
*/
package com.suse.manager.hub;

import com.suse.manager.webui.utils.token.Token;
import com.suse.manager.model.hub.IssAccessToken;

import spark.Request;
import spark.Response;
Expand All @@ -26,9 +26,8 @@ public interface RouteWithIssToken {
*
* @param request the request object
* @param response the response object
* @param token the token with this request
* @param serverFqdn the FQDN of the remote server
* @param token the access token granting access and identifying the caller
* @return the content to be set in the response
*/
Object handle(Request request, Response response, Token token, String serverFqdn);
Object handle(Request request, Response response, IssAccessToken token);
}
45 changes: 22 additions & 23 deletions java/code/src/com/suse/manager/hub/SyncController.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,11 @@

import com.redhat.rhn.domain.credentials.HubSCCCredentials;

import com.suse.manager.model.hub.IssHub;
import com.suse.manager.model.hub.IssPeripheral;
import com.suse.manager.model.hub.IssAccessToken;
import com.suse.manager.model.hub.IssRole;
import com.suse.manager.model.hub.RegisterJson;
import com.suse.manager.model.hub.SCCCredentialsJson;
import com.suse.manager.webui.controllers.ECMAScriptDateAdapter;
import com.suse.manager.webui.utils.token.Token;
import com.suse.manager.webui.utils.token.TokenParsingException;

import com.google.gson.Gson;
Expand Down Expand Up @@ -82,52 +80,53 @@ public void initRoutes() {
}

// Basic ping to check if the system is up
private String ping(Request request, Response response, Token token, String fqdn) {
return message(response, "Pinged from %s".formatted(fqdn));
private String ping(Request request, Response response, IssAccessToken token) {
return message(response, "Pinged from %s".formatted(token.getServerFqdn()));
}

private String register(Request request, Response response, Token token, String fqdn) {
private String register(Request request, Response response, IssAccessToken token) {
RegisterJson registerRequest = GSON.fromJson(request.body(), RegisterJson.class);

String tokenToStore = registerRequest.getToken();
if (StringUtils.isEmpty(tokenToStore)) {
LOGGER.error("No token received in the request for server {}", fqdn);
LOGGER.error("No token received in the request for server {}", token.getServerFqdn());
return badRequest(response, "Required token is missing");
}

try {
hubManager.storeAccessToken(fqdn, tokenToStore);
hubManager.saveNewServer(registerRequest.getRole(), fqdn, registerRequest.getRootCA());
hubManager.storeAccessToken(token, tokenToStore);
hubManager.saveNewServer(token, registerRequest.getRole(), registerRequest.getRootCA());

return success(response);
}
catch (TokenParsingException ex) {
LOGGER.error("Unable to parse the received token for server {}", fqdn);
LOGGER.error("Unable to parse the received token for server {}", token.getServerFqdn());
return badRequest(response, "The specified token is not parseable");
}
}

private String generateCredentials(Request request, Response response, Token token, String fqdn) {
IssPeripheral peripheral = (IssPeripheral) hubManager.findServer(IssRole.PERIPHERAL, fqdn);
if (peripheral == null) {
// This should never happen, fqdn guaranteed be a hub after calling allowingOnlyHub() on route init.
private String generateCredentials(Request request, Response response, IssAccessToken token) {
try {
HubSCCCredentials credentials = hubManager.generateSCCCredentials(token);
return success(response, new SCCCredentialsJson(credentials.getUsername(), credentials.getPassword()));
}
catch (IllegalArgumentException ex) {
// This should never happen, fqdn guaranteed be a peripheral after calling allowingOnlyPeripheral() when
// initializing the route.
return badRequest(response, "Specified FQDN is not a known peripheral");
}

HubSCCCredentials credentials = hubManager.generateSCCCredentials(peripheral);
return success(response, new SCCCredentialsJson(credentials.getUsername(), credentials.getPassword()));
}

private String storeCredentials(Request request, Response response, Token token, String fqdn) {
private String storeCredentials(Request request, Response response, IssAccessToken token) {
SCCCredentialsJson storeRequest = GSON.fromJson(request.body(), SCCCredentialsJson.class);

IssHub hub = (IssHub) hubManager.findServer(IssRole.HUB, fqdn);
if (hub == null) {
try {
hubManager.storeSCCCredentials(token, storeRequest.getUsername(), storeRequest.getPassword());
return success(response);
}
catch (IllegalArgumentException ex) {
// This should never happen, fqdn guaranteed be a hub after calling allowingOnlyHub() on route init.
return badRequest(response, "Specified FQDN is not a known hub");
}

hubManager.storeSCCCredentials(hub, storeRequest.getUsername(), storeRequest.getPassword());
return success(response);
}
}
Loading

0 comments on commit 7899f50

Please sign in to comment.