Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support more than one google group for auth #652

Merged
merged 6 commits into from
Dec 9, 2024
Merged

Support more than one google group for auth #652

merged 6 commits into from
Dec 9, 2024

Conversation

tomrf1
Copy link
Member

@tomrf1 tomrf1 commented Dec 4, 2024

We want to allow other groups (24/7 Support, Central Production) to access the RRCP. This is not currently possible - users have to be in the support.admin.console google group.

Before the change:

The server fetches a list of google groups from config. When logging in, a user must be a member of all the configured groups. This list includes a special group for enforcing 2fa, since users must also be in this group.

After the change:

When making any authorised request, a user must be in at least one of the configured groups.
Additionally, we also still need to check that the user is in the special 2fa group. So I have moved this into a separate config item, so that we can check membership of this group separately from the other list of groups.

The change

Previously the group checking was done in Login.scala at the point that a user logs in, with the line:
processOauth2Callback(requiredGoogleGroups, googleGroupChecker)
The google auth library would then use the googleGroupChecker to do the check - but this method requires a user to be in all groups, which is not what we want.

Instead, we now do the group checking as part of the authAction, which is created in AppComponents.scala. This method of group checking only requires one group to match.

It's a bit confusing that the play google-auth library behaves in two different ways like this. But I can see examples of both methods in our repos.

Testing

Deployed to CODE, and temporarily removed a user from the support.admin.console google group to confirm their access was lost.

@@ -15,9 +15,9 @@ import services.{Athena, Aws, CapiService, DynamoArchivedBannerDesigns, DynamoAr
import software.amazon.awssdk.services.dynamodb.DynamoDbClient
import software.amazon.awssdk.services.s3.model.GetObjectRequest

class AppComponents(context: Context, stage: String) extends BuiltInComponentsFromContext(context) with AhcWSComponents with NoHttpFiltersComponents with AssetsComponents {
class AppComponents(context: Context, stage: String) extends BuiltInComponentsFromContext(context) with AhcWSComponents with NoHttpFiltersComponents with AssetsComponents with Filters {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adding the Filters trait here gives us access to the requireGroup method

@@ -50,7 +50,9 @@ class AppComponents(context: Context, stage: String) extends BuiltInComponentsFr

private val requiredGoogleGroups: Set[String] = configuration.get[String]("googleAuth.requiredGroups").split(',').toSet

private val authAction = new AuthAction[AnyContent](authConfig, controllers.routes.Login.loginAction, controllerComponents.parsers.default)(executionContext)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here we adapt authAction to also do the group checking

@@ -34,7 +33,7 @@ class Login(
* Looks up user's identity via Google
*/
def oauth2Callback: Action[AnyContent] = Action.async { implicit request =>
processOauth2Callback(requiredGoogleGroups, googleGroupChecker)
processOauth2Callback()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this means we no longer check group membership during the initial google auth step, and we instead do it on every request

@tomrf1 tomrf1 marked this pull request as ready for review December 6, 2024 10:06
@tomrf1 tomrf1 requested a review from a team as a code owner December 6, 2024 10:06
Copy link
Member

@rupertbates rupertbates left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks reasonable to me 👍

@tomrf1 tomrf1 merged commit c19d84f into main Dec 9, 2024
3 checks passed
@tomrf1 tomrf1 deleted the tf-groups branch December 9, 2024 09:11
@@ -48,9 +48,15 @@ class AppComponents(context: Context, stage: String) extends BuiltInComponentsFr
)
}

private val twoFactorAuthEnforceGoogleGroup = configuration.get[String]("googleAuth.2faEnforceGroup")
private val requiredGoogleGroups: Set[String] = configuration.get[String]("googleAuth.requiredGroups").split(',').toSet
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably should have renamed this to allowedGroups as they are not all required any more

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a very good point - it would make it a lot clearer. I'm going to do this in a follow up PR

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed here #655

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants