Пример #1
0
    def create(self,
               name,
               value,
               expiration=None,
               encrypt=False,
               user_id=None):
        """ Creates a new named attribute, raising an exception if it already exists.
        """
        # Audit comes first
        audit_pii.info(self.cid,
                       'attr.create',
                       self.current_user_id,
                       user_id,
                       extra={
                           'current_app': self.current_app,
                           'remote_addr': self.remote_addr
                       })

        # Check access permissions to that user's attributes
        self._require_correct_user('create', user_id)

        with closing(self.odb_session_func()) as session:
            try:
                return self._create(session, name, value, expiration, encrypt,
                                    user_id)
            except IntegrityError:
                logger.warn(format_exc())
                raise ValidationError(status_code.attr.already_exists)
Пример #2
0
    def _set_expiry(self,
                    session,
                    name,
                    expiration,
                    user_id=None,
                    needs_commit=True):
        """ A low-level implementation of self.set_expiry which expects an SQL session on input.
        """
        # Audit comes first
        audit_pii.info(self.cid,
                       'attr._set_expiry',
                       self.current_user_id,
                       user_id,
                       extra={
                           'current_app': self.current_app,
                           'remote_addr': self.remote_addr,
                           'is_super_user': self.is_super_user
                       })

        # Check access permissions to that user's attributes
        self._require_correct_user('_set_expiry', user_id)

        return self._update(session,
                            name,
                            expiration=expiration,
                            user_id=user_id,
                            needs_commit=needs_commit)
Пример #3
0
    def renew(self,
              cid,
              ust,
              current_app,
              remote_addr,
              user_agent=None,
              needs_decrypt=True):
        """ Renew timelife of a user session, if it is valid, and returns its new expiration time in UTC.
        """
        # PII audit comes first
        audit_pii.info(cid,
                       'session.renew',
                       extra={
                           'current_app': current_app,
                           'remote_addr': remote_addr
                       })

        with closing(self.odb_session_func()) as session:
            expiration_time = self._get(session,
                                        ust,
                                        current_app,
                                        remote_addr,
                                        'renew',
                                        needs_decrypt=needs_decrypt,
                                        renew=True,
                                        user_agent=user_agent,
                                        check_if_password_expired=True)
            session.commit()
            return expiration_time
Пример #4
0
    def names(self, user_id=None, _utcnow=_utcnow):
        """ Returns names of all attributes as a list (unsorted).
        """
        # Audit comes first
        audit_pii.info(self.cid,
                       'attr.names',
                       self.current_user_id,
                       user_id,
                       extra={
                           'current_app': self.current_app,
                           'remote_addr': self.remote_addr,
                           'is_super_user': self.is_super_user
                       })

        # Check access permissions to that user's attributes
        self._require_correct_user('names', user_id)

        now = _utcnow()

        with closing(self.odb_session_func()) as session:
            q = session.query(AttrModel.name).\
                filter(AttrModel.user_id==(user_id or self.user_id)).\
                filter(AttrModel.ust==self.ust).\
                filter(AttrModel.expiration_time > now)

            if self.ust:
                q = q.\
                    filter(AttrModel.ust==SSOSession.ust).\
                    filter(SSOSession.expiration_time > now)

            result = q.all()

        return [item.name for item in result]
Пример #5
0
    def get_current_session(self, cid, current_ust, current_app, remote_addr,
                            needs_super_user):
        """ Returns current session info or raises an exception if it could not be found.
        Optionally, requires that a super-user be owner of current_ust.
        """
        # PII audit comes first
        audit_pii.info(cid,
                       'session.get_current_session',
                       extra={
                           'current_app': current_app,
                           'remote_addr': remote_addr
                       })

        # Verify current session's very existence first ..
        current_session = self._get_session(current_ust, current_app,
                                            remote_addr, 'get_current_session')
        if not current_session:
            logger.warn('Could not verify session `%s` `%s` `%s` `%s`',
                        current_ust, current_app, remote_addr, format_exc())
            raise ValidationError(status_code.auth.not_allowed, True)

        # .. the session exists but it may be still the case that we require a super-user on input.
        if needs_super_user:
            if not current_session.is_super_user:
                logger.warn(
                    'Current UST does not belong to a super-user, cannot continue (session.get_current_session), ' \
                    'current user is `%s` `%s`', current_session.user_id, current_session.username)
                raise ValidationError(status_code.auth.not_allowed, True)

        return current_session
