Example #1
0
def _merge_users(target, source, **kwargs):
    BlockingPrincipal.merge_users(target, source, 'blocking')
    Blocking.find(created_by_id=source.id).update({Blocking.created_by_id: target.id})
    Reservation.find(created_by_id=source.id).update({Reservation.created_by_id: target.id})
    Reservation.find(booked_for_id=source.id).update({Reservation.booked_for_id: target.id})
    Room.find(owner_id=source.id).update({Room.owner_id: target.id})
    rb_settings.acls.merge_users(target, source)
Example #2
0
def _merge_users(target, source, **kwargs):
    BlockingPrincipal.merge_users(target, source, 'blocking')
    Blocking.find(created_by_id=source.id).update({Blocking.created_by_id: target.id})
    Reservation.find(created_by_id=source.id).update({Reservation.created_by_id: target.id})
    Reservation.find(booked_for_id=source.id).update({Reservation.booked_for_id: target.id})
    Room.find(owner_id=source.id).update({Room.owner_id: target.id})
    rb_settings.acls.merge_users(target, source)
Example #3
0
def _merge_users(target, source, **kwargs):
    from indico.modules.rb.models.blocking_principals import BlockingPrincipal
    from indico.modules.rb.models.blockings import Blocking
    from indico.modules.rb.models.principals import RoomPrincipal
    from indico.modules.rb.models.reservations import Reservation
    Blocking.query.filter_by(created_by_id=source.id).update({Blocking.created_by_id: target.id})
    BlockingPrincipal.merge_users(target, source, 'blocking')
    Reservation.query.filter_by(created_by_id=source.id).update({Reservation.created_by_id: target.id})
    Reservation.query.filter_by(booked_for_id=source.id).update({Reservation.booked_for_id: target.id})
    Room.query.filter_by(owner_id=source.id).update({Room.owner_id: target.id})
    RoomPrincipal.merge_users(target, source, 'room')
    rb_settings.acls.merge_users(target, source)
Example #4
0
def _merge_users(target, source, **kwargs):
    from indico.modules.rb.models.blocking_principals import BlockingPrincipal
    from indico.modules.rb.models.blockings import Blocking
    from indico.modules.rb.models.principals import RoomPrincipal
    from indico.modules.rb.models.reservations import Reservation
    Blocking.query.filter_by(created_by_id=source.id).update({Blocking.created_by_id: target.id})
    BlockingPrincipal.merge_users(target, source, 'blocking')
    Reservation.query.filter_by(created_by_id=source.id).update({Reservation.created_by_id: target.id})
    Reservation.query.filter_by(booked_for_id=source.id).update({Reservation.booked_for_id: target.id})
    Room.query.filter_by(owner_id=source.id).update({Room.owner_id: target.id})
    RoomPrincipal.merge_users(target, source, 'room')
    rb_settings.acls.merge_users(target, source)
Example #5
0
def test_can_be_overridden_acl(dummy_blocking, dummy_user, create_user,
                               dummy_group, in_acl, expected):
    user = create_user('user', groups={dummy_group.id})
    dummy_blocking.allowed = [
        BlockingPrincipal(entity_type='Avatar', entity_id=dummy_user.id)
    ]
    if in_acl == 'user':
        dummy_blocking.allowed.append(
            BlockingPrincipal(entity_type='Avatar', entity_id=user.id))
    elif in_acl == 'group':
        dummy_blocking.allowed.append(
            BlockingPrincipal(entity_type='Group', entity_id=dummy_group.id))
    assert dummy_blocking.can_be_overridden(user) == expected
Example #6
0
def rb_merge_users(new_id, old_id):
    """Updates RB data after an Avatar merge

    :param new_id: Target user
    :param old_id: Source user (being deleted in the merge)
    """
    from indico.modules.rb import settings as rb_settings
    from indico.modules.rb.models.blocking_principals import BlockingPrincipal
    from indico.modules.rb.models.blockings import Blocking
    from indico.modules.rb.models.reservations import Reservation
    from indico.modules.rb.models.rooms import Room

    old_user = User.get(int(old_id))
    new_user = User.get(int(new_id))
    for bp in BlockingPrincipal.find():
        if bp.principal == old_user:
            bp.principal = new_user
    Blocking.find(created_by_id=old_id).update({'created_by_id': new_id})
    Reservation.find(created_by_id=old_id).update({'created_by_id': new_id})
    Reservation.find(booked_for_id=old_id).update({'booked_for_id': new_id})
    Room.find(owner_id=old_id).update({'owner_id': new_id})
    for key in ('authorized_principals', 'admin_principals'):
        principals = rb_settings.get(key)
        principals = principals_merge_users(principals, new_id, old_id)
        rb_settings.set(key, principals)
