예제 #1
0
파일: __init__.py 프로젝트: JuKu/pycroft
def user_show_groups_json(user_id, group_filter="all"):
    memberships = Membership.q.filter(Membership.user_id == user_id)
    if group_filter == "active":
        memberships = memberships.filter(
            # it is important to use == here, "is" does NOT work
            or_(Membership.begins_at == None,
                Membership.begins_at <= session.utcnow())
        ).filter(
            # it is important to use == here, "is" does NOT work
            or_(Membership.ends_at == None,
                Membership.ends_at > session.utcnow())
        )

    return jsonify(items=[{
            'group_name': membership.group.name,
            'begins_at': (datetime_filter(membership.begins_at)
                          if membership.begins_at is not None else ''),
            'ends_at': (datetime_filter(membership.ends_at)
                        if membership.ends_at is not None else ''),
            'actions': [{'href': url_for(".edit_membership",
                                        user_id=user_id,
                                        membership_id=membership.id),
                        'title': 'Bearbeiten',
                        'icon': 'glyphicon-edit'},
                        {'href': url_for(".end_membership",
                                         user_id=user_id,
                                         membership_id=membership.id),
                         'title': "Beenden",
                         'icon': 'glyphicon-off'} if membership.active() else {}],
        } for membership in memberships.all()])
예제 #2
0
def json_trafficdata(user_id, days=7):
    """Generate a JSON file to use with traffic and credit graphs.

    :param user_id:
    :param days: optional amount of days to be included
    :return: JSON with traffic and credit data formatted according to the following schema
    {
        "type": "object",
        "properties": {
            "items": {
                "type": "object",
                "properties": {
                    "traffic": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "egress": { "type": "integer" },
                                "ingress": { "type": "integer" },
                                "timestamp": { "type": "string" }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    """
    interval = timedelta(days=days)
    result = traffic_history(user_id,
                             session.utcnow() - interval + timedelta(days=1),
                             session.utcnow())

    return jsonify(items={'traffic': [e.__dict__ for e in result]})
예제 #3
0
def check_new_user_data(login: str,
                        email: str,
                        name: str,
                        swdd_person_id: Optional[int],
                        room: Optional[Room],
                        move_in_date: Optional[date],
                        ignore_similar_name: bool = False,
                        allow_existing: bool = False):
    user_swdd_person_id = get_user_by_swdd_person_id(swdd_person_id)

    if user_swdd_person_id and not allow_existing:
        raise UserExistsException

    user_login = User.q.filter_by(login=login).first()

    if user_login is not None and not allow_existing:
        raise LoginTakenException

    user_email = User.q.filter_by(email=email).first()

    if user_email is not None and not allow_existing:
        raise EmailTakenException

    if room is not None and not ignore_similar_name:
        check_similar_user_in_room(name, room)

    if move_in_date is not None:
        if move_in_date > (session.utcnow() + timedelta(days=180)
                           ).date() or move_in_date < session.utcnow().date():
            raise MoveInDateInvalidException
예제 #4
0
    def test_free_membership(self):
        self.user_membership.begins_at = session.utcnow().replace(
            day=self.membership_fee_current.booking_end.days + 1)

        end_date = last_day_of_month(session.utcnow().date())

        self.assertEquals(0.00, estimate_balance(self.user, end_date))
예제 #5
0
파일: traffic.py 프로젝트: agdsn/pycroft
def sync_exceeded_traffic_limits():
    """Adds and removes memberships of the 'traffic_limit_exceeded group.'

    """

    processor = User.q.get(0)

    # Add memberships
    users = User.q.join(User._current_traffic_balance) \
                  .filter(CurrentTrafficBalance.amount < 0) \
                  .except_(User.q.join(User.current_properties)\
                  .filter(or_(CurrentProperty.property_name == 'traffic_limit_disabled',\
                              CurrentProperty.property_name == 'traffic_limit_exceeded')))\
                  .all()

    for user in users:
        make_member_of(user, config.traffic_limit_exceeded_group,
                       processor, closed(session.utcnow(), None))
        print("Traffic-Limit exceeded: " + user.name)

    # End memberships
    users = User.q.join(User.current_properties) \
                  .filter(CurrentProperty.property_name == 'traffic_limit_exceeded') \
                  .join(User._current_traffic_balance) \
                  .filter(or_(CurrentTrafficBalance.amount >= 0,
                              CurrentProperty.property_name == 'traffic_limit_disabled')) \
                  .all()

    for user in users:
        remove_member_of(user, config.traffic_limit_exceeded_group,
                         processor, closed(session.utcnow(), None))
        print("Traffic-Limit no longer exceeded: " + user.name)
예제 #6
0
파일: test_user.py 프로젝트: agdsn/pycroft
 def test_active_memberships(self):
     self.assertEqual(self.user.active_memberships(), [])
     m = self.add_membership(self.property_group)
     self.assertEqual(self.user.active_memberships(), [m])
     when = single(session.utcnow() - timedelta(hours=1))
     self.assertEqual(self.user.active_memberships(when), [])
     when = single(session.utcnow() + timedelta(hours=1))
     self.assertEqual(self.user.active_memberships(when), [m])