Пример #6
0
    def require_super_user(self, cid, current_ust, current_app, remote_addr):
        """ Makes sure that current_ust belongs to a super-user or raises an exception if it does not.
        """
        # PII audit comes first
        audit_pii.info(cid, 'session.require_super_user', extra={'current_app':current_app, 'remote_addr':remote_addr})

        return self.get_current_session(cid, current_ust, current_app, remote_addr, True)
Пример #7
0
    def verify(self,
               cid,
               target_ust,
               current_ust,
               current_app,
               remote_addr,
               user_agent=None):
        """ Verifies a user session without renewing it.
        """
        # PII audit comes first
        audit_pii.info(cid,
                       'session.verify',
                       extra={
                           'current_app': current_app,
                           'remote_addr': remote_addr
                       })

        self.require_super_user(cid, current_ust, current_app, remote_addr)

        try:
            with closing(self.odb_session_func()) as session:
                return self._get(session,
                                 target_ust,
                                 current_app,
                                 remote_addr,
                                 'verify',
                                 renew=False,
                                 user_agent=user_agent)
        except Exception:
            logger.warn('Could not verify UST, e:`%s`', format_exc())
            return False
Пример #8
0
    def get_list(self, cid, ust, target_ust, current_ust, current_app, remote_addr, _unused_user_agent=None):
        """ Returns a list of sessions. Regular users may receive basic information about their own sessions only
        whereas super-users may look up any other user's session list.
        """
        # PII audit comes first
        audit_pii.info(cid, 'session.get_list', extra={'current_app':current_app, 'remote_addr':remote_addr})

        # Local aliases
        has_ust = bool(ust)
        current_ust_elem = ust if has_ust else current_ust

        current_session = self.get_current_session(cid, current_ust_elem, current_app, remote_addr, False)

        # We return a list of sessions for currently logged in user
        if has_ust:
            return self._get_session_list_by_user_id(current_session.user_id)

        else:
            # If we are to return a list of sessions for another UST, we need to be a super-user
            if not current_session.is_super_user:
                logger.warn(
                    'Current UST does not belong to a super-user, cannot continue (session.get_list), current user is ' \
                    '`%s` `%s`', current_session.user_id, current_session.username)
                raise ValidationError(status_code.auth.not_allowed, True)

            # If we are here, it means that we are a super-user and we are to return sessions
            # by another person's UST but there is still a chance that this other person is actually us.
            if current_ust == target_ust:
                return self._get_session_list_by_user_id(current_session.user_id)
            else:
                return self._get_session_list_by_ust(target_ust)
Пример #9
0
    def get(self, cid, target_ust, current_ust, current_app, remote_addr, user_agent=None, check_if_password_expired=True):
        """ Gets details of a session given by its UST on input, without renewing it.
        Must be called by a super-user.
        """
        # PII audit comes first
        audit_pii.info(cid, 'session.get', extra={'current_app':current_app, 'remote_addr':remote_addr})

        # Only super-users are allowed to call us
        current_session = self.require_super_user(cid, current_ust, current_app, remote_addr)

        # This returns all attributes ..
        session = self._get_session(
            target_ust, current_app, remote_addr, 'get', check_if_password_expired, user_agent=user_agent)

        # .. and we need to build a session entity with a few selected ones only
        out = SessionEntity()
        out.creation_time = session.creation_time
        out.expiration_time = session.expiration_time
        out.remote_addr = session.remote_addr
        out.user_agent = session.user_agent
        out.attr = AttrAPI(cid, current_session.user_id, current_session.is_super_user,
            current_app, remote_addr, self.odb_session_func, self.is_sqlite, self.encrypt_func, self.decrypt_func,
            session.user_id, session.ust)

        return out
