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)
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)
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)
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)
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
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)
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)
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)
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)
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)
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()
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)
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)
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)
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'
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)