Skip to content

Commit

Permalink
Merge pull request #4386 from govuk-one-login/ATO-585/add-userid-to-a…
Browse files Browse the repository at this point in the history
…uth_log_out_success-event

ATO-585: Add information to the AUTH_LOG_OUT_SUCCESS audit event
  • Loading branch information
billrdunn committed May 13, 2024
2 parents e37f41c + 3fec8b0 commit 4742ba2
Show file tree
Hide file tree
Showing 4 changed files with 244 additions and 147 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;
import uk.gov.di.orchestration.audit.TxmaAuditUser;
import uk.gov.di.orchestration.shared.entity.ClientRegistry;
import uk.gov.di.orchestration.shared.entity.Session;
import uk.gov.di.orchestration.shared.helpers.CookieHelper;
Expand All @@ -29,11 +30,13 @@

import static uk.gov.di.orchestration.shared.helpers.AuditHelper.attachTxmaAuditFieldFromHeaders;
import static uk.gov.di.orchestration.shared.helpers.InstrumentationHelper.segmentedFunctionCall;
import static uk.gov.di.orchestration.shared.helpers.IpAddressHelper.extractIpAddress;
import static uk.gov.di.orchestration.shared.helpers.LogLineHelper.LogFieldName.CLIENT_ID;
import static uk.gov.di.orchestration.shared.helpers.LogLineHelper.LogFieldName.CLIENT_SESSION_ID;
import static uk.gov.di.orchestration.shared.helpers.LogLineHelper.LogFieldName.GOVUK_SIGNIN_JOURNEY_ID;
import static uk.gov.di.orchestration.shared.helpers.LogLineHelper.attachLogFieldToLogs;
import static uk.gov.di.orchestration.shared.helpers.LogLineHelper.attachSessionIdToLogs;
import static uk.gov.di.orchestration.shared.helpers.PersistentIdHelper.extractPersistentIdFromCookieHeader;

public class LogoutHandler
implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
Expand Down Expand Up @@ -97,25 +100,31 @@ public APIGatewayProxyResponseEvent logoutRequestHandler(APIGatewayProxyRequestE
() -> sessionService.getSessionFromSessionCookie(input.getHeaders()));
attachSessionToLogsIfExists(sessionFromSessionCookie, input.getHeaders());

var subjectId = sessionFromSessionCookie.map(Session::getInternalCommonSubjectIdentifier);
var sessionId = sessionFromSessionCookie.map(Session::getSessionId);

var auditUser =
TxmaAuditUser.user()
.withIpAddress(extractIpAddress(input))
.withPersistentSessionId(
extractPersistentIdFromCookieHeader(input.getHeaders()))
.withSessionId(sessionId.orElse(null))
.withUserId(subjectId.orElse(null));

Map<String, String> queryStringParameters = input.getQueryStringParameters();
if (queryStringParameters == null || queryStringParameters.isEmpty()) {
LOG.info("Returning default logout as no input parameters");
getSessionAndDestroyIfExists(sessionFromSessionCookie);
return logoutService.generateDefaultLogoutResponse(
Optional.empty(),
input,
Optional.empty(),
getSessionAndDestroyIfExists(sessionFromSessionCookie));
Optional.empty(), auditUser, Optional.empty());
}
Optional<String> state = Optional.ofNullable(queryStringParameters.get("state"));

Optional<String> idTokenHint =
Optional.ofNullable(queryStringParameters.get("id_token_hint"));
if (idTokenHint.isEmpty()) {
return logoutService.generateDefaultLogoutResponse(
state,
input,
Optional.empty(),
getSessionAndDestroyIfExists(sessionFromSessionCookie));
getSessionAndDestroyIfExists(sessionFromSessionCookie);
return logoutService.generateDefaultLogoutResponse(state, auditUser, Optional.empty());
}

LOG.info("ID token hint is present");
Expand All @@ -129,8 +138,7 @@ public APIGatewayProxyResponseEvent logoutRequestHandler(APIGatewayProxyRequestE
Optional.empty(),
new ErrorObject(
OAuth2Error.INVALID_REQUEST_CODE, "unable to validate id_token_hint"),
input,
Optional.empty(),
auditUser,
Optional.empty());
}