Пример #10
0
    def set_expiry_many(self, data, expiration=None, user_id=None):
        """ Sets expiry for multiple attributes in one call.
        """
        # Audit comes first
        audit_pii.info(self.cid,
                       'attr.set_expiry_many',
                       self.current_user_id,
                       user_id,
                       extra={
                           'current_app': self.current_app,
                           'remote_addr': self.remote_addr
                       })

        with closing(self.odb_session_func()) as session:
            for item in data:

                # Check access permissions to that user's attributes
                _user_id = item.get('user_id', user_id)
                self._require_correct_user('set_expiry_many', _user_id)

                # Check OK
                self._set_expiry(session,
                                 item['name'],
                                 item.get('expiration', expiration),
                                 _user_id,
                                 needs_commit=False)

            # Commit now everything added to session thus far
            session.commit()
Пример #11
0
    def _get(self,
             session,
             data,
             decrypt,
             serialize_dt,
             user_id=None,
             columns=AttrModel,
             exists_only=False,
             _utcnow=_utcnow):
        """ A low-level implementation of self.get which knows how to return one or more named attributes.
        """
        # Audit comes first
        audit_pii.info(self.cid,
                       'attr._get',
                       self.current_user_id,
                       user_id,
                       extra={
                           'current_app': self.current_app,
                           'remote_addr': self.remote_addr,
                           'data': data,
                           'is_super_user': self.is_super_user
                       })

        # Check access permissions to that user's attributes
        self._require_correct_user('_get', user_id)

        data = [data] if isinstance(data, basestring) else data
        out = dict.fromkeys(data, None)

        now = _utcnow()

        q = session.query(columns).\
            filter(AttrModel.user_id==(user_id or self.user_id)).\
            filter(AttrModel.ust==self.ust).\
            filter(AttrModel.name.in_(data)).\
            filter(AttrModel.expiration_time > now)

        if self.ust:
            q = q.\
                filter(AttrModel.ust==SSOSession.ust).\
                filter(SSOSession.expiration_time > now)

        result = q.all()

        for item in result:
            out[item.name] = True if exists_only else AttrEntity.from_sql(
                item, decrypt, self.decrypt_func, serialize_dt)

        # Explicitly convert None to False to satisfy the requirement of returning a boolean value
        # if we are being called from self.exist (otherwise, None is fine).
        if exists_only:
            for key, value in out.items():
                if value is None:
                    out[key] = False

        if len(data) == 1:
            return out[data[0]]
        else:
            return out
Пример #12
0
    def _update(self,
                session,
                name,
                value=None,
                expiration=None,
                encrypt=False,
                user_id=None,
                needs_commit=True,
                _utcnow=_utcnow):
        """ A low-level implementation of self.update which expects an SQL session on input.
        """
        # Audit comes first
        audit_pii.info(self.cid,
                       'attr._update',
                       self.current_user_id,
                       user_id,
                       extra={
                           'current_app': self.current_app,
                           'remote_addr': self.remote_addr,
                           'name': name,
                           'expiration': expiration,
                           'encrypt': encrypt,
                           'is_super_user': self.is_super_user
                       })

        # Check access permissions to that user's attributes
        self._require_correct_user('_update', user_id)

        now = _utcnow()
        values = {'last_modified': now}

        if value:
            values['value'] = dumps(
                self.encrypt_func(value.encode('utf8')) if encrypt else value)

        if expiration:
            values['expiration_time'] = now + timedelta(seconds=expiration)

        and_condition = [
            AttrModelTable.c.user_id == (user_id or self.user_id),
            AttrModelTable.c.ust == self.ust,
            AttrModelTable.c.name == name,
            AttrModelTable.c.expiration_time > now,
        ]

        if self.ust:
            and_condition.extend([
                AttrModelTable.c.ust == SSOSessionTable.c.ust,
                SSOSessionTable.c.expiration_time > now
            ])

        session.execute(
            AttrModelTableUpdate().\
            values(values).\
            where(and_(*and_condition)))

        if needs_commit:
            session.commit()
