Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
    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"
Ejemplo n.º 4
0
 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
Ejemplo n.º 5
0
    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
Ejemplo n.º 6
0
    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
Ejemplo n.º 7
0
    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
Ejemplo n.º 8
0
    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()
Ejemplo n.º 9
0
    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
Ejemplo n.º 10
0
    def invalidate_all_tokens(self, user=None):
        if user is None:
            user = self.get_user()

        user.uuid = getUUID()
        user.save()