예제 #7
0
 def test_active_memberships(self):
     self.assertEqual(self.user.active_memberships(), [])
     m = self.add_membership(self.property_group)
     self.assertEqual(self.user.active_memberships(), [m])
     when = single(session.utcnow() - timedelta(hours=1))
     self.assertEqual(self.user.active_memberships(when), [])
     when = single(session.utcnow() + timedelta(hours=1))
     self.assertEqual(self.user.active_memberships(when), [m])
예제 #8
0
 def test_active_traffic_groups(self):
     self.assertEqual(self.user.active_traffic_groups(), [])
     self.add_membership(self.traffic_group)
     self.assertEqual(self.user.active_traffic_groups(),
                      [self.traffic_group])
     when = single(session.utcnow() - timedelta(hours=1))
     self.assertEqual(self.user.active_traffic_groups(when), [])
     when = single(session.utcnow() + timedelta(hours=1))
     self.assertEqual(self.user.active_traffic_groups(when),
                      [self.traffic_group])
예제 #9
0
파일: test_user.py 프로젝트: agdsn/pycroft
 def test_active_traffic_groups(self):
     self.assertEqual(self.user.active_traffic_groups(), [])
     self.add_membership(self.traffic_group)
     self.assertEqual(self.user.active_traffic_groups(),
                      [self.traffic_group])
     when = single(session.utcnow() - timedelta(hours=1))
     self.assertEqual(self.user.active_traffic_groups(when), [])
     when = single(session.utcnow() + timedelta(hours=1))
     self.assertEqual(self.user.active_traffic_groups(when),
                      [self.traffic_group])
예제 #10
0
파일: test_user.py 프로젝트: agdsn/pycroft
 def test_active_traffic_groups_expression(self):
     query = self.create_active_traffic_groups_query()
     self.assertEqual(query.all(), [])
     self.add_membership(self.traffic_group)
     query = self.create_active_traffic_groups_query()
     self.assertEqual(query.all(), [self.traffic_group])
     when = single(session.utcnow() - timedelta(hours=1))
     query = self.create_active_traffic_groups_query(when)
     self.assertEqual(query.all(), [])
     when = single(session.utcnow() + timedelta(hours=1))
     query = self.create_active_traffic_groups_query(when)
     self.assertEqual(query.all(), [self.traffic_group])
예제 #11
0
 def test_active_property_groups_expression(self):
     query = self.create_active_property_groups_query()
     self.assertEqual(query.all(), [])
     self.add_membership(self.property_group)
     query = self.create_active_property_groups_query()
     self.assertEqual(query.all(), [self.property_group])
     when = single(session.utcnow() - timedelta(hours=1))
     query = self.create_active_property_groups_query(when)
     self.assertEqual(query.all(), [])
     when = single(session.utcnow() + timedelta(hours=1))
     query = self.create_active_property_groups_query(when)
     self.assertEqual(query.all(), [self.property_group])
예제 #12
0
class MembershipFeeFactory(BaseFactory):
    class Meta:
        model = MembershipFee

    name = Faker('word')
    regular_fee = 5.00
    booking_begin = timedelta(3)
    booking_end = timedelta(14)
    payment_deadline = timedelta(14)
    payment_deadline_final = timedelta(62)
    begins_on = LazyAttribute(lambda o: session.utcnow().date().replace(day=1))
    ends_on = LazyAttribute(lambda o: last_day_of_month(session.utcnow()))
예제 #13
0
    def test_set_correct_dates(self):
        # add membership to group1
        p1 = Membership(user=self.user, group=self.property_group1)
        p1.begins_at = session.utcnow()
        p1.ends_at = session.utcnow()

        session.session.add(p1)
        session.session.commit()

        p1.begins_at = session.utcnow() - timedelta(days=3)
        p1.ends_at = session.utcnow() + timedelta(days=3)

        session.session.commit()
예제 #14
0
    def test_0040_set_correct_dates(self):
        # add membership to group1
        p1 = Membership(user=self.user, group=self.property_group1)
        p1.begins_at = session.utcnow()
        p1.ends_at = session.utcnow()

        session.session.add(p1)
        session.session.commit()

        p1.begins_at = session.utcnow() - timedelta(days=3)
        p1.ends_at = session.utcnow() + timedelta(days=3)

        session.session.commit()
예제 #15
0
파일: task.py 프로젝트: agdsn/pycroft
    def schedule(self, due, user, parameters, processor):
        if due < session.utcnow():
            raise ValueError("the due date must be in the future")

        task = UserTask(type=self.type,
                        due=due,
                        creator=processor,
                        created=session.utcnow(),
                        user=user)

        task.parameters = parameters

        return task