Пример #13
0
    def on_external_auth_succeeded(self,
                                   cid,
                                   sec_def,
                                   user_id,
                                   ext_session_id,
                                   current_app,
                                   remote_addr,
                                   user_agent=None,
                                   _basic_auth=SEC_DEF_TYPE.BASIC_AUTH,
                                   _jwt=SEC_DEF_TYPE.JWT,
                                   _utcnow=datetime.utcnow,
                                   _sha256=sha256):
        """ Invoked when a user succeeded in authentication via means external to default SSO credentials,
        e.g. through Basic Auth or JWT. Creates an SSO session related to that event or renews an existing one.
        """
        # type: (unicode, Bunch, unicode, unicode, unicode, unicode) -> SessionInfo

        # PII audit comes first
        audit_pii.info(cid,
                       'session.on_external_auth_succeeded',
                       extra={
                           'current_app': current_app,
                           'remote_addr': remote_addr,
                           'sec.sec_type': sec_def.sec_type,
                           'sec.id': sec_def.id,
                           'sec.username': sec_def.username,
                       })

        if sec_def.sec_type == _basic_auth:
            ext_session_id = '{}.{}'.format(sec_def.sec_type, sec_def.id)
        elif sec_def.sec_type == _jwt:
            # JWT tokens tend to be long so we store and hashes rather than raw values
            ext_session_id = _sha256(ext_session_id).hexdigest()
        else:
            raise NotImplementedError()

        existing_ust = None  # type: unicode

        # Check if there is already a session associated with this external one
        with closing(self.odb_session_func()) as session:
            sso_session = get_session_by_ext_id(session, ext_session_id,
                                                _utcnow())
            if sso_session:
                existing_ust = sso_session.ust

        # .. if there is, renew it ..
        if existing_ust:
            self.renew(cid, existing_ust, current_app, remote_addr, user_agent,
                       False)

        # .. otherwise, create a new one. Note that we get here only if
        else:
            ctx = LoginCtx(remote_addr, user_agent, False, False, {
                'user_id': user_id,
                'current_app': current_app
            }, ext_session_id)
            return self.login(ctx, is_logged_in_ext=True)
Пример #14
0
    def _create(self,
                session,
                name,
                value,
                expiration=None,
                encrypt=False,
                user_id=None,
                needs_commit=True,
                _utcnow=_utcnow):
        """ A low-level implementation of self.create which expects an SQL session on input.
        """
        # Audit comes first
        audit_pii.info(self.cid,
                       'attr._create',
                       self.current_user_id,
                       user_id,
                       extra={
                           'current_app': self.current_app,
                           'remote_addr': self.remote_addr,
                           'name': name,
                           'expiration': expiration,
                           'encrypt': encrypt,
                           'is_super_user': self.is_super_user
                       })

        self._require_correct_user('_create', user_id)

        now = _utcnow()

        attr_model = AttrModel()
        attr_model.user_id = user_id or self.user_id
        attr_model.ust = self.ust
        attr_model._ust_string = self.ust or ''  # Cannot, and will not be, NULL, check the comment in the model for details
        attr_model.is_session_attr = self.is_session_attr
        attr_model.name = name
        attr_model.value = dumps(
            self.encrypt_func(value.encode('utf8')) if encrypt else value)
        attr_model.is_encrypted = encrypt
        attr_model.creation_time = now
        attr_model.last_modified = now

        # Expiration is optional
        attr_model.expiration_time = now + timedelta(
            seconds=expiration) if expiration else _default_expiration

        session.add(attr_model)

        if needs_commit:
            session.commit()