Example #7
0
 def _save(self):
     blocking = self._blocking
     blocking.reason = self._form.reason.data
     # Just overwrite the whole list
     blocking.allowed = [
         BlockingPrincipal(entity_type=item['_type'], entity_id=item['id'])
         for item in self._form.principals.data
     ]
     # Blocked rooms need some more work as we can't just overwrite them
     old_blocked = {br.room_id for br in blocking.blocked_rooms}
     new_blocked = set(self._form.blocked_rooms.data)
     added_blocks = new_blocked - old_blocked
     removed_blocks = old_blocked - new_blocked
     for room_id in removed_blocks:
         blocked_room = next(br for br in blocking.blocked_rooms
                             if br.room_id == room_id)
         blocking.blocked_rooms.remove(blocked_room)
     added_blocked_rooms = []
     for room_id in added_blocks:
         blocked_room = BlockedRoom(room_id=room_id)
         blocking.blocked_rooms.append(blocked_room)
         added_blocked_rooms.append(blocked_room)
     db.session.flush()
     flash(_(u'Blocking updated'), 'success')
     self._process_blocked_rooms(added_blocked_rooms)
Example #8
0
def rb_merge_users(new_id, old_id):
    """Updates RB data after an Avatar merge

    :param new_id: Target user
    :param old_id: Source user (being deleted in the merge)
    """
    from indico.modules.rb import settings as rb_settings
    from indico.modules.rb.models.blocking_principals import BlockingPrincipal
    from indico.modules.rb.models.blockings import Blocking
    from indico.modules.rb.models.reservations import Reservation
    from indico.modules.rb.models.rooms import Room

    old_user = User.get(int(old_id))
    new_user = User.get(int(new_id))
    for bp in BlockingPrincipal.find():
        if bp.principal == old_user:
            bp.principal = new_user
    Blocking.find(created_by_id=old_id).update({'created_by_id': new_id})
    Reservation.find(created_by_id=old_id).update({'created_by_id': new_id})
    Reservation.find(booked_for_id=old_id).update({'booked_for_id': new_id})
    Room.find(owner_id=old_id).update({'owner_id': new_id})
    for key in ('authorized_principals', 'admin_principals'):
        principals = rb_settings.get(key)
        principals = principals_merge_users(principals, new_id, old_id)
        rb_settings.set(key, principals)
Example #9
0
def rb_merge_users(new_id, old_id):
    """Updates RB data after an Avatar merge

    :param new_id: Target user
    :param old_id: Source user (being deleted in the merge)
    """
    from indico.modules.rb import settings
    from indico.modules.rb.models.blocking_principals import BlockingPrincipal
    from indico.modules.rb.models.blockings import Blocking
    from indico.modules.rb.models.reservations import Reservation
    from indico.modules.rb.models.rooms import Room

    BlockingPrincipal.find(entity_type='Avatar', entity_id=old_id).update({'entity_id': new_id})
    Blocking.find(created_by_id=old_id).update({'created_by_id': new_id})
    Reservation.find(created_by_id=old_id).update({'created_by_id': new_id})
    Reservation.find(booked_for_id=old_id).update({'booked_for_id': new_id})
    Room.find(owner_id=old_id).update({'owner_id': new_id})
    for key in ('authorized_principals', 'admin_principals'):
        principals = settings.get(key, [])
        principals = principals_merge_users(principals, new_id, old_id)
        settings.set(key, principals)
