def service_account_has_external_access(service_account, google_project_id): """ Checks if service account has external access or not. Args: service_account(str): service account google_project_id(str): google project id Returns: bool: whether or not the service account has external access """ with GoogleCloudManager(google_project_id, use_default=False) as g_mgr: response = g_mgr.get_service_account_policy(service_account) if response.status_code != 200: logger.error( "Unable to get IAM policy for service account {}\n{}.".format( service_account, response.json() ) ) # if there is an exception, assume it has external access return True json_obj = response.json() # In the case that a service account does not have any role, Google API # returns a json object without bindings key if "bindings" in json_obj: policy = GooglePolicy.from_json(json_obj) if policy.roles: return True if g_mgr.get_service_account_keys_info(service_account): return True return False
def is_valid_service_account_type(project_id, account_id): """ Checks service account type against allowed service account types for service account registration Args: project_id(str): project identifier for project associated with service account account_id(str): account identifier to check valid type Returns: Bool: True if service acocunt type is allowed as defined in ALLOWED_SERVICE_ACCOUNT_TYPES """ try: with GoogleCloudManager(project_id, use_default=False) as g_mgr: return ( g_mgr.get_service_account_type(account_id) in ALLOWED_SERVICE_ACCOUNT_TYPES ) except Exception as exc: logger.error( "validity of Google service account {} (google project: {}) type " "determined False due to error. Details: {}".format( account_id, project_id, exc ) )
def create_google_logging_bucket(name, storage_class=None, google_project_id=None): cirrus_config.update(**config["CIRRUS_CFG"]) # determine project where buckets are located if not provided, default # to configured project if checking creds doesn't work storage_creds_project_id = ( google_project_id or _get_storage_project_id() or cirrus_config.GOOGLE_PROJECT_ID ) manager = GoogleCloudManager( storage_creds_project_id, creds=cirrus_config.configs["GOOGLE_STORAGE_CREDS"] ) with manager as g_mgr: g_mgr.create_or_update_bucket( name, storage_class=storage_class, public=False, requester_pays=False, for_logging=True, ) logger.info( "Successfully created Google Bucket {} " "to store Access Logs.".format(name) )
def delete(self, id_): """ Delete a service account Args: id_ (str): Google service account email to delete """ user_id = current_token["sub"] service_account_email = get_service_account_email(id_) registered_service_account = get_registered_service_account_from_email( service_account_email) if not registered_service_account: raise NotFound( "Could not find a registered service account from given email {}" .format(service_account_email)) google_project_id = registered_service_account.google_project_id # check if user has permission to delete the service account with GoogleCloudManager(google_project_id) as gcm: authorized = is_user_member_of_google_project(user_id, gcm) if not authorized: return ( 'User "{}" does not have permission to delete the provided ' 'service account "{}".'.format(user_id, id_), 403, ) return self._delete(id_)
def _setup_google_bucket_access_group( db_session, google_bucket_name, bucket_db_id, google_project_id, storage_creds_project_id, privileges, ): access_group = _create_google_bucket_access_group( db_session, google_bucket_name, bucket_db_id, google_project_id, privileges ) # use storage creds to update bucket iam storage_manager = GoogleCloudManager( storage_creds_project_id, creds=cirrus_config.configs["GOOGLE_STORAGE_CREDS"] ) with storage_manager as g_mgr: g_mgr.give_group_access_to_bucket( access_group.email, google_bucket_name, access=privileges ) logger.info( "Successfully set up Google Bucket Access Group {} " "for Google Bucket {}.".format(access_group.email, google_bucket_name) ) return access_group
def delete_expired_service_accounts(DB): """ Delete all expired service accounts. """ cirrus_config.update(**config["CIRRUS_CFG"]) driver = SQLAlchemyDriver(DB) with driver.session as session: current_time = int(time.time()) records_to_delete = ( session.query(ServiceAccountToGoogleBucketAccessGroup) .filter(ServiceAccountToGoogleBucketAccessGroup.expires < current_time) .all() ) if len(records_to_delete): with GoogleCloudManager() as manager: for record in records_to_delete: try: manager.remove_member_from_group( record.service_account.email, record.access_group.email ) session.delete(record) logger.info( "Removed expired service account: {}".format( record.service_account.email ) ) except Exception as e: logger.error( "ERROR: Could not delete service account {}. Details: {}".format( record.service_account.email, e ) ) session.commit()
def _remove_client_service_accounts(db_session, client): client_service_accounts = ( db_session.query(GoogleServiceAccount) .filter(GoogleServiceAccount.client_id == client.client_id) .all() ) if client_service_accounts: with GoogleCloudManager() as g_mgr: for service_account in client_service_accounts: logger.info( "Deleting client {}'s service account: {}".format( client.name, service_account.email ) ) response = g_mgr.delete_service_account(service_account.email) if not response.get("error"): db_session.delete(service_account) db_session.commit() else: logger.error("ERROR - from Google: {}".format(response)) logger.error( "ERROR - Could not delete client service account: {}".format( service_account.email ) )
def _verify_google_group_member(session, access_group, member): """ Delete if the member which is a google group is not in Fence. Args: session(Session): db session access_group(GoogleBucketAccessGroup): access group member(dict): group member info Returns: None """ account_emails = [ granted_group.proxy_group.email for granted_group in ( session.query(GoogleProxyGroupToGoogleBucketAccessGroup).filter_by( access_group_id=access_group.id).all()) ] if not any( [email for email in account_emails if email == member.get("email")]): try: with GoogleCloudManager() as manager: manager.remove_member_from_group(member.get("email"), access_group.email) except Exception as e: print( "ERROR: Could not remove google group memeber {} from access group {}. Detail {}" .format(member.get("email"), access_group.email, e))
def add_bucket_acl(self, bucket, username, access=None): """ Tries to grant a user access to a bucket Args: bucket (str): Google Bucket Access Group email address. This should be the address of a Google Group that has read access on a single bucket. Access is controlled by adding members to this group. username (str): An email address of a member to add to the Google Bucket Access Group. access (str): IGNORED. For Google buckets, the Google Bucket Access Group is given access to the bucket through Google's IAM, so you cannot selectively choose permissions. Once you're added, you have the access that was set up for that group in Google IAM. """ response = None with GoogleCloudManager(project_id=self.google_project_id) as g_mgr: try: response = g_mgr.add_member_to_group( member_email=username, group_id=bucket ) except Exception as exc: raise RequestError("Google API Error: {}".format(exc), code=400) return response
def _get_user_email_list_from_google_project_with_owner_role(project_id): """ Get a list of emails associated to google project id Args: project_id(str): project id Returns: list(str): list of emails belong to the project """ with GoogleCloudManager(project_id, use_default=False) as prj: members = prj.get_project_membership(project_id) users = [ member for member in members if member.member_type == GooglePolicyMember.USER ] return list( { u.email_id for u in users for role in u.roles if role.name.upper() == "OWNER" } )
def is_user_member_of_all_google_projects(user_id, google_project_ids, db=None, membership=None): """ Return whether or not the given user is a member of ALL of the provided Google project IDs. This will verify that either the user's email or their linked Google account email exists as a member in the projects. Args: user_id (int): User identifier google_project_ids (List(str)): List of unique google project ids db(str): db connection string membership (List(GooglePolicyMember) : pre-calculated list of members, Will make call to Google API if membership is None Returns: bool: whether or not the given user is a member of ALL of the provided Google project IDs """ is_member = False for google_project_id in google_project_ids: with GoogleCloudManager(google_project_id) as google_cloud_manager: is_member = is_user_member_of_google_project( user_id, google_cloud_manager, db, membership) if not is_member: return False return is_member
def _create_proxy_group(user_id, username): """ Create a proxy group for the given user Args: user_id (int): unique integer id for user username (str): unique name for user Return: userdatamodel.user.GoogleProxyGroup: the newly created proxy group """ with GoogleCloudManager() as g_cloud: prefix = get_prefix_for_google_proxy_groups() new_proxy_group = g_cloud.create_proxy_group_for_user(user_id, username, prefix=prefix) proxy_group = GoogleProxyGroup(id=new_proxy_group["id"], email=new_proxy_group["email"]) # link proxy group to user user = current_session.query(User).filter_by(id=user_id).first() user.google_proxy_group_id = proxy_group.id current_session.add(proxy_group) current_session.commit() logger.info("Created proxy group {} for user {} with id {}.".format( new_proxy_group["email"], username, user_id)) return proxy_group
def _verify_google_service_account_member(session, access_group, member): """ Delete if the member which is a service account is not in Fence. Args: session(session): db session access_group(GoogleBucketAccessGroup): access group members(dict): service account member info Returns: None """ account_emails = [ account.service_account.email for account in ( session.query(ServiceAccountToGoogleBucketAccessGroup).filter_by( access_group_id=access_group.id).all()) ] if not any( [email for email in account_emails if email == member.get("email")]): try: with GoogleCloudManager() as manager: manager.remove_member_from_group(member.get("email"), access_group.email) print("Removed {} from {}, not found in fence but found " "in Google Group.".format(member.get("email"), access_group.email)) except Exception as e: print( "ERROR: Could not remove service account memeber {} from access group {}. Detail {}" .format(member.get("email"), access_group.email, e))
def _create_google_bucket_access_group( db_session, google_bucket_name, bucket_db_id, google_project_id, privileges ): access_group = None prefix = config.get("GOOGLE_GROUP_PREFIX", "") # use default creds for creating group and iam policies with GoogleCloudManager(google_project_id) as g_mgr: # create bucket access group result = g_mgr.create_group( name=prefix + "_" + google_bucket_name + "_" + "_".join(privileges) + "_gbag" ) group_email = result["email"] # add bucket group to db access_group = ( db_session.query(GoogleBucketAccessGroup) .filter_by(bucket_id=bucket_db_id, email=group_email) .first() ) if not access_group: access_group = GoogleBucketAccessGroup( bucket_id=bucket_db_id, email=group_email, privileges=privileges ) db_session.add(access_group) db_session.commit() return access_group
def is_user_member_of_all_google_projects( user_id, google_project_ids, db=None, membership=None ): """ Return whether or not the given user is a member of ALL of the provided Google project IDs. This will verify that either the user's email or their linked Google account email exists as a member in the projects. Args: user_id (int): User identifier google_project_ids (List(str)): List of unique google project ids db(str): db connection string membership (List(GooglePolicyMember) : pre-calculated list of members, Will make call to Google API if membership is None Returns: bool: whether or not the given user is a member of ALL of the provided Google project IDs """ session = get_db_session(db) user = session.query(User).filter_by(id=user_id).first() if not user: logger.error( "Could not determine if user (id: {}) is from projects:" " {} due to error. User does not exist...".format( user_id, google_project_ids ) ) return False linked_google_account = ( session.query(UserGoogleAccount) .filter(UserGoogleAccount.user_id == user_id) .first() ) try: for google_project_id in google_project_ids: with GoogleCloudManager(google_project_id, use_default=False) as g_mgr: members = membership or g_mgr.get_project_membership() member_emails = [member.email_id.lower() for member in members] # first check if user.email is in project, then linked account if not (user.email and user.email in member_emails): if not ( linked_google_account and linked_google_account.email in member_emails ): # no user email is in project return False except Exception as exc: logger.error( "Could not determine if user (id: {}) is from projects:" " {} due to error. Details: {}".format(user_id, google_project_ids, exc) ) return False return True
def _unlink_google_account(): user_id = current_token["sub"] g_account = ( current_session.query(UserGoogleAccount) .filter(UserGoogleAccount.user_id == user_id) .first() ) if not g_account: error_message = { "error": "g_acnt_link_error", "error_description": ( "Couldn't unlink account for user, no linked Google " "account found." ), } _clear_google_link_info_from_session() return error_message, 404 g_account_access = ( current_session.query(UserGoogleAccountToProxyGroup) .filter( UserGoogleAccountToProxyGroup.user_google_account_id == g_account.id ) .first() ) if g_account_access: try: with GoogleCloudManager() as g_manager: g_manager.remove_member_from_group( member_email=g_account.email, group_id=g_account_access.proxy_group_id, ) except Exception as exc: error_message = { "error": "g_acnt_access_error", "error_description": ( "Couldn't remove account from user's proxy group, " "Google API failure. Exception: {}".format(exc) ), } _clear_google_link_info_from_session() return error_message, 400 current_session.delete(g_account_access) current_session.commit() current_session.delete(g_account) current_session.commit() # clear session and cookies so access token and session don't have # outdated linkage info flask.session.clear() response = flask.make_response("", 200) clear_cookies(response) return response
def get_test_cloud_manager(): project_id = "test_project" manager = GoogleCloudManager(project_id) manager._authed_session = MagicMock() manager._admin_service = MagicMock() manager._storage_client = MagicMock() manager.credentials = MagicMock() return manager
def email_users_without_access( db, auth_ids, user_emails, check_linking, google_project_id ): """ Build list of users without acess and send emails. Args: db (str): database instance auth_ids (list(str)): list of project auth_ids to check access against user_emails (list(str)): list of emails to check access for check_linking (bool): flag to check for linked google email Returns: None """ users_without_access = _get_users_without_access( db, auth_ids, user_emails, check_linking ) if len(users_without_access) == len(user_emails): logger.warning( "No user has proper access to provided projects. Contact project administrator. No emails will be sent" ) return elif len(users_without_access) > 0: logger.info( "Some user(s) do not have proper access to provided projects. Email(s) will be sent to user(s)." ) with GoogleCloudManager(google_project_id) as gcm: members = gcm.get_project_membership(google_project_id) users = [] for member in members: if member.member_type == GooglePolicyMember.USER: users.append(member.email_id) for user, projects in users_without_access.iteritems(): logger.info( "{} does not have access to the following datasets: {}.".format( user, ",".join(projects) ) ) if user in users: logger.info( "{} is a member of google project: {}. User will be emailed.".format( user, google_project_id ) ) email_user_without_access(user, projects, google_project_id) else: logger.info( "{} is NOT a member of google project: {}. User will NOT be emailed.".format( user, google_project_id ) ) else: logger.info("All users have proper access to provided projects.")
def delete_keypair(provider, access_key): """ .. http:get: /<provider>/(string: access_key) Delete a keypair for user :param access_key: existing access key belongs to this user For Google: The access_key can be constructed from data in the response from creating the key. access_key should be a string: `projects/{PROJECT_ID}/serviceAccounts/{ACCOUNT}/keys/{KEY}` which can be constructed with the information from POST/PUT `credentials/google` Use `project_id` for {PROJECT_ID}, `client_email` for {ACCOUNT}, `private_key_id` for {KEY} :statuscode 201 Success :statuscode 403 Forbidden to delete access key :statuscode 404 Access key doesn't exist """ if provider == 'cdis': jti = access_key with flask.current_app.db.session as session: api_key = ( session .query(UserRefreshToken) .filter_by(jti=jti) .first() ) if not api_key: flask.abort(400, 'token not found with JTI {}'.format(jti)) blacklist_token(jti, api_key.expires) elif provider == 'google': with GoogleCloudManager() as g_cloud: service_account = _get_google_service_account_for_client(g_cloud) if service_account: keys_for_account = ( g_cloud.get_service_account_keys_info(service_account.google_unique_id) ) # Only delete the requested key if is owned by current client's SA if access_key in [key['name'].split('/')[-1] for key in keys_for_account]: g_cloud.delete_service_account_key(service_account.google_unique_id, access_key) else: flask.abort(400, 'Could not delete key ' + access_key + '. Not found for current user.') else: flask.abort(400, 'Could not find service account for current user.') else: flask.current_app.storage_manager.delete_keypair(provider, flask.g.user, access_key) return '', 204
def remove_expired_google_service_account_keys(db): import fence.settings cirrus_config.update(**fence.settings.CIRRUS_CFG) db = SQLAlchemyDriver(db) with db.session as current_session: client_service_accounts = current_session.query( GoogleServiceAccount, Client).filter(GoogleServiceAccount.client_id == Client.client_id) current_time = int(time.time()) print("Current time: {}\n".format(current_time)) expired_sa_keys_for_users = current_session.query( GoogleServiceAccountKey).filter( GoogleServiceAccountKey.expires <= current_time) # handle service accounts with default max expiration for service_account, client in client_service_accounts: with GoogleCloudManager() as g_mgr: g_mgr.handle_expired_service_account_keys( service_account.google_unique_id) # handle service accounts with custom expiration for expired_user_key in expired_sa_keys_for_users: sa = (current_session.query(GoogleServiceAccount).filter( GoogleServiceAccount.id == expired_user_key.service_account_id).first()) response = g_mgr.delete_service_account_key( account=sa.google_unique_id, key_name=expired_user_key.key_id) response_error_code = response.get("error", {}).get("code") if not response_error_code: current_session.delete(expired_user_key) print( "INFO: Removed expired service account key {} " "for service account {} (owned by user with id {}).\n". format(expired_user_key.key_id, sa.email, sa.user_id)) elif response_error_code == 404: print( "INFO: Service account key {} for service account {} " "(owned by user with id {}) does not exist in Google. " "Removing from database...\n".format( expired_user_key.key_id, sa.email, sa.user_id)) current_session.delete(expired_user_key) else: print("ERROR: Google returned an error when attempting to " "remove service account key {} " "for service account {} (owned by user with id {}). " "Error:\n{}\n".format(expired_user_key.key_id, sa.email, sa.user_id, response))
def _is_valid_service_account(sa_email, google_project_id): """ Validate the given registered service account and remove if invalid. Args: sa_email(str): service account email google_project_id(str): google project id """ with GoogleCloudManager(google_project_id) as gcm: google_project_number = get_google_project_number(google_project_id, gcm) has_access = bool(google_project_number) if not has_access: # if our monitor doesn't have access at this point, just don't return any # information. When the project check runs, it will catch the monitor missing # error and add it to the removal reasons raise Unauthorized( "Google Monitoring SA doesn't have access to Google Project: {}".format( google_project_id ) ) try: sa_validity = GoogleServiceAccountValidity( sa_email, google_project_id, google_project_number=google_project_number ) if is_google_managed_service_account(sa_email): sa_validity.check_validity( early_return=True, check_type=True, check_policy_accessible=True, check_external_access=False, ) else: sa_validity.check_validity( early_return=True, check_type=True, check_policy_accessible=True, check_external_access=True, ) except Exception as exc: # any issues, assume invalid # TODO not sure if this is the right way to handle this... logger.warning( "Service Account {} determined invalid due to unhandled exception: {}. " "Assuming service account is invalid.".format(sa_email, str(exc)) ) traceback.print_exc() sa_validity = None return sa_validity
def remove_expired_google_accounts_from_proxy_groups(db): cirrus_config.update(**config["CIRRUS_CFG"]) db = SQLAlchemyDriver(db) with db.session as current_session: current_time = int(time.time()) logger.info("Current time: {}".format(current_time)) expired_accounts = current_session.query(UserGoogleAccountToProxyGroup).filter( UserGoogleAccountToProxyGroup.expires <= current_time ) with GoogleCloudManager() as g_mgr: for expired_account_access in expired_accounts: g_account = ( current_session.query(UserGoogleAccount) .filter( UserGoogleAccount.id == expired_account_access.user_google_account_id ) .first() ) try: response = g_mgr.remove_member_from_group( member_email=g_account.email, group_id=expired_account_access.proxy_group_id, ) response_error_code = response.get("error", {}).get("code") if not response_error_code: current_session.delete(expired_account_access) logger.info( "INFO: Removed {} from proxy group with id {}.\n".format( g_account.email, expired_account_access.proxy_group_id ) ) else: logger.error( "ERROR: Google returned an error when attempting to " "remove member {} from proxy group {}. Error:\n{}\n".format( g_account.email, expired_account_access.proxy_group_id, response, ) ) except Exception as exc: logger.error( "ERROR: Google returned an error when attempting to " "remove member {} from proxy group {}. Error:\n{}\n".format( g_account.email, expired_account_access.proxy_group_id, exc ) )
def delete(self, bucket, file_id): try: with GoogleCloudManager(creds='a') as gcm: gcm.delete_data_file(bucket, file_id) return ("", 204) except Exception as e: logger.error(e) try: status_code = e.resp.status except Exception as exc: logger.error(exc) status_code = 500 return ("Failed to delete data file.", status_code)
def add_user_service_account_to_google( session, to_add_project_ids, google_project_id, service_account ): """ Add service account to Google access groups Args: session(current_session): db session to_add_project_ids (List(id)): list of project ids google_project_id (str): google project id service_account (UserServiceAccount): user service account """ logger.debug( "attempting to add {} to groups for projects: {}".format( service_account, to_add_project_ids ) ) for project_id in to_add_project_ids: access_groups = _get_google_access_groups(session, project_id) logger.debug( "google group(s) for project {}: {}".format(project_id, access_groups) ) for access_group in access_groups: try: # TODO: Need to remove try/catch after major refactor with GoogleCloudManager( google_project_id, use_default=False ) as g_manager: response = g_manager.add_member_to_group( member_email=service_account.email, group_id=access_group.email ) if response.get("email", None): logger.debug( "Successfully add member {} to Google group {}.".format( service_account.email, access_group.email ) ) else: raise GoogleAPIError( "Can not add {} to Google group {}".format( service_account.email, access_group.email ) ) except Exception as exc: raise GoogleAPIError( "Can not add {} to Google group {}. Detail {}".format( service_account.email, access_group.email, exc ) )
def delete(self, bucket, file_id): try: with GoogleCloudManager( creds=config["CIRRUS_CFG"]["GOOGLE_STORAGE_CREDS"]) as gcm: gcm.delete_data_file(bucket, file_id) return ("", 204) except Exception as e: logger.error(e) try: status_code = e.resp.status except Exception as exc: logger.error(exc) status_code = 500 return ("Failed to delete data file.", status_code)
def create_google_access_key(client_id, user_id, username, proxy_group_id): """ Return an access key for current user and client. NOTE: This will create a service account for the client if one does not exist. Returns: JSON key in Google Credentials File format: .. code-block:: JavaScript { "type": "service_account", "project_id": "project-id", "private_key_id": "some_number", "private_key": "-----BEGIN PRIVATE KEY-----\n.... =\n-----END PRIVATE KEY-----\n", "client_email": "<api-name>[email protected]", "client_id": "...", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://accounts.google.com/o/oauth2/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "https://www.googleapis.com/...<api-name>api%40project-id.iam.gserviceaccount.com" } """ key = {} service_account = get_or_create_service_account( client_id=client_id, user_id=user_id, username=username, proxy_group_id=proxy_group_id, ) with GoogleCloudManager() as g_cloud: key = g_cloud.get_access_key(service_account.email) logger.info( "Created key with id {} for service account {} in user {}'s " "proxy group {} (user's id: {}).".format( key.get("private_key_id"), service_account.email, username, proxy_group_id, user_id, ) ) return key, service_account
def get_google_project_membership(project_id): """ Returns GCM get_project_membership() result, which is a list of all members on the projects IAM Args: project_id(str): unique id for project Returns List(GooglePolicyMember): list of members on project's IAM """ with GoogleCloudManager(project_id, use_default=False) as prj: return prj.get_project_membership(project_id)
def get(self): """ List access keys for user **Example:** .. code-block:: http POST /credentials/apis/ HTTP/1.1 Content-Type: application/json Accept: application/json Info from Google API /serviceAccounts/<account>/keys endpoint TODO: In the future we should probably add in our expiration time, when we start monitoring and deleting after x amount of time .. code-block:: JavaScript { "access_keys": [ { "keyAlgorithm": enum(ServiceAccountKeyAlgorithm), "validBeforeTime": string, "name": string, "validAfterTime": string, }, ... ] } """ client_id = current_token.get("azp") or None user_id = current_token["sub"] username = current_token.get("context", {}).get("user", {}).get("name") with GoogleCloudManager() as g_cloud_manager: proxy_group_id = get_or_create_proxy_group_id() service_account = get_or_create_service_account( client_id=client_id, user_id=user_id, username=username, proxy_group_id=proxy_group_id, ) keys = g_cloud_manager.get_service_account_keys_info( service_account.google_unique_id) result = {"access_keys": keys} return flask.jsonify(result)
def get_google_project_valid_users_and_service_accounts(project_id, membership=None): """ Gets google project members of type USER or SERVICE_ACCOUNT and raises an error if it finds a member that isn't one of those types. Args: project_id (str): Google project ID membership (List(GooglePolicyMember): pre-calculated list of members, Will make call to Google API if membership is None Return: List[cirrus.google_cloud.iam.GooglePolicyMember]: Members on the google project Raises: NotSupported: Member is invalid type """ try: with GoogleCloudManager(project_id, use_default=False) as prj: members = membership or prj.get_project_membership(project_id) for member in members: if not ( member.member_type == GooglePolicyMember.SERVICE_ACCOUNT or member.member_type == GooglePolicyMember.USER ): raise NotSupported( "Member {} has invalid type: {}".format( member.email_id, member.member_type ) ) users = [ member for member in members if member.member_type == GooglePolicyMember.USER ] service_accounts = [ member for member in members if member.member_type == GooglePolicyMember.SERVICE_ACCOUNT ] return users, service_accounts except Exception as exc: logger.error( "validity of Google Project (id: {}) members " "could not complete. Details: {}".format(project_id, exc) ) raise
def delete(self): """ .. http:get: /google/ Delete keypair(s) for user ?all=true must be specified True values are y, yes, t, true, on and 1; false values are n, no, f, false, off and 0 :statuscode 204 Success :statuscode 403 Forbidden to delete access key :statuscode 405 Method Not Allowed if ?all=true is not included """ user_id = current_token["sub"] try: all_arg = strtobool(flask.request.args.get("all", "false").lower()) except ValueError: all_arg = False if not all_arg: flask.abort( 405, "Please include ?all=true to confirm deletion of ALL Google Service account keys.", ) with GoogleCloudManager() as g_cloud: client_id = current_token.get("azp") or None service_account = get_service_account(client_id, user_id) if service_account: keys_for_account = g_cloud.get_service_account_keys_info( service_account.email) # Only delete the key if is owned by current client's SA all_client_keys = [ key["name"].split("/")[-1] for key in keys_for_account ] for key in all_client_keys: _delete_service_account_key(g_cloud, service_account.email, key) else: flask.abort( 404, "Could not find service account for current user.") return "", 204