Ejemplo n.º 1
0
    def invalidate_all_tokens(self, user=None):
        if user is None:
            user = self.get_user()

        user.uuid = getUUID()
        user.save()
        return True
Ejemplo n.º 2
0
    def fill_payload(self, userobj, expiration=None, token_type=None):
        """ Informations to store inside the JWT token,
        starting from the user obtained from the current service

        Claim attributes listed here:
        http://blog.apcelent.com/json-web-token-tutorial-example-python.html

        TTL is measured in seconds
        """

        if expiration is None:
            expiration = timedelta(seconds=self.longTTL)

        payload = {'user_id': userobj.uuid, 'jti': getUUID()}

        short_jwt = \
            Detector.get_global_var('AUTH_FULL_JWT_PAYLOAD', '') \
            .lower() == 'false'

        if token_type is not None:
            if token_type == self.PWD_RESET or \
               token_type == self.ACTIVATE_ACCOUNT:
                short_jwt = True
                payload["t"] = token_type

        if not short_jwt:
            now = datetime.now(pytz.utc)
            nbf = now  # you can add a timedelta
            exp = now + expiration
            payload['iat'] = now
            payload['nbf'] = nbf
            payload['exp'] = exp

        return self.fill_custom_payload(userobj, payload)
Ejemplo n.º 3
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()
     user.save()
     log.warning("User uuid changed to: %s", user.uuid)
     return True
Ejemplo n.º 4
0
def test():

    # 7de267d0-4680-4530-9861-d3c5204a2e46
    regexp = r"[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}"

    u = getUUID()
    assert u is not None
    assert isinstance(u, str)
    assert len(u) == 36
    assert re.match(regexp, u) is not None
    assert u != getUUID()

    u = getUUIDfromString("test")
    assert u is not None
    assert isinstance(u, str)
    assert len(u) == 36
    assert re.match(regexp, u) is not None
    assert u == getUUIDfromString("test")
    assert u != getUUIDfromString("test2")
Ejemplo n.º 5
0
 def write_key_and_cert(self, key, cert):
     proxycertcontent = cert.decode()
     if proxycertcontent is None or proxycertcontent.strip() == '':
         return None
     tempfile = "/tmp/%s" % getUUID()
     flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL
     with os.fdopen(os.open(tempfile, flags, 0o600), 'w') as f:
         f.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, key).decode())
         f.write(proxycertcontent)
     return tempfile
Ejemplo n.º 6
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()
     log.warning("User uuid changed to: %s", user.uuid)
     return True
Ejemplo n.º 7
0
    def __init__(self, services, app=None):

        sql = services.get('sqlalchemy', None)

        if sql is None:
            log.critical("Unable to retrieve sqlalchemy service")
            return

        if app is None:
            log.critical("Unable to retrieve app context")
            return

        if os.environ.get('SEADATA_PROJECT', False):

            with app.app_context():
                users = os.environ.get('SEADATA_PRIVILEGED_USERS')

                if users is None or users == "":
                    users = []
                else:
                    users = users.replace(' ', '').split(',')
                # users = ['stresstest', 'svanderhorst']
                roles = ['normal_user', 'staff_user']
                if len(users) == 0:
                    log.info("No privileged user found")
                else:
                    for username in users:

                        if username == "":
                            log.warning("Invalid username: [%s]", username)
                            continue
                        try:
                            log.info("Creating user %s", username)
                            userdata = {
                                "uuid": getUUID(),
                                "email": username,
                                "name": username,
                                "surname": 'iCAT',
                                "authmethod": 'irods',
                            }
                            user = sql.User(**userdata)
                            for r in roles:
                                user.roles.append(
                                    sql.Role.query.filter_by(name=r).first())
                            sql.session.add(user)
                            sql.session.commit()
                            log.info("User %s created with roles: %s",
                                     username, roles)
                        except BaseException as e:
                            log.error("Errors creating user %s: %s", username,
                                      str(e))
Ejemplo n.º 8
0
    def irods_user(self, username, session):

        # create user
        user = self.db.User(
            email=username,
            name=username,
            surname='iCAT',
            uuid=getUUID(),
            authmethod='irods',
            session=session,
        )
        # add role
        user.roles.append(
            self.db.Role.query.filter_by(name=self.default_role).first())

        # save
        self.db.session.add(user)
        from sqlalchemy.exc import IntegrityError
        try:
            self.db.session.commit()
            log.info('Cached iRODS user: %s', username)
        except IntegrityError:
            # rollback current commit
            self.db.session.rollback()
            log.warning("iRODS user already cached: %s", username)
            # get the existing object
            user = self.get_user_object(username)
            # update only the session field
            user.session = session

        # token
        token, jti = self.create_token(self.fill_payload(user))
        now = datetime.now(pytz.utc)
        if user.first_login is None:
            user.first_login = now
        user.last_login = now
        self.db.session.add(user)
        self.db.session.commit()
        self.save_token(user, token, jti)

        return token, username
Ejemplo n.º 9
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:
                log.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:
                log.warning("No users inside db. Injected default.")
                self.create_user(
                    {
                        'uuid': getUUID(),
                        'email': self.default_user,
                        # 'authmethod': 'credentials',
                        'name': 'Default',
                        'surname': 'User',
                        # 'password': self.hash_password(self.default_password)
                        'password': self.default_password
                    },
                    roles=self.default_roles)

        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.º 10
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 BaseException:
            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, _ 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:
                log.critical("Multiple users?")
                return None, "Server misconfiguration"
            internal_user = internal_users.pop()
            log.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()
            log.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
            log.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()
        log.debug("Updated external user %s", external_user)

        return internal_user, external_user
Ejemplo n.º 11
0
    def init_users_and_roles(self):

        missing_role = missing_user = False
        roles = []
        transactions = []

        try:

            # if no roles
            cursor = self.db.Role.objects.all()
            missing_role = len(list(cursor)) < 1

            for role in self.default_roles:
                role = self.db.Role(name=role, description="automatic")
                if missing_role:
                    transactions.append(role)
                roles.append(role)

            if missing_role:
                log.warning("No roles inside mongo. Injected defaults.")

            # if no users
            cursor = self.db.User.objects.all()
            missing_user = len(list(cursor)) < 1

            if missing_user:

                self.create_user(
                    {
                        'uuid': getUUID(),
                        'email': self.default_user,
                        # 'authmethod': 'credentials',
                        'name': 'Default',
                        'surname': 'User',
                        # 'password': self.hash_password(self.default_password)
                        'password': self.default_password
                    },
                    roles=roles)

                # 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
                # user.roles = roles
                # for role in roles:
                #     user.roles.append(role)

                # transactions.append(user)
                log.warning("No users inside mongo. Injected default.")

        except BaseException as e:
            raise AttributeError("Models for auth are wrong:\n%s" % e)

        if missing_user or missing_role:
            for transaction in transactions:
                transaction.save()
            log.info("Saved init transactions")
Ejemplo n.º 12
0
 def custom_user_properties(self, userdata):
     new_userdata = super(Authentication,
                          self).custom_user_properties(userdata)
     if not new_userdata.get('uuid'):
         new_userdata['uuid'] = getUUID()
     return new_userdata