Search code examples
pythongoogle-oauth

How to get all Google groups for signed in user using google_auth_oauthlib flow?


I am using Google Sign-in to authenticate/authorize users to access my Flask web application. This part is working fine.

I need to organize users based on group they belong. Using admin on google I've created group and only users from that group can use application.

Problem is that it only works for me. Probably because I am admin/domain owner.

Everyone else gets error when fetching token.

I am using google_auth_oauthlib.flow.

Scopes I use are:

"https://www.googleapis.com/auth/userinfo.profile",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/admin.directory.group.readonly",
"openid"

When someone outside that group tries to access, log shows next error.

When getting token: (invalid_grant) Bad Request
Traceback (most recent call last):
  File "/tmp/tmpfhwmhvrg/__main__/licsrv/admin/admin.py", line 150, in view_cb_google
    f.fetch_token(authorization_response=authorization_response)
  File "/tmp/tmpfhwmhvrg/pip36/google_auth_oauthlib/google_auth_oauthlib/flow.py", line 241, in fetch_token
    self.client_config['token_uri'], **kwargs)
  File "/tmp/tmpfhwmhvrg/pip36/requests_oauthlib/requests_oauthlib/oauth2_session.py", line 244, in fetch_token
    self._client.parse_request_body_response(r.text, scope=self.scope)
  File "/tmp/tmpfhwmhvrg/pip36/oauthlib/oauthlib/oauth2/rfc6749/clients/base.py", line 411, in parse_request_body_response
    self.token = parse_token_response(body, scope=scope)
  File "/tmp/tmpfhwmhvrg/pip36/oauthlib/oauthlib/oauth2/rfc6749/parameters.py", line 379, in parse_token_response
    validate_token_parameters(params)
  File "/tmp/tmpfhwmhvrg/pip36/oauthlib/oauthlib/oauth2/rfc6749/parameters.py", line 386, in validate_token_parameters
    raise_from_error(params.get('error'), params)
  File "/tmp/tmpfhwmhvrg/pip36/oauthlib/oauthlib/oauth2/rfc6749/errors.py", line 415, in raise_from_error
    raise cls(**kwargs)
oauthlib.oauth2.rfc6749.errors.InvalidGrantError: (invalid_grant) Bad Request


Solution

  • Permission https://www.googleapis.com/auth/admin.directory.group.readonly is not available for non-admin users.

    Solution was to write apps script that will be executed with accessing user context and check if user is in group or have any permission within group.

    Permission above was replaced with https://www.googleapis.com/auth/groups permission and that was enough to execute apps script.

    Apps script example is below, and it is only part of script used in project.

    function authorizeUser(userEmail) {
      var group = GroupsApp.getGroupByEmail("%PUT YOUR GROUP EMAIL HERE%");
      var inGroup = false;
      var users = group.getUsers();
      for (var i = 0; i < users.length; i++) {
        var user = users[i];
        inGroup = user.getEmail() == userEmail;
        if (inGroup) {
          break;
        }
      }
      Logger.log("inGroup: " + inGroup);
      return inGroup;
    }
    

    NOTE

    It important to link scripts project with Google dev project before creating new script and functions, otherwise it might not be able to execute script function as unavailable.