Пример #15
0
Файл: attr.py Проект: danlg/zato
    def delete(self, data, user_id=None, _utcnow=_utcnow):
        """ Deletes one or more names attributes.
        """
        # Audit comes first
        audit_pii.info(self.cid,
                       'attr.delete/delete_many',
                       self.current_user_id,
                       user_id,
                       extra={
                           'current_app': self.current_app,
                           'remote_addr': self.remote_addr,
                           'data': data,
                           'is_super_user': self.is_super_user
                       })

        # Check access permissions to that user's attributes
        self._require_correct_user('delete', user_id)

        now = _utcnow()
        data = [data] if isinstance(data, basestring) else data

        and_condition = [
            AttrModelTable.c.user_id == (user_id or self.user_id),
            AttrModelTable.c.ust == self.ust,
            AttrModelTable.c.name.in_(data),
            AttrModelTable.c.expiration_time > now,
        ]

        with closing(self.odb_session_func()) as session:

            if self.ust:

                # Check comment in self._update for a comment why the below is needed
                if self.is_sqlite:
                    result = self._ensure_ust_is_not_expired(
                        session, self.ust, now)
                    if not result:
                        raise ValidationError(
                            status_code.session.no_such_session)
                else:
                    and_condition.extend([
                        AttrModelTable.c.ust == SSOSessionTable.c.ust,
                        SSOSessionTable.c.expiration_time > now
                    ])

            session.execute(
                AttrModelTableDelete().\
                where(and_(*and_condition)))
            session.commit()
Пример #16
0
    def set_many(self, data, expiration=None, encrypt=False, user_id=None):
        """ Sets values of multiple attributes in one call.
        """
        # Audit comes first
        audit_pii.info(self.cid,
                       'attr.set_many',
                       self.current_user_id,
                       user_id,
                       extra={
                           'current_app': self.current_app,
                           'remote_addr': self.remote_addr
                       })

        # Check access permissions to that user's attributes
        self._require_correct_user('set_many', user_id)

        self._call_many(self._set, data, expiration, encrypt, user_id)
Пример #17
0
    def exists(self, data, user_id=None):
        """ Returns a boolean flag to indicate if input attribute(s) exist(s) or not.
        """
        # Audit comes first
        audit_pii.info(self.cid,
                       'attr.exists/exists_many',
                       self.current_user_id,
                       user_id,
                       extra={
                           'current_app': self.current_app,
                           'remote_addr': self.remote_addr
                       })

        # Check access permissions to that user's attributes
        self._require_correct_user('exists', user_id)

        with closing(self.odb_session_func()) as session:
            return self._exists(session, data, user_id)
Пример #18
0
    def set_expiry(self, name, expiration, user_id=None):
        """ Sets expiration for a named attribute.
        """
        # Audit comes first
        audit_pii.info(self.cid,
                       'attr.set_expiry',
                       self.current_user_id,
                       user_id,
                       extra={
                           'current_app': self.current_app,
                           'remote_addr': self.remote_addr
                       })

        # Check access permissions to that user's attributes
        self._require_correct_user('set_expiry', user_id)

        with closing(self.odb_session_func()) as session:
            return self._set_expiry(session, name, expiration, user_id)
Пример #19
0
    def get(self, data, decrypt=True, serialize_dt=False, user_id=None):
        """ Returns a named attribute.
        """
        # Audit comes first
        audit_pii.info(self.cid,
                       'attr.get/get_many',
                       self.current_user_id,
                       user_id,
                       extra={
                           'current_app': self.current_app,
                           'remote_addr': self.remote_addr
                       })

        # Check access permissions to that user's attributes
        self._require_correct_user('get', user_id)

        with closing(self.odb_session_func()) as session:
            return self._get(session, data, decrypt, serialize_dt, user_id)
Пример #20
0
    def set(self, name, value, expiration=None, encrypt=False, user_id=None):
        """ Set value of a named attribute, creating it if it does not already exist.
        """
        # Audit comes first
        audit_pii.info(self.cid,
                       'attr.set',
                       self.current_user_id,
                       user_id,
                       extra={
                           'current_app': self.current_app,
                           'remote_addr': self.remote_addr
                       })

        # Check access permissions to that user's attributes
        self._require_correct_user('set', user_id)

        with closing(self.odb_session_func()) as session:
            self._set(session, name, value, expiration, encrypt)