Example #10
0
def rb_merge_users(new_id, old_id):
    """Updates RB data after an Avatar merge

    :param new_id: Target user
    :param old_id: Source user (being deleted in the merge)
    """
    from indico.modules.rb import settings
    from indico.modules.rb.models.blocking_principals import BlockingPrincipal
    from indico.modules.rb.models.blockings import Blocking
    from indico.modules.rb.models.reservations import Reservation
    from indico.modules.rb.models.rooms import Room

    BlockingPrincipal.find(entity_type='Avatar',
                           entity_id=old_id).update({'entity_id': new_id})
    Blocking.find(created_by_id=old_id).update({'created_by_id': new_id})
    Reservation.find(created_by_id=old_id).update({'created_by_id': new_id})
    Reservation.find(booked_for_id=old_id).update({'booked_for_id': new_id})
    Room.find(owner_id=old_id).update({'owner_id': new_id})
    for key in ('authorized_principals', 'admin_principals'):
        principals = settings.get(key, [])
        principals = principals_merge_users(principals, new_id, old_id)
        settings.set(key, principals)
Example #11
0
    def migrate_blockings(self):
        state_map = {
            None: BlockedRoom.State.pending,
            False: BlockedRoom.State.rejected,
            True: BlockedRoom.State.accepted
        }

        print cformat('%{white!}migrating blockings')
        for old_blocking_id, old_blocking in self.rb_root['RoomBlocking'][
                'Blockings'].iteritems():
            b = Blocking(id=old_blocking.id,
                         created_by_id=self.merged_avatars.get(
                             old_blocking._createdBy, old_blocking._createdBy),
                         created_dt=as_utc(old_blocking._utcCreatedDT),
                         start_date=old_blocking.startDate,
                         end_date=old_blocking.endDate,
                         reason=convert_to_unicode(old_blocking.message))

            print cformat(u'- %{cyan}{}').format(b.reason)
            for old_blocked_room in old_blocking.blockedRooms:
                br = BlockedRoom(
                    state=state_map[old_blocked_room.active],
                    rejected_by=old_blocked_room.rejectedBy,
                    rejection_reason=convert_to_unicode(
                        old_blocked_room.rejectionReason),
                )
                room = Room.get(get_room_id(old_blocked_room.roomGUID))
                room.blocked_rooms.append(br)
                b.blocked_rooms.append(br)
                print cformat(u'  %{blue!}Room:%{reset} {} ({})').format(
                    room.full_name,
                    BlockedRoom.State(br.state).title)

            for old_principal in old_blocking.allowed:
                principal_id = old_principal._id
                if old_principal._type == 'Avatar':
                    principal_id = int(
                        self.merged_avatars.get(old_principal._id,
                                                old_principal._id))
                    principal_type = 'User'
                else:
                    principal_type = 'Group'
                bp = BlockingPrincipal(
                    _principal=[principal_type, principal_id])
                b._allowed.add(bp)
                print cformat(u'  %{blue!}Allowed:%{reset} {}({})').format(
                    bp.entity_type, bp.entity_id)
            db.session.add(b)
        db.session.commit()
Example #12
0
 def _save(self):
     self._blocking = blocking = Blocking()
     blocking.start_date = self._form.start_date.data
     blocking.end_date = self._form.end_date.data
     blocking.created_by_user = session.user
     blocking.reason = self._form.reason.data
     blocking.allowed = [
         BlockingPrincipal(entity_type=item['_type'], entity_id=item['id'])
         for item in self._form.principals.data
     ]
     blocking.blocked_rooms = [
         BlockedRoom(room_id=room_id)
         for room_id in self._form.blocked_rooms.data
     ]
     db.session.add(blocking)
     db.session.flush(
     )  # synchronizes relationships (e.g. BlockedRoom.room)
     flash(_(u'Blocking created'), 'success')
     self._process_blocked_rooms(blocking.blocked_rooms)