예제 #16
0
파일: task.py 프로젝트: agdsn/pycroft
def schedule_user_task(task_type, due, user, parameters: TaskParams,
                       processor):
    if due < session.utcnow():
        raise ValueError("the due date must be in the future")

    task = UserTask(type=task_type,
                    due=due,
                    creator=processor,
                    created=session.utcnow(),
                    user=user)

    task.parameters = parameters
    session.session.add(task)

    return task
예제 #17
0
    def create_factories(self):
        ConfigFactory.create()

        self.processor = UserFactory.create()

        self.last_month_last = session.utcnow().replace(day=1) - timedelta(1)
        self.last_month_last_date = self.last_month_last.date()

        self.membership_fee_last = MembershipFeeFactory.create(
            begins_on=self.last_month_last_date.replace(day=1),
            ends_on=self.last_month_last_date)

        payment_deadline = timedelta(14)
        payment_deadline_final = timedelta(62)

        no_pid_action_date = session.utcnow() - payment_deadline + timedelta(1)
        pid_state_date = no_pid_action_date - timedelta(1)
        pid_no_end_membership_date = session.utcnow(
        ) - payment_deadline_final + timedelta(1)
        pid_end_membership_date = pid_no_end_membership_date - timedelta(1)

        self.membership_fee_no_pid_action = MembershipFeeFactory.create(
            begins_on=no_pid_action_date,
            ends_on=no_pid_action_date,
            booking_begin=timedelta(1),
            booking_end=timedelta(1),
        )

        self.membership_fee_pid_state = MembershipFeeFactory.create(
            begins_on=pid_state_date,
            ends_on=pid_state_date,
            booking_begin=timedelta(1),
            booking_end=timedelta(1),
        )

        self.membership_fee_no_end_membership = MembershipFeeFactory.create(
            begins_on=pid_no_end_membership_date,
            ends_on=pid_no_end_membership_date,
            booking_begin=timedelta(1),
            booking_end=timedelta(1),
        )

        self.membership_fee_pid_end_membership = MembershipFeeFactory.create(
            begins_on=pid_end_membership_date,
            ends_on=pid_end_membership_date,
            booking_begin=timedelta(1),
            booking_end=timedelta(1),
        )
예제 #18
0
파일: user.py 프로젝트: agdsn/pycroft
def finish_member_request(prm: PreMember,
                          processor: User | None,
                          ignore_similar_name: bool = False):
    if prm.room is None:
        raise ValueError("Room is None")

    if prm.move_in_date is not None and prm.move_in_date < session.utcnow(
    ).date():
        prm.move_in_date = session.utcnow().date()

    check_new_user_data(prm.login, prm.email, prm.name, prm.swdd_person_id,
                        prm.room, prm.move_in_date, ignore_similar_name)

    user, _ = create_user(prm.name,
                          prm.login,
                          prm.email,
                          prm.birthdate,
                          groups=[],
                          processor=processor,
                          address=prm.room.address,
                          passwd_hash=prm.passwd_hash)

    processor = processor if processor is not None else user

    user.swdd_person_id = prm.swdd_person_id
    user.email_confirmed = prm.email_confirmed

    move_in_datetime = utc.with_min_time(prm.move_in_date)

    move_in(user,
            prm.room.building_id,
            prm.room.level,
            prm.room.number,
            None,
            processor if processor is not None else user,
            when=move_in_datetime)

    message = deferred_gettext("Created from registration {}.").format(
        str(prm.id)).to_json()
    log_user_event(message, processor, user)

    if move_in_datetime > session.utcnow():
        make_member_of(user, config.pre_member_group, processor,
                       closed(session.utcnow(), None))

    session.session.delete(prm)

    return user
예제 #19
0
def transaction_confirm_all(processor):
    # Confirm all transactions older than one hour that are not confirmed yet
    transactions = Transaction.q.filter_by(confirmed=False)\
        .filter(Transaction.posted_at < session.utcnow() - timedelta(hours=1))

    for transaction in transactions:
        transaction_confirm(transaction, processor)
예제 #20
0
    def test_adding_single_membership(self):
        begins_at = session.utcnow()
        ends_at = begins_at + timedelta(hours=1)
        during = closed(begins_at, ends_at)

        self.add_membership(during)
        self.assertMembershipIntervalsEqual(IntervalSet(during))
예제 #21
0
    def test_0030_add_timed_membership(self):
        # add membership to group1
        now = session.utcnow()
        membership = Membership(
            begins_at=now,
            user=self.user,
            group=self.property_group1
        )
        membership.ends_at = membership.begins_at + timedelta(days=3)
        session.session.add(membership)
        session.session.commit()

        self.assertTrue(self.user.has_property(PropertyData.prop_test1.name))
        self.assertFalse(self.user.has_property(PropertyData.prop_test2.name))

        # add expired membership to group2
        membership = Membership(
            begins_at=now - timedelta(hours=2),
            user=self.user,
            group=self.property_group2
        )
        membership.ends_at = now - timedelta(hours=1)
        session.session.add(membership)
        session.session.commit()

        self.assertTrue(self.user.has_property(PropertyData.prop_test1.name))
        self.assertFalse(self.user.has_property(PropertyData.prop_test2.name))