Expand All @@ -143,17 +151,14 @@ public APIGatewayProxyResponseEvent logoutRequestHandler(APIGatewayProxyRequestE
return logoutService.generateErrorLogoutResponse(
Optional.empty(),
new ErrorObject(OAuth2Error.INVALID_REQUEST_CODE, "invalid id_token_hint"),
input,
Optional.empty(),
auditUser,
Optional.empty());
}

if (audience.isEmpty()) {
getSessionAndDestroyIfExists(sessionFromSessionCookie);
return logoutService.generateDefaultLogoutResponse(
Optional.empty(),
input,
Optional.empty(),
getSessionAndDestroyIfExists(sessionFromSessionCookie));
Optional.empty(), auditUser, Optional.empty());
}
final String clientID = audience.get();

Expand All @@ -162,35 +167,33 @@ public APIGatewayProxyResponseEvent logoutRequestHandler(APIGatewayProxyRequestE
Optional<ClientRegistry> clientRegistry = dynamoClientService.getClient(clientID);
if (clientRegistry.isEmpty()) {
LOG.warn("Client not found in ClientRegistry");
getSessionAndDestroyIfExists(sessionFromSessionCookie);
return logoutService.generateErrorLogoutResponse(
state,
new ErrorObject(OAuth2Error.UNAUTHORIZED_CLIENT_CODE, "client not found"),
input,
Optional.of(clientID),
getSessionAndDestroyIfExists(sessionFromSessionCookie));
auditUser,
Optional.of(clientID));
}

Optional<String> postLogoutRedirectUri =
Optional.ofNullable(queryStringParameters.get("post_logout_redirect_uri"));
if (postLogoutRedirectUri.isEmpty()) {
LOG.info(
"post_logout_redirect_uri is NOT present in logout request. Generating default logout response");
getSessionAndDestroyIfExists(sessionFromSessionCookie);
return logoutService.generateDefaultLogoutResponse(
state,
input,
Optional.of(clientID),
getSessionAndDestroyIfExists(sessionFromSessionCookie));
state, auditUser, Optional.of(clientID));
}

if (!postLogoutRedirectUriInClientReg(postLogoutRedirectUri, clientRegistry)) {
getSessionAndDestroyIfExists(sessionFromSessionCookie);
return logoutService.generateErrorLogoutResponse(
state,
new ErrorObject(
OAuth2Error.INVALID_REQUEST_CODE,
"client registry does not contain post_logout_redirect_uri"),
input,
Optional.of(clientID),
getSessionAndDestroyIfExists(sessionFromSessionCookie));
auditUser,
Optional.of(clientID));
}

if (sessionFromSessionCookie.isPresent()) {
Expand All @@ -202,7 +205,7 @@ public APIGatewayProxyResponseEvent logoutRequestHandler(APIGatewayProxyRequestE
clientID,
postLogoutRedirectUri.get(),
state,
input));
auditUser));

} else {
return segmentedFunctionCall(
Expand All @@ -212,9 +215,8 @@ public APIGatewayProxyResponseEvent logoutRequestHandler(APIGatewayProxyRequestE
URI.create(postLogoutRedirectUri.get()),
state,
Optional.empty(),
input,
Optional.of(clientID),
Optional.empty()));
auditUser,
Optional.of(clientID)));
}
}

Expand Down Expand Up @@ -267,16 +269,11 @@ private APIGatewayProxyResponseEvent logout(
String clientID,
String uri,
Optional<String> state,
APIGatewayProxyRequestEvent input) {
TxmaAuditUser auditUser) {

segmentedFunctionCall("destroySessions", () -> logoutService.destroySessions(session));
cloudwatchMetricsService.incrementLogout(Optional.of(clientID));
return logoutService.generateLogoutResponse(
URI.create(uri),
state,
Optional.empty(),
input,
Optional.of(clientID),
Optional.of(session.getSessionId()));
URI.create(uri), state, Optional.empty(), auditUser, Optional.of(clientID));
}
}

0 comments on commit 4742ba2

Please sign in to comment.