Example #13
0
def test_approve_acl(db, create_user, create_reservation, create_blocking,
                     smtp, in_acl, rejected):
    user = create_user(u'user')
    blocking = create_blocking(start_date=date.today(),
                               end_date=date.today() + timedelta(days=1))
    if in_acl:
        blocking.allowed.append(
            BlockingPrincipal(entity_type=u'Avatar', entity_id=user.id))
        db.session.flush()
    br = blocking.blocked_rooms[0]
    resv = create_reservation(start_dt=datetime.combine(
        blocking.start_date, time(8)),
                              end_dt=datetime.combine(blocking.start_date,
                                                      time(10)),
                              created_by_user=user,
                              booked_for_user=user)
    assert br.state == BlockedRoom.State.pending
    br.approve(notify_blocker=False)
    assert br.state == BlockedRoom.State.accepted
    assert resv.is_rejected == rejected
    assert len(smtp.outbox) == (2 if rejected else 0)
Example #14
0
class Blocking(db.Model):
    __tablename__ = 'blockings'
    __table_args__ = {'schema': 'roombooking'}

    id = db.Column(db.Integer, primary_key=True)
    created_by_id = db.Column(db.Integer,
                              db.ForeignKey('users.users.id'),
                              index=True,
                              nullable=False)
    created_dt = db.Column(UTCDateTime, nullable=False, default=now_utc)
    start_date = db.Column(db.Date, nullable=False, index=True)
    end_date = db.Column(db.Date, nullable=False, index=True)
    reason = db.Column(db.Text, nullable=False)

    _allowed = db.relationship('BlockingPrincipal',
                               backref='blocking',
                               cascade='all, delete-orphan',
                               collection_class=set)
    allowed = association_proxy(
        '_allowed',
        'principal',
        creator=lambda v: BlockingPrincipal(principal=v))
    blocked_rooms = db.relationship('BlockedRoom',
                                    backref='blocking',
                                    cascade='all, delete-orphan')
    #: The user who created this blocking.
    created_by_user = db.relationship('User',
                                      lazy=False,
                                      backref=db.backref('blockings',
                                                         lazy='dynamic'))

    @hybrid_method
    def is_active_at(self, d):
        return self.start_date <= d <= self.end_date

    @is_active_at.expression
    def is_active_at(self, d):
        return (self.start_date <= d) & (d <= self.end_date)

    def can_edit(self, user, allow_admin=True):
        if not user:
            return False
        return user == self.created_by_user or (allow_admin
                                                and rb_is_admin(user))

    def can_delete(self, user, allow_admin=True):
        if not user:
            return False
        return user == self.created_by_user or (allow_admin
                                                and rb_is_admin(user))

    def can_override(self,
                     user,
                     room=None,
                     explicit_only=False,
                     allow_admin=True):
        """Check if a user can override the blocking

        The following persons are authorized to override a blocking:
        - the creator of the blocking
        - anyone on the blocking's ACL
        - unless explicit_only is set: rb admins and room managers (if a room is given)
        """
        if not user:
            return False
        if self.created_by_user == user:
            return True
        if not explicit_only:
            if allow_admin and rb_is_admin(user):
                return True
            if room and room.can_manage(user):
                return True
        return any(user in principal for principal in iter_acl(self.allowed))

    @property
    def external_details_url(self):
        return url_for('rb.blocking_link', blocking_id=self.id, _external=True)

    @return_ascii
    def __repr__(self):
        return format_repr(self,
                           'id',
                           'start_date',
                           'end_date',
                           _text=self.reason)