예제 #22
0
파일: user.py 프로젝트: JuKu/pycroft
def unblock(user, processor, when=None):
    """Unblocks a user.

    This removes his membership of the ``config.violation`` group.

    Note that for unblocking, no further asynchronous action has to be
    triggered, as opposed to e.g. membership termination.

    :param User user: The user to be unblocked.
    :param User processor: The admin who unblocked the user.
    :param datetime when: The time of membership termination.  Note
        that in comparison to :py:func:`suspend`, you don't provide an
        _interval_, but a point in time, defaulting to the current
        time.  Will be converted to ``closedopen(when, None)``.

    :return: The unblocked user.
    """
    if when is None:
        when = session.utcnow()

    remove_member_of(user=user,
                     group=config.violation_group,
                     processor=processor,
                     during=closedopen(when, None))
    message = deferred_gettext(u"User has been unblocked.")
    log_user_event(message=message.to_json(), author=processor, user=user)
    return user
예제 #23
0
파일: task.py 프로젝트: FriwiDev/pycroft
def execute_scheduled_tasks():
    tasks = (session.session.query(with_polymorphic(Task, "*"))
             .filter(Task.status == TaskStatus.OPEN,
                     Task.due <= session.utcnow())
             .all())

    print("executing {} scheduled tasks".format(len(tasks)))

    for task in tasks:
        repair_session()

        task_impl = task_type_to_impl.get(task.type)()

        try:
            task_impl.execute(task)
        except Exception as e:
            task_impl.errors.append(str(e))

        repair_session()

        if task_impl.new_status is not None:
            task.status = task_impl.new_status

        if task_impl.errors:
            task.errors = task_impl.errors

            for error in task.errors:
                print("Error while executing task: {}".format(error))

        write_task_message(task, "Processed {} task. Status: {}".format(
            task.type.name, task.status.name), log=True)

        session.session.commit()
예제 #24
0
    def test_adding_single_membership(self):
        begins_at = session.utcnow()
        ends_at = begins_at + timedelta(hours=1)
        during = closed(begins_at, ends_at)

        self.add_membership(during)
        self.assertMembershipIntervalsEqual(IntervalSet(during))
예제 #25
0
def unblock(user, processor, when=None):
    """Unblocks a user.

    This removes his membership of the violation, blocken and payment_in_default
    group.

    Note that for unblocking, no further asynchronous action has to be
    triggered, as opposed to e.g. membership termination.

    :param User user: The user to be unblocked.
    :param User processor: The admin who unblocked the user.
    :param datetime when: The time of membership termination.  Note
        that in comparison to :py:func:`suspend`, you don't provide an
        _interval_, but a point in time, defaulting to the current
        time.  Will be converted to ``closedopen(when, None)``.

    :return: The unblocked user.
    """
    if when is None:
        when = session.utcnow()

    for group in get_blocked_groups():
        if user.member_of(group):
            remove_member_of(user=user, group=group,
                             processor=processor, during=closedopen(when, None))

    return user
예제 #26
0
def timesince_filter(dt, default="just now"):
    """
    Returns string representing "time since" e.g.
    3 days ago, 5 hours ago etc.

    adopted from
    http://flask.pocoo.org/snippets/33/
    """
    if dt is None:
        return "k/A"

    now = session.utcnow()
    diff = now - dt

    periods = (
        (diff.days / 365, "Jahr", "Jahre"),
        (diff.days / 30, "Monat", "Monate"),
        (diff.days / 7, "Woche", "Wochen"),
        (diff.days, "Tag", "Tage"),
        (diff.seconds / 3600, "Stunde", "Stunden"),
        (diff.seconds / 60, "Minute", "Minuten"),
        (diff.seconds, "Sekunde", "Sekunden"),
    )

    for period, singular, plural in periods:

        if period:
            return "vor {:d} {}".format(period, singular if period == 1 else plural)

    return default
예제 #27
0
def remove_old_traffic_data():
    TrafficVolume.q.filter(
        TrafficVolume.timestamp < (session.utcnow() - timedelta(7))).delete()

    session.session.commit()

    print("Deleted old traffic data")
예제 #28
0
def block(user, reason, processor, during=None, violation=True):
    """Suspend a user during a given interval.

    The user is added to violation_group or blocked_group in a given
    interval.  A reason needs to be provided.

    :param User user: The user to be suspended.
    :param unicode reason: The reason for suspending.
    :param User processor: The admin who suspended the user.
    :param Interval|None during: The interval in which the user is
        suspended.  If None the user will be suspendeded from now on
        without an upper bound.
    :param Boolean violation: If the user should be added to the violation group

    :return: The suspended user.
    """
    if during is None:
        during = closedopen(session.utcnow(), None)

    if violation:
        make_member_of(user, config.violation_group, processor, during)
    else:
        make_member_of(user, config.blocked_group, processor, during)

    message = deferred_gettext(u"Suspended during {during}. Reason: {reason}.")
    log_user_event(message=message.format(during=during, reason=reason)
                   .to_json(), author=processor, user=user)
    return user
