def _upsert_userinfo(self, sess, user_info): """ update user info to database. Args: sess: sqlalchemy session user_info: a dict of {username: {display_name, phone_number, tags, admin} Return: None """ for username in user_info: u = query_for_user(session=sess, username=username) if u is None: self.logger.info("create user {}".format(username)) u = User(username=username) sess.add(u) if self.arborist_client: self.arborist_client.create_user({"name": username}) u.email = user_info[username].get("email", "") u.display_name = user_info[username].get("display_name", "") u.phone_number = user_info[username].get("phone_number", "") u.is_admin = user_info[username].get("admin", False) # do not update if there is no tag if user_info[username]["tags"] == {}: continue # remove user db tags if they are not shown in new tags for tag in u.tags: if tag.key not in user_info[username]["tags"]: u.tags.remove(tag) # sync for k, v in user_info[username]["tags"].items(): found = False for tag in u.tags: if tag.key == k: found = True tag.value = v # create new tag if not found if not found: tag = Tag(key=k, value=v) u.tags.append(tag)
def create_providers(data, db_session): s = db_session providers = data["providers"] for provider in providers: prov = CloudProvider() prov.name = provider["name"] prov.backend = provider["backend"] prov.service = provider["service"] s.add(prov) s.flush for name, user in list(data["users"].items()): new_user = User() new_user.username = name new_user.email = user["email"] new_user.is_admin = user["is_admin"] s.add(new_user) user["id"] = new_user.id for project in data["projects"]: new_project = Project() new_project.name = project["name"] s.add(new_project) for storage in project["storage_access"]: provider = s.query(CloudProvider).filter_by(name=storage).first() if provider: new_storage_access = StorageAccess(provider_id=provider.id, project_id=new_project.id) s.add(new_storage_access) for bucket in project["buckets"]: new_bucket = Bucket() new_bucket.name = bucket["name"] provider = s.query(CloudProvider).filter_by( name=bucket["provider"]).first() new_bucket.provider_id = provider.id s.add(new_bucket) s.flush() project_to_bucket = ProjectToBucket() project_to_bucket.bucket_id = new_bucket.id project_to_bucket.project_id = new_project.id s.add(project_to_bucket) s.flush() for user in project["users"]: access = AccessPrivilege() access.user_id = data["users"][user["name"]]["id"] access.project_id = new_project.id s.add(access)
def _grant_from_db(self, s, userinfo, to_add, auth_provider): ''' Grant user access to projects in the auth database Args: s: sqlalchemy session to_add: a set of (username, project.auth_id) to be granted Return: None ''' for (username, project_auth_id) in to_add: u = s.query(User).filter(User.username == username).first() if not u: self.logger.info('create user {}'.format(username)) u = User(username=username) u.email = userinfo[username]['email'] s.add(u) self.logger.info('grant {} access to {} in db'.format( username, project_auth_id)) user_access = AccessPrivilege( user=u, project=self._projects[project_auth_id], privilege=['read-storage'], auth_provider=auth_provider) s.add(user_access)
def login_user(username, provider, fence_idp=None, shib_idp=None, email=None, id_from_idp=None): """ Login a user with the given username and provider. Set values in Flask session to indicate the user being logged in. In addition, commit the user and associated idp information to the db. Args: username (str): specific username of user to be logged in provider (str): specfic idp of user to be logged in fence_idp (str, optional): Downstreawm fence IdP shib_idp (str, optional): Downstreawm shibboleth IdP email (str, optional): email of user (may or may not match username depending on the IdP) id_from_idp (str, optional): id from the IDP (which may be different than the username) """ def set_flask_session_values(user): """ Helper fuction to set user values in the session. Args: user (User): User object """ flask.session["username"] = user.username flask.session["user_id"] = str(user.id) flask.session["provider"] = user.identity_provider.name if fence_idp: flask.session["fence_idp"] = fence_idp if shib_idp: flask.session["shib_idp"] = shib_idp flask.g.user = user flask.g.scopes = ["_all"] flask.g.token = None user = query_for_user(session=current_session, username=username) if user: _update_users_email(user, email) _update_users_id_from_idp(user, id_from_idp) # This expression is relevant to those users who already have user and # idp info persisted to the database. We return early to avoid # unnecessarily re-saving that user and idp info. if user.identity_provider and user.identity_provider.name == provider: set_flask_session_values(user) return else: # we need a new user user = User(username=username) if email: user.email = email if id_from_idp: user.id_from_idp = id_from_idp # TODO: update iss_sub mapping table? # setup idp connection for new user (or existing user w/o it setup) idp = (current_session.query(IdentityProvider).filter( IdentityProvider.name == provider).first()) if not idp: idp = IdentityProvider(name=provider) user.identity_provider = idp current_session.add(user) current_session.commit() set_flask_session_values(user)