Example #15
0
class Blocking(db.Model):
    __tablename__ = 'blockings'
    __table_args__ = {'schema': 'roombooking'}

    id = db.Column(db.Integer, primary_key=True)
    created_by_id = db.Column(db.String, nullable=False)
    created_dt = db.Column(UTCDateTime, nullable=False, default=now_utc)
    start_date = db.Column(db.Date, nullable=False, index=True)
    end_date = db.Column(db.Date, nullable=False, index=True)
    reason = db.Column(db.Text, nullable=False)

    _allowed = db.relationship('BlockingPrincipal',
                               backref='blocking',
                               cascade='all, delete-orphan',
                               collection_class=set)
    allowed = association_proxy(
        '_allowed',
        'principal',
        creator=lambda v: BlockingPrincipal(principal=v))
    blocked_rooms = db.relationship('BlockedRoom',
                                    backref='blocking',
                                    cascade='all, delete-orphan')

    @hybrid_method
    def is_active_at(self, d):
        return self.start_date <= d <= self.end_date

    @is_active_at.expression
    def is_active_at(self, d):
        return (self.start_date <= d) & (d <= self.end_date)

    @property
    def created_by_user(self):
        return User.get(self.created_by_id).as_avatar

    @created_by_user.setter
    def created_by_user(self, user):
        self.created_by_id = user.id

    def can_be_modified(self, user):
        """
        The following persons are authorized to modify a blocking:
        - owner (the one who created the blocking)
        - admin (of course)
        """
        if not user:
            return False
        return user == self.created_by_user or user.isRBAdmin()

    def can_be_deleted(self, user):
        return self.can_be_modified(user)

    def can_be_overridden(self, user, room=None, explicit_only=False):
        """Determines if a user can override the blocking

        The following persons are authorized to override a blocking:
        - owner (the one who created the blocking)
        - any users on the blocking's ACL
        - unless explicitOnly is set: admins and room owners (if a room is given)
        """
        if not user:
            return False
        if self.created_by_user == user:
            return True
        if not explicit_only:
            if user.isRBAdmin():
                return True
            elif room and room.is_owned_by(user):
                return True
        for principal in self._allowed:
            if principal.entity.containsUser(user):
                return True
        return False

    @return_ascii
    def __repr__(self):
        return u'<Blocking({0}, {1}, {2}, {3}, {4})>'.format(
            self.id, self.created_by_id, self.reason, self.start_date,
            self.end_date)
def test_entity_group(dummy_group):
    principal = BlockingPrincipal(principal=dummy_group)
    assert principal.entity == dummy_group.as_legacy_group
    assert principal.entity_name == 'Group'
def test_entity_user(dummy_user):
    principal = BlockingPrincipal(principal=dummy_user.user)
    assert principal.entity == dummy_user
    assert principal.entity_name == 'User'
Example #18
0
class Blocking(db.Model):
    __tablename__ = 'blockings'
    __table_args__ = {'schema': 'roombooking'}

    id = db.Column(db.Integer, primary_key=True)
    created_by_id = db.Column(db.Integer,
                              db.ForeignKey('users.users.id'),
                              index=True,
                              nullable=False)
    created_dt = db.Column(UTCDateTime, nullable=False, default=now_utc)
    start_date = db.Column(db.Date, nullable=False, index=True)
    end_date = db.Column(db.Date, nullable=False, index=True)
    reason = db.Column(db.Text, nullable=False)

    _allowed = db.relationship('BlockingPrincipal',
                               backref='blocking',
                               cascade='all, delete-orphan',
                               collection_class=set)
    allowed = association_proxy(
        '_allowed',
        'principal',
        creator=lambda v: BlockingPrincipal(principal=v))
    blocked_rooms = db.relationship('BlockedRoom',
                                    backref='blocking',
                                    cascade='all, delete-orphan')
    #: The user who created this blocking.
    created_by_user = db.relationship('User',
                                      lazy=False,
                                      backref=db.backref('blockings',
                                                         lazy='dynamic'))

    @hybrid_method
    def is_active_at(self, d):
        return self.start_date <= d <= self.end_date

    @is_active_at.expression
    def is_active_at(self, d):
        return (self.start_date <= d) & (d <= self.end_date)

    def can_be_modified(self, user):
        """
        The following persons are authorized to modify a blocking:
        - owner (the one who created the blocking)
        - admin (of course)
        """
        return user and (user == self.created_by_user or rb_is_admin(user))

    def can_be_deleted(self, user):
        return self.can_be_modified(user)

    def can_be_overridden(self, user, room=None, explicit_only=False):
        """Determines if a user can override the blocking

        The following persons are authorized to override a blocking:
        - owner (the one who created the blocking)
        - any users on the blocking's ACL
        - unless explicitOnly is set: admins and room owners (if a room is given)
        """
        if not user:
            return False
        if self.created_by_user == user:
            return True
        if not explicit_only:
            if rb_is_admin(user):
                return True
            elif room and room.is_owned_by(user):
                return True
        return any(user in principal for principal in iter_acl(self.allowed))

    @return_ascii
    def __repr__(self):
        return '<Blocking({0}, {1}, {2}, {3}, {4})>'.format(
            self.id, self.created_by_user, self.reason, self.start_date,
            self.end_date)