예제 #29
0
def timesince_filter(dt, default="just now"):
    """
    Returns string representing "time since" e.g.
    3 days ago, 5 hours ago etc.

    adopted from
    http://flask.pocoo.org/snippets/33/
    """
    if dt is None:
        return "k/A"

    now = session.utcnow()
    diff = now - dt

    periods = (
        (diff.days / 365, "Jahr", "Jahre"),
        (diff.days / 30, "Monat", "Monate"),
        (diff.days / 7, "Woche", "Wochen"),
        (diff.days, "Tag", "Tage"),
        (diff.seconds / 3600, "Stunde", "Stunden"),
        (diff.seconds / 60, "Minute", "Minuten"),
        (diff.seconds, "Sekunde", "Sekunden"),
    )

    for period, singular, plural in periods:

        if period:
            return f"vor {period:d} {singular if period == 1 else plural}"

    return default
예제 #30
0
파일: __init__.py 프로젝트: JuKu/pycroft
def add_membership(user_id):
    user = get_user_or_404(user_id)
    form = UserAddGroupMembership()

    if form.validate_on_submit():
        if form.begins_at.data is not None:
            begins_at = datetime.combine(form.begins_at.data, utc.time_min())
        else:
            begins_at = session.utcnow()
        if not form.ends_at.unlimited.data:
            ends_at = datetime.combine(form.ends_at.date.data, utc.time_min())
        else:
            ends_at = None
        make_member_of(user, form.group.data, current_user,
                       closed(begins_at, ends_at))
        message = u"Nutzer zur Gruppe '{}' hinzugefügt.".format(form.group.data.name)
        lib.logging.log_user_event(message, current_user, user)
        session.session.commit()
        flash(u'Nutzer wurde der Gruppe hinzugefügt.', 'success')

        return redirect(url_for(".user_show",
                                user_id=user_id,
                                _anchor='groups'))

    return render_template('user/add_membership.html',
        page_title=u"Neue Gruppenmitgliedschaft für Nutzer {}".format(user_id),
        user_id=user_id, form=form)
예제 #31
0
    def create_factories(self):
        ConfigFactory.create()

        self.user = UserFactory.create()

        self.user_membership = MembershipFactory.create(
            active_during=closedopen(session.utcnow() - timedelta(weeks=52),
                                     None),
            user=self.user,
            group=config.member_group)

        last_month_last = session.utcnow().date().replace(day=1) - timedelta(1)

        self.membership_fee_current = MembershipFeeFactory.create()
        self.membership_fee_last = MembershipFeeFactory.create(
            begins_on=last_month_last.replace(day=1), ends_on=last_month_last)
예제 #32
0
파일: user.py 프로젝트: agdsn/pycroft
    def traffic_for_days(self, days):
        from pycroft.model.traffic import TrafficVolume

        return select(func.sum(TrafficVolume.amount).label('amount')) \
            .where(
            TrafficVolume.timestamp >= (session.utcnow() - timedelta(days-1)).date()
            .where(TrafficVolume.user_id == self.id))
예제 #33
0
    def test_0040_disable_membership(self):
        # add membership to group1
        membership = Membership(
            begins_at=session.utcnow() - timedelta(hours=2),
            user=self.user,
            group=self.property_group1
        )
        session.session.add(membership)
        session.session.commit()

        self.assertTrue(self.user.has_property(PropertyData.prop_test1.name))
        membership.disable(session.utcnow() - timedelta(hours=1))
        session.session.commit()
        self.assertNotIn(
            self.property_group1,
            self.user.active_property_groups()
        )
        self.assertFalse(self.user.has_property(PropertyData.prop_test1.name))

        # add membership to group1
        membership = Membership(
            begins_at=session.utcnow(),
            user=self.user,
            group=self.property_group1
        )
        session.session.add(membership)
        session.session.commit()

        self.assertTrue(self.user.has_property(PropertyData.prop_test1.name))

        # add membership to group2
        membership = Membership(
            begins_at=session.utcnow() - timedelta(hours=2),
            user=self.user,
            group=self.property_group2
        )
        session.session.add(membership)
        session.session.commit()

        self.assertTrue(self.user.has_property(PropertyData.prop_test1.name))
        self.assertTrue(self.user.has_property(PropertyData.prop_test2.name))

        # disables membership in group2
        membership.disable(session.utcnow() - timedelta(hours=1))
        session.session.commit()
        self.assertTrue(self.user.has_property(PropertyData.prop_test1.name))
        self.assertFalse(self.user.has_property(PropertyData.prop_test2.name))
예제 #34
0
파일: user.py 프로젝트: JuKu/pycroft
 def active_memberships(self, when=None):
     if when is None:
         now = session.utcnow()
         when = single(now)
     return [
         m for m in self.memberships
         if when.overlaps(closed(m.begins_at, m.ends_at))
     ]