Пример #21
0
    def on_external_auth_succeeded(self, cid, sec_type, sec_def_id, sec_def_username, user_id, ext_session_id, totp_code,
        current_app, remote_addr, user_agent=None, _utcnow=datetime.utcnow,
        ):
        """ Invoked when a user succeeded in authentication via means external to default SSO credentials,
        e.g. through Basic Auth or JWT. Creates an SSO session related to that event or renews an existing one.
        """
        # type: (unicode, Bunch, unicode, unicode, unicode, unicode) -> SessionInfo

        remote_addr = remote_addr if isinstance(remote_addr, unicode) else remote_addr.decode('utf8')

        # PII audit comes first
        audit_pii.info(cid, 'session.on_external_auth_succeeded', extra={
            'current_app':current_app,
            'remote_addr':remote_addr,
            'sec.sec_type': sec_type,
            'sec.id': sec_def_id,
            'sec.username': sec_def_username,
        })

        existing_ust = None # type: unicode
        ext_session_id = self._format_ext_session_id(sec_type, sec_def_id, ext_session_id)

        # Check if there is already a session associated with this external one
        sso_session = self._get_session_by_ext_id(sec_type, sec_def_id, ext_session_id)
        if sso_session:
            existing_ust = sso_session.ust

        # .. if there is, renew it ..
        if existing_ust:
            expiration_time = self.renew(cid, existing_ust, current_app, remote_addr, user_agent, False)
            session_info = SessionInfo()
            session_info.ust = existing_ust
            session_info.expiration_time = expiration_time
            return session_info

        # .. otherwise, create a new one. Note that we get here only if
        else:
            ctx = LoginCtx(remote_addr, user_agent, False, False, {
                'user_id': user_id,
                'current_app': current_app,
                'totp_code': totp_code,
                'sec_type': sec_type,
            }, ext_session_id)
            return self.login(ctx, is_logged_in_ext=True)
Пример #22
0
    def _exists(self, session, data, user_id=None):
        """ A low-level implementation of self.exists which expects an SQL session on input.
        """
        # Audit comes first
        audit_pii.info(self.cid,
                       'attr._exists',
                       self.current_user_id,
                       user_id,
                       extra={
                           'current_app': self.current_app,
                           'remote_addr': self.remote_addr,
                           'is_super_user': self.is_super_user
                       })

        # Check access permissions to that user's attributes
        self._require_correct_user('_exists', user_id)

        return self._get(session, data, False, False, user_id, AttrModel.name,
                         True)
Пример #23
0
Файл: attr.py Проект: danlg/zato
    def _call_many(self,
                   func,
                   data,
                   expiration=None,
                   encrypt=False,
                   user_id=None):
        """ A reusable method for manipulation of multiple attributes at a time.
        """
        # Audit comes first
        audit_pii.info(self.cid,
                       'attr._call_many',
                       self.current_user_id,
                       user_id,
                       extra={
                           'current_app': self.current_app,
                           'remote_addr': self.remote_addr,
                           'is_super_user': self.is_super_user,
                           'func': func.__func__.__name__
                       })

        with closing(self.odb_session_func()) as session:
            for item in data:

                # Check access permissions to that user's attributes
                _user_id = item.get('user_id', user_id)
                self._require_correct_user('_call_many', _user_id)

                func(session,
                     item['name'],
                     item['value'],
                     item.get('expiration', expiration),
                     item.get('encrypt', encrypt),
                     _user_id,
                     needs_commit=False)

            # Commit now everything added to session thus far
            try:
                session.commit()
            except IntegrityError:
                logger.warn(format_exc())
                raise ValidationError(status_code.attr.already_exists)
Пример #24
0
    def delete(self, data, user_id=None, _utcnow=_utcnow):
        """ Deletes one or more names attributes.
        """
        # Audit comes first
        audit_pii.info(self.cid,
                       'attr.delete/delete_many',
                       self.current_user_id,
                       user_id,
                       extra={
                           'current_app': self.current_app,
                           'remote_addr': self.remote_addr,
                           'data': data,
                           'is_super_user': self.is_super_user
                       })

        # Check access permissions to that user's attributes
        self._require_correct_user('delete', user_id)

        now = _utcnow()
        data = [data] if isinstance(data, basestring) else data

        and_condition = [
            AttrModelTable.c.user_id == (user_id or self.user_id),
            AttrModelTable.c.ust == self.ust,
            AttrModelTable.c.name.in_(data),
            AttrModelTable.c.expiration_time > now,
        ]

        if self.ust:
            and_condition.extend([
                AttrModelTable.c.ust == SSOSessionTable.c.ust,
                SSOSessionTable.c.expiration_time > now
            ])

        with closing(self.odb_session_func()) as session:
            session.execute(
                AttrModelTableDelete().\
                where(and_(*and_condition)))
            session.commit()
