def createNode(self, model, attributes={}): """ Generic create of a graph node based on the give model and applying the given attributes """ node = model() uuid = getUUID() if hasattr(node, 'id'): setattr(node, 'id', uuid) if hasattr(node, 'uuid'): setattr(node, 'uuid', uuid) if hasattr(node, 'created'): setattr(node, 'created', datetime.now(pytz.utc)) if hasattr(node, 'modified'): setattr(node, 'modified', datetime.now(pytz.utc)) for key in attributes: setattr(node, key, attributes[key]) node.save() return node
def init_users_and_roles(self): # Handle system roles current_roles = [] current_roles_objs = self._graph.Role.nodes.all() for role in current_roles_objs: current_roles.append(role.name) for role in self.DEFAULT_ROLES: if role not in current_roles: self.create_role(role) from flask import current_app if current_app.config['TESTING']: # Create some users for testing pass # Default user (if no users yet available) if not len(self._graph.User.nodes) > 0: logger.warning("No users inside graphdb. Injecting default.") self.create_user({ 'uuid': getUUID(), 'email': self.DEFAULT_USER, 'authmethod': 'credentials', 'name': 'Default', 'surname': 'User', 'password': self.hash_password(self.DEFAULT_PASSWORD) }, roles=self.DEFAULT_ROLES)
def get(self, mid=None): """ This is just an example of what an endpoint can do with the graph """ if mid is not None: raise NotImplementedError("To do") ########################### # Get the service object graph = self.global_get_service('neo4j') ########################### # Models can be found inside the graphdb object # create a node myjson = {'test': 1, 'another': 99} node = graph.MetaData(content=myjson) # save it inside the graphdb node.save() # create a second node myid = getUUID() mylocation = 'irods:///%s' % myid datanode = graph.DigitalEntity(id=myid, location=mylocation) datanode.save() # connect the two nodes datanode.described.connect(node) print(node, datanode) return "Hello world"
def invalidate_all_tokens(self, user=None): """ To invalidate all tokens the user uuid is changed """ if user is None: user = self._user user.uuid = getUUID() self._db.session.add(user) self._db.session.commit() logger.warning("User uuid changed to: %s" % user.uuid) return True
def post(self): """ Register a UUID """ # Create graph object graph = self.global_get_service('neo4j') icom = self.global_get_service('irods') ####################### ####################### # // TO FIX: request a 'user' parameter # User myuser = None userobj = self.get_current_user() irodsusers = userobj.associated.search(default_user=True) if len(irodsusers) < 1: # associate with guest user? class myuser(object): username = icom.get_default_user() else: myuser = irodsusers.pop() myuserobj = None try: myuserobj = graph.IrodsUser.nodes.get(username=myuser.username) except graph.IrodsUser.DoesNotExist: return self.force_response(errors={ 'iRODS user': '******'}) ####################### ####################### ####################### # Create UUID myid = getUUID() # // TO FIX: request a 'location' parameter mylocation = 'noprotocol:///%s/%s/TOBEDEFINED' % (myuser, myid) dobj = graph.DataObject(id=myid, location=mylocation) dobj.save() ####################### # Link the obj dobj.owned.connect(myuserobj) ####################### # Return the UUID return dobj.id
def store_oauth2_user(self, current_user, token): """ Allow external accounts (oauth2 credentials) to be connected to internal local user """ email = current_user.data.get('email') cn = current_user.data.get('cn') # A graph node for internal accounts associated to oauth2 try: user_node = self._graph.User.nodes.get(email=email) if user_node.authmethod != 'oauth2': # The user already exist with another type of authentication return None except self._graph.User.DoesNotExist: ## TO BE VERIFIED user_node = self.create_user(userdata={ 'uuid': getUUID(), 'email': email, 'authmethod': 'oauth2' }) ## NOTE: missing roles for this user? # A self._graph node for external oauth2 account try: oauth2_external = \ self._graph.ExternalAccounts.nodes.get(username=email) except self._graph.ExternalAccounts.DoesNotExist: oauth2_external = self._graph.ExternalAccounts(username=email) # update main info for this user oauth2_external.email = email oauth2_external.token = token oauth2_external.certificate_cn = cn oauth2_external.save() user_node.externals.connect(oauth2_external) return user_node, oauth2_external
def post(self): """ Register a UUID """ # Create graph object graph = self.global_get_service('neo4j') es = self.global_get_service('elasticsearch') # Create user if not exists username = self._args['owner'] user = graph.ProvidedUser.get_or_create({'username': username}).pop() # Add user to elastic search suggestions es.get_or_create_suggestion( es.GenericSuggestion, text=username, payload={'type': 'user'}) # Create and link UUID dobj = graph.DataObject(id=getUUID()) dobj.save() dobj.owned.connect(user) # Return the UUID return dobj.id
def init_users_and_roles(self): missing_role = missing_user = False try: # if no roles missing_role = not self._db.Role.query.first() if missing_role: logger.warning("No roles inside db. Injected defaults.") for role in self.DEFAULT_ROLES: sqlrole = self._db.Role(name=role, description="automatic") self._db.session.add(sqlrole) # if no users missing_user = not self._db.User.query.first() if missing_user: logger.warning("No users inside db. Injected default.") user = self._db.User( uuid=getUUID(), email=self.DEFAULT_USER, authmethod='credentials', name='Default', surname='User', password=self.hash_password(self.DEFAULT_PASSWORD)) # link roles into users for role in self.DEFAULT_ROLES: sqlrole = self._db.Role.query.filter_by(name=role).first() user.roles.append(sqlrole) self._db.session.add(user) except sqlalchemy.exc.OperationalError: raise AttributeError("Existing SQL tables are not consistent " + "to existing models. Please consider " + "rebuilding your DB.") if missing_user or missing_role: self._db.session.commit()
def store_oauth2_user(self, current_user, token): """ Allow external accounts (oauth2 credentials) to be connected to internal local user """ try: values = current_user.data except: return None, "Authorized response is invalid" # print("TEST", values, type(values)) if not isinstance(values, dict) or len(values) < 1: return None, "Authorized response is empty" email = values.get('email') cn = values.get('cn') ui = values.get('unity:persistent') # DN very strange: the current key is something like 'urn:oid:2.5.4.49' # is it going to change? dn = None for key, value in values.items(): if 'urn:oid' in key: dn = values.get(key) if dn is None: return None, "Missing DN from authorized response..." # Check if a user already exists with this email internal_user = None internal_users = self._db.User.query.filter( self._db.User.email == email).all() # If something found if len(internal_users) > 0: # Should never happen, please if len(internal_users) > 1: logger.critical("Multiple users?") return None, "Server misconfiguration" internal_user = internal_users.pop() logger.debug("Existing internal user: %s" % internal_user) # A user already locally exists with another authmethod. Not good. if internal_user.authmethod != 'oauth2': return None, "Creating a user which locally already exists" # If missing, add it locally else: # Create new one internal_user = self._db.User( uuid=getUUID(), email=email, authmethod='oauth2') # link default role into users internal_user.roles.append( self._db.Role.query.filter_by(name=self.DEFAULT_ROLE).first()) self._db.session.add(internal_user) self._db.session.commit() logger.info("Created internal user %s" % internal_user) # Get ExternalAccount for the oauth2 data if exists external_user = self._db.ExternalAccounts \ .query.filter_by(username=email).first() # or create it otherwise if external_user is None: external_user = self._db.ExternalAccounts(username=email, unity=ui) # Connect the external account to the current user external_user.main_user = internal_user # Note: for pre-production release # we allow only one external account per local user logger.info("Created external user %s" % external_user) # Update external user data to latest info received external_user.email = email external_user.token = token external_user.certificate_cn = cn external_user.certificate_dn = dn self._db.session.add(external_user) self._db.session.commit() logger.debug("Updated external user %s" % external_user) return internal_user, external_user
def invalidate_all_tokens(self, user=None): if user is None: user = self.get_user() user.uuid = getUUID() user.save()