예제 #35
0
    def test_0010_group_users(self):
        self.assertEqual(len(self.property_group1.users), 0)
        self.assertEqual(len(self.property_group1.active_users()), 0)

        # add membership to group1
        p1 = Membership(begins_at=session.utcnow() - timedelta(hours=2),
                        user=self.user, group=self.property_group1)
        session.session.add(p1)
        session.session.commit()

        self.assertEqual(len(self.property_group1.users), 1)
        self.assertEqual(len(self.property_group1.active_users()), 1)

        p1.disable(session.utcnow() - timedelta(hours=1))
        session.session.commit()
        self.assertEqual(len(self.property_group1.users), 1)
        self.assertEqual(len(self.property_group1.active_users()), 0)
예제 #36
0
    def create_user_from1y(self, **kwargs):
        reg_date = session.utcnow() - timedelta(weeks=52)

        return UserWithMembershipFactory(registered_at=reg_date,
                                         membership__active_during=closedopen(
                                             reg_date, None),
                                         membership__group=config.member_group,
                                         **kwargs)
예제 #37
0
파일: user.py 프로젝트: LukasGibeh/pycroft
    def traffic_for_days(self, days):
        from pycroft.model.traffic import TrafficVolume

        return sum(
            v.amount
            for v in TrafficVolume.q.filter_by(user_id=self.id).filter(
                TrafficVolume.timestamp >= (session.utcnow() -
                                            timedelta(days - 1)).date()))
예제 #38
0
 def test_0030_start_date_after_end(self):
     # add membership to group1
     now = session.utcnow()
     self.assertRaisesRegexp(
         AssertionError,
         "begins_at must be before ends_at",
         Membership, user=self.user, group=self.property_group1,
         begins_at=now + timedelta(days=1), ends_at=now
     )
예제 #39
0
    def test_join_overlapping_memberships(self):
        begins_at1 = session.utcnow()
        ends_at1 = begins_at1 + timedelta(hours=2)
        during1 = closed(begins_at1, ends_at1)
        begins_at2 = begins_at1 + timedelta(hours=1)
        ends_at2 = begins_at1 + timedelta(hours=3)
        during2 = closed(begins_at2, ends_at2)

        self.add_membership(during1)
        self.add_membership(during2)
        self.assertMembershipIntervalsEqual(IntervalSet(closed(begins_at1, ends_at2)))
예제 #40
0
    def test_removing_all_memberships(self):
        begins_at1 = session.utcnow()
        ends_at1 = begins_at1 + timedelta(hours=1)
        during1 = closed(begins_at1, ends_at1)
        begins_at2 = begins_at1 + timedelta(hours=2)
        ends_at2 = begins_at1 + timedelta(hours=3)
        during2 = closed(begins_at2, ends_at2)

        self.add_membership(during1)
        self.add_membership(during2)
        self.remove_membership()
        self.assertMembershipIntervalsEqual(IntervalSet())
예제 #41
0
파일: finance.py 프로젝트: agdsn/pycroft
def end_payment_in_default_memberships():
    processor = User.q.get(0)

    users = User.q.join(User.current_properties) \
                .filter(CurrentProperty.property_name == 'payment_in_default') \
                .join(Account).filter(Account.balance <= 0).all()

    for user in users:
        remove_member_of(user, config.payment_in_default_group, processor,
                             closedopen(session.utcnow(), None))

    return users
예제 #42
0
 def test_removing_memberships(self):
     t0 = session.utcnow()
     t1 = t0 + timedelta(hours=1)
     t2 = t0 + timedelta(hours=2)
     t3 = t0 + timedelta(hours=3)
     t4 = t0 + timedelta(hours=4)
     t5 = t0 + timedelta(hours=5)
     self.add_membership(closed(t0, t2))
     self.add_membership(closed(t3, t5))
     self.remove_membership(closed(t1, t4))
     self.assertMembershipIntervalsEqual(IntervalSet(
         (closed(t0, t1), closed(t4, t5))))
예제 #43
0
파일: __init__.py 프로젝트: agdsn/pycroft
def generate_user_data(user):
    try:
        traffic_maxmium = effective_traffic_group(user).credit_limit
    except NoTrafficGroup:
        traffic_maxmium = None

    props = {prop.property_name for prop in user.current_properties}
    user_status = status(user)

    interval = timedelta(days=7)
    step = timedelta(days=1)
    traffic_history = func_traffic_history(user.id,
                                          session.utcnow() - interval + step,
                                          interval, step)

    finance_history = [{
        'valid_on': split.transaction.posted_at,
        'amount': split.amount,
        'description': split.transaction.description
    } for split in build_transactions_query(user.account)]
    last_finance_update = finance_history[-1]['valid_on'] if finance_history \
        else None

    return jsonify(
        id=user.id,
        user_id=encode_type2_user_id(user.id),
        name=user.name,
        login=user.login,
        status={
            'member': user_status.member,
            'traffic_exceeded': user_status.traffic_exceeded,
            'network_access': user_status.network_access,
            'account_balanced': user_status.account_balanced,
            'violation': user_status.violation
        },
        room=str(user.room),
        interfaces=[
            {'mac': str(i.mac), 'ips': [str(ip.address) for ip in i.ips]}
            for h in user.hosts for i in h.interfaces
        ],
        mail=user.email,
        cache='cache_access' in props,
        # TODO: make `has_property` use `current_property`
        properties=list(props),
        traffic_balance=user.current_credit,
        traffic_maximum=traffic_maxmium,
        traffic_history=[e.__dict__ for e in traffic_history],
        # TODO: think about better way for credit
        finance_balance=-user.account.balance,
        finance_history=finance_history,
        last_finance_update=last_finance_update
    )