Пример #25
0
    def _set(self,
             session,
             name,
             value,
             expiration=None,
             encrypt=False,
             user_id=None,
             needs_commit=True):
        """ A low-level implementation of self.set which expects an SQL session on input.
        """
        # Audit comes first
        audit_pii.info(self.cid,
                       'attr._set',
                       self.current_user_id,
                       user_id,
                       extra={
                           'current_app': self.current_app,
                           'remote_addr': self.remote_addr,
                           'name': name,
                           'expiration': expiration,
                           'encrypt': encrypt,
                           'is_super_user': self.is_super_user
                       })

        # Check access permissions to that user's attributes
        self._require_correct_user('_set', user_id)

        # Check if the attribute exists ..
        if self._exists(session, name, user_id):

            # .. it does, so we need to set its new value.
            self._update(session, name, value, expiration, encrypt, user_id,
                         needs_commit)

        # .. does not exist, so we need to create it
        else:
            self._create(session, name, value, expiration, encrypt, user_id,
                         needs_commit)
Пример #26
0
    def update(self,
               name,
               value,
               expiration=None,
               encrypt=False,
               user_id=None):
        """ Updates an existing attribute, raising an exception if it does not already exist.
        """
        # Audit comes first
        audit_pii.info(self.cid,
                       'attr.update',
                       self.current_user_id,
                       user_id,
                       extra={
                           'current_app': self.current_app,
                           'remote_addr': self.remote_addr
                       })

        # Check access permissions to that user's attributes
        self._require_correct_user('update', user_id)

        with closing(self.odb_session_func()) as session:
            return self._update(session, name, value, expiration, encrypt,
                                user_id)
Пример #27
0
Файл: attr.py Проект: danlg/zato
    def _update(self,
                session,
                name,
                value=None,
                expiration=None,
                encrypt=False,
                user_id=None,
                needs_commit=True,
                _utcnow=_utcnow):
        """ A low-level implementation of self.update which expects an SQL session on input.
        """
        # Audit comes first
        audit_pii.info(self.cid,
                       'attr._update',
                       self.current_user_id,
                       user_id,
                       extra={
                           'current_app': self.current_app,
                           'remote_addr': self.remote_addr,
                           'name': name,
                           'expiration': expiration,
                           'encrypt': encrypt,
                           'is_super_user': self.is_super_user
                       })

        # Check access permissions to that user's attributes
        self._require_correct_user('_update', user_id)

        now = _utcnow()
        values = {'last_modified': now}

        if value:
            values['value'] = dumps(
                self.encrypt_func(value.encode('utf8')) if encrypt else value)

        if expiration:
            values['expiration_time'] = now + timedelta(seconds=expiration)

        and_condition = [
            AttrModelTable.c.user_id == (user_id or self.user_id),
            AttrModelTable.c.ust == self.ust,
            AttrModelTable.c.name == name,
            AttrModelTable.c.expiration_time > now,
        ]

        if self.ust:

            # SQLite needs to be treated in a special way, otherwise we get an exception from SQLAlchemy
            # NotImplementedError: This backend does not support multiple-table criteria within UPDATE
            # which means that on SQLite we need an additional query.
            if self.is_sqlite:
                result = self._ensure_ust_is_not_expired(
                    session, self.ust, now)
                if not result:
                    raise ValidationError(status_code.session.no_such_session)
            else:
                and_condition.extend([
                    AttrModelTable.c.ust == SSOSessionTable.c.ust,
                    SSOSessionTable.c.expiration_time > now
                ])

        session.execute(
            AttrModelTableUpdate().\
            values(values).\
            where(and_(*and_condition)))

        if needs_commit:
            session.commit()