예제 #44
0
    def test_0050_clear_end_date(self):
        # add membership to group1
        p1 = Membership(user=self.user, group=self.property_group1)
        p1.begins_at = session.utcnow()
        p1.ends_at = session.utcnow()
        session.session.add(p1)
        session.session.commit()

        # test if membership in database
        p1 = Membership.q.filter_by(
            user=self.user, group=self.property_group1
        ).one()
        self.assertIsNotNone(p1.ends_at)

        # clear ends_at
        p1.ends_at = None
        session.session.commit()

        p1 = Membership.q.filter_by(
            user=self.user, group=self.property_group1
        ).one()
        self.assertIsNone(p1.ends_at)
예제 #45
0
파일: traffic.py 프로젝트: agdsn/pycroft
def grant_regular_credit(user):
    """Grant a user's regular credit

    The relevant :py:cls:`TrafficGroup` is the one with the largest
    ``credit_amount``.

    :param User user: the user to grant credit to
    """
    now = session.utcnow()
    group = effective_traffic_group(user)
    credit = TrafficCredit(timestamp=now, amount=group.credit_amount,
                           user_id=user.id)
    session.session.add(credit)
예제 #46
0
파일: user.py 프로젝트: agdsn/pycroft
 def has_property(self, property_name, when=None):
     """
     :param str property_name: name of a property
     :param Interval when:
     """
     if when is None:
         now = session.utcnow()
         when = single(now)
     prop_granted_flags = [
         group.property_grants[property_name]
         for group in self.active_property_groups(when)
         if property_name in group.property_grants
     ]
     return all(prop_granted_flags) and any(prop_granted_flags)
예제 #47
0
파일: finance.py 프로젝트: agdsn/pycroft
def handle_payments_in_default():
    processor = User.q.get(0)

    # Add memberships and end "member" membership if threshold met
    users = User.q.join(User.current_properties)\
                  .filter(CurrentProperty.property_name == 'membership_fee') \
                  .join(Account).filter(Account.balance > 0).all()

    users_pid_membership = []
    users_membership_terminated = []

    ts_now = session.utcnow()
    for user in users:
        last_pid_membership = Membership.q.filter(Membership.user_id == user.id) \
            .filter(Membership.group_id == config.payment_in_default_group.id) \
            .order_by(Membership.ends_at.desc()) \
            .first()

        if last_pid_membership is not None:
            if last_pid_membership.ends_at is not None and \
               last_pid_membership.ends_at >= ts_now - timedelta(days=7):
                continue

        in_default_days = user.account.in_default_days

        try:
            fee = get_membership_fee_for_date(
                date.today() - timedelta(days=in_default_days))
        except NoResultFound:
            fee = get_last_applied_membership_fee()

        if not fee:
            return [], []

        if not user.has_property('payment_in_default'):
            if in_default_days >= fee.payment_deadline.days:
                make_member_of(user, config.payment_in_default_group,
                               processor, closed(ts_now, None))
                users_pid_membership.append(user)

        if in_default_days >= fee.payment_deadline_final.days:
            remove_member_of(user, config.member_group, processor,
                             closedopen(ts_now, None))
            log_user_event("Mitgliedschaftsende wegen Zahlungsrückstand ({})"
                           .format(fee.name),
                           processor, user)
            users_membership_terminated.append(user)

    return users_pid_membership, users_membership_terminated
예제 #48
0
    def test_0020_add_membership(self):
        # add membership to group1
        membership = Membership(
            begins_at=session.utcnow(),
            user=self.user,
            group=self.property_group1
        )
        session.session.add(membership)
        session.session.commit()

        self.assertTrue(self.user.has_property(PropertyData.prop_test1.name))
        self.assertFalse(self.user.has_property(PropertyData.prop_test2.name))

        # add membership to group2
        membership = Membership(
            begins_at=session.utcnow(),
            user=self.user,
            group=self.property_group2
        )
        session.session.add(membership)
        session.session.commit()

        self.assertTrue(self.user.has_property(PropertyData.prop_test1.name))
        self.assertTrue(self.user.has_property(PropertyData.prop_test2.name))
예제 #49
0
    def test_0010_create_user_log_entry(self):
        user_log_entry = log_user_event(message=self.message,
                                        author=self.user,
                                        user=self.user)

        self.assertEqual(user_log_entry.message, self.message)
        self.assertAlmostEqual(user_log_entry.created_at, session.utcnow(),
                               delta=timedelta(seconds=5))
        self.assertEqual(user_log_entry.author, self.user)
        self.assertEqual(user_log_entry.user, self.user)

        self.assertIsNotNone(LogEntry.q.get(user_log_entry.id))
        session.session.delete(user_log_entry)
        session.session.commit()
        self.assertIsNone(LogEntry.q.get(user_log_entry.id))
예제 #50
0
    def test_0020_end_date_before_start(self):
        # add membership to group1
        p1 = Membership(user=self.user, group=self.property_group1)
        p1.begins_at = session.utcnow()

        def set_old_date():
            """ Set ends_at before begins_at
            """
            p1.ends_at = session.utcnow() - timedelta(hours=2)

        self.assertRaisesRegexp(
            AssertionError,
            "begins_at must be before ends_at",
            set_old_date
        )
예제 #51
0
파일: finance.py 프로젝트: agdsn/pycroft
def complex_transaction(description, author, splits, valid_on=None):
    if valid_on is None:
        valid_on = session.utcnow().date()
    objects = []
    new_transaction = Transaction(
        description=description,
        author=author,
        valid_on=valid_on
    )
    objects.append(new_transaction)
    objects.extend(
        Split(amount=amount, account=account, transaction=new_transaction)
        for (account, amount) in splits
    )
    session.session.add_all(objects)
    return new_transaction
예제 #52
0
파일: core.py 프로젝트: agdsn/pycroft
 def __init__(self, label=None, validators=None, format='%Y-%m-%d',
              **kwargs):
     # Move Bootstrap datepicker specific options to its own dict
     self.datepicker_options = dict((
         (option, value) for (option, value) in kwargs.items()
         if option in self.available_datepicker_options
     ))
     for option in self.datepicker_options.keys():
         kwargs.pop(option)
     defaults = {'default': session.utcnow(), 'language': 'de',
                 'today_highlight': 'true', 'today_btn': 'linked'}
     self.datepicker_options = dict(chain(defaults.items(),
                                          self.datepicker_options.items()))
     # The format option is used by both DateField and Bootstrap datepicker,
     # albeit with a different format string syntax.
     self.datepicker_options['format'] = self.convert_format_string(format)
     super(DateField, self).__init__(label, validators, format, **kwargs)
예제 #53
0
파일: user.py 프로젝트: agdsn/pycroft
    def active(cls, when=None):
        """
        Tests if memberships overlap with a given interval. If no interval is
        given, it tests if the memberships are active right now.
        :param Interval when:
        :return:
        """
        if when is None:
            now = session.utcnow()
            when = single(now)

        return and_(
            or_(cls.begins_at == null(), literal(when.end) == null(),
                cls.begins_at <= literal(when.end)),
            or_(literal(when.begin) == null(), cls.ends_at == null(),
                literal(when.begin) <= cls.ends_at)
        ).label("active")
예제 #54
0
파일: __init__.py 프로젝트: agdsn/pycroft
def json_trafficdata(user_id, days=7):
    """Generate a JSON file to use with traffic and credit graphs.

    :param user_id:
    :param days: optional amount of days to be included
    :return: JSON with traffic and credit data formatted according to the following schema
    {
        "type": "object",
        "properties": {
            "items": {
                "type": "object",
                "properties": {
                    "credit_limit": { "type": "integer" },
                    "traffic": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "balance": { "type": "integer" },
                                "credit": { "type": "integer" },
                                "egress": { "type": "integer" },
                                "ingress": { "type": "integer" },
                                "timestamp": { "type": "string" }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    """
    interval = timedelta(days=days)
    step = timedelta(days=1)
    result = traffic_history(user_id, session.utcnow() - interval + step, interval, step)

    credit_limit = session.session.execute(User.active_traffic_groups().where(
        User.id == user_id).with_only_columns(
        [func.max(TrafficGroup.credit_limit)])).scalar()

    return jsonify(
        items={
            'traffic': [e.__dict__ for e in result],
            'credit_limit': credit_limit
        }
    )
예제 #55
0
파일: test_user.py 프로젝트: agdsn/pycroft
    def test_deferred_blocking_and_unblocking_works(self):
        u = self.user_to_block

        blockage = session.utcnow() + timedelta(days=1)
        unblockage = blockage + timedelta(days=2)
        blocked_user = UserHelper.suspend(u, reason=u"test", processor=u,
                                          during=closedopen(blockage, None))
        session.session.commit()

        blocked_during = closedopen(blockage, unblockage)
        self.assertEqual(u.log_entries[0].author, blocked_user)
        self.assert_violation_membership(blocked_user, subinterval=blocked_during)

        unblocked_user = UserHelper.unblock(blocked_user, processor=u, when=unblockage)
        session.session.commit()

        self.assertEqual(unblocked_user.log_entries[0].author, unblocked_user)
        self.assert_violation_membership(unblocked_user, subinterval=blocked_during)