Example #1
0
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)
Example #2
0
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)
Example #3
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
Example #4
0
    def post(self, user_id):
        parser = reqparse.RequestParser()
        parser.add_argument('use_cache', dest='use_cache', type=inputs.boolean,
                            required=True)
        args = parser.parse_args()

        user = get_user_or_404(user_id)
        if args.use_cache != user.member_of(config.cache_group):
            if args.use_cache:
                make_member_of(user, config.cache_group, user)
            else:
                remove_member_of(user, config.cache_group, user)
        session.session.commit()
        return "Cache usage has been changed."
Example #5
0
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
Example #6
0
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
Example #7
0
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
Example #8
0
def create_user(name, login, email, birthdate, groups, processor, address):
    """Create a new member

    Create a new user with a generated password, finance- and unix account, and make him member
    of the `config.member_group` and `config.network_access_group`.

    :param str name: The full name of the user (e.g. Max Mustermann)
    :param str login: The unix login for the user
    :param str email: E-Mail address of the user
    :param Date birthdate: Date of birth
    :param PropertyGroup groups: The initial groups of the new user
    :param User processor: The processor
    :param Address address: Where the user lives. May or may not come from a room.
    :return:
    """

    now = session.utcnow()
    plain_password = user_helper.generate_password(12)
    # create a new user
    new_user = User(
        login=login,
        name=name,
        email=email,
        registered_at=now,
        account=Account(name="", type="USER_ASSET"),
        password=plain_password,
        birthdate=birthdate,
        address=address
    )

    account = UnixAccount(home_directory="/home/{}".format(login))
    new_user.unix_account = account

    with session.session.begin(subtransactions=True):
        session.session.add(new_user)
        session.session.add(account)
    new_user.account.name = deferred_gettext(u"User {id}").format(
        id=new_user.id).to_json()

    for group in groups:
        make_member_of(new_user, group, processor, closed(now, None))

    log_user_event(author=processor,
                   message=deferred_gettext(u"User created.").to_json(),
                   user=new_user)

    return new_user, plain_password
Example #9
0
def take_actions_for_payment_in_default_users(users_pid_membership,
                                              users_membership_terminated,
                                              processor):
    ts_now = session.utcnow()

    for user in users_pid_membership:
        if not user.member_of(config.payment_in_default_group):
            make_member_of(user, config.payment_in_default_group,
                           processor, closed(ts_now, None))

    from pycroft.lib.user import move_out

    for user in users_membership_terminated:
        if user.member_of(config.member_group):
            move_out(user, "Zahlungsrückstand", processor, ts_now - timedelta(seconds=1), True)

            log_user_event("Mitgliedschaftsende wegen Zahlungsrückstand.",
                           processor, user)
Example #10
0
def setup_traffic_group(user, processor, custom_group_id=None, terminate_other=False):
    """Add a user to a default or custom traffic group

    If neither a custom group is given, nor the corresponding building
    has a default traffic group, no membership is added.  Group
    removal is executed independent of the latter.

    :param User user: the user
    :param User processor: the processor
    :param int custom_group_id: the id of a custom traffic group.  if
        ``None``, the traffic group of the building is used.
    :param bool terminate_other: Whether to terminate current
        :py:cls:`TrafficGroup` memberships.  Defaults to ``False``
    """
    now = session.utcnow()
    if terminate_other:
        for group in user.traffic_groups:
            remove_member_of(user, group, processor, closedopen(now, None))
    traffic_group = determine_traffic_group(user, custom_group_id)
    if traffic_group is not None:
        make_member_of(user, traffic_group, processor, closedopen(now, None))
Example #11
0
def move_in(user, building_id, level, room_number, mac, processor, birthdate=None,
            host_annex=False, begin_membership=True, when=None):
    """Move in a user in a given room and do some initialization.

    The user is given a new Host with an interface of the given mac, a
    UnixAccount, a finance Account, and is made member of important
    groups.  Networking is set up.

    :param User user: The user to move in
    :param int building_id:
    :param int level:
    :param str room_number:
    :param str mac: The mac address of the users pc.
    :param User processor:
    :param Date birthdate: Date of birth`
    :param bool host_annex: when true: if MAC already in use,
        annex host to new user
    :param bool begin_membership: Starts a membership if true
    :param datetime when: The date at which the user should be moved in

    :return: The user object.
    """

    if when and when > session.utcnow():
        return schedule_user_task(task_type=TaskType.USER_MOVE_IN,
                                  due=when,
                                  user=user,
                                  parameters={'building_id': building_id,
                                              'level': level,
                                              'room_number': room_number,
                                              'mac': mac,
                                              'birthdate': birthdate,
                                              'host_annex': host_annex,
                                              'begin_membership': begin_membership},
                                  processor=processor)
    else:
        room = get_room(building_id, level, room_number)

        if birthdate:
            user.birthdate = birthdate

        if begin_membership:
            if user.member_of(config.external_group):
                remove_member_of(user, config.external_group, processor,
                                 closedopen(session.utcnow(), None))

            for group in {config.member_group, config.network_access_group}:
                if not user.member_of(group):
                    make_member_of(user, group, processor, closed(session.utcnow(), None))

        if room:
            user.room = room
            user.address = room.address

            if mac and user.birthdate:
                interface_existing = Interface.q.filter_by(mac=mac).first()

                if interface_existing is not None:
                    if host_annex:
                        host_existing = interface_existing.host
                        host_existing.owner_id = user.id

                        session.session.add(host_existing)
                        migrate_user_host(host_existing, user.room, processor)
                    else:
                        raise MacExistsException
                else:
                    new_host = Host(owner=user, room=room)
                    session.session.add(new_host)
                    session.session.add(Interface(mac=mac, host=new_host))
                    setup_ipv4_networking(new_host)

        msg = deferred_gettext(u"Moved in: {room}")

        log_user_event(author=processor,
                       message=msg.format(room=room.short_name).to_json(),
                       user=user)

        return user
Example #12
0
def create_user(name,
                login,
                email,
                birthdate,
                groups,
                processor,
                address,
                passwd_hash=None,
                send_confirm_mail: bool = False):
    """Create a new member

    Create a new user with a generated password, finance- and unix account, and make him member
    of the `config.member_group` and `config.network_access_group`.

    :param str name: The full name of the user (e.g. Max Mustermann)
    :param str login: The unix login for the user
    :param str email: E-Mail address of the user
    :param Date birthdate: Date of birth
    :param PropertyGroup groups: The initial groups of the new user
    :param Optional[User] processor: The processor
    :param Address address: Where the user lives. May or may not come from a room.
    :param passwd_hash: Use password hash instead of generating a new password
    :param send_confirm_mail: If a confirmation mail should be send to the user
    :return:
    """

    now = session.utcnow()
    plain_password = user_helper.generate_password(12)
    # create a new user
    new_user = User(login=login,
                    name=name,
                    email=email,
                    registered_at=now,
                    account=Account(name="", type="USER_ASSET"),
                    password=plain_password,
                    wifi_password=generate_wifi_password(),
                    birthdate=birthdate,
                    address=address)

    processor = processor if processor is not None else new_user

    if passwd_hash:
        new_user.passwd_hash = passwd_hash
        plain_password = None

    account = UnixAccount(home_directory="/home/{}".format(login))
    new_user.unix_account = account

    with session.session.begin(subtransactions=True):
        session.session.add(new_user)
        session.session.add(account)
    new_user.account.name = deferred_gettext(u"User {id}").format(
        id=new_user.id).to_json()

    for group in groups:
        make_member_of(new_user, group, processor, closed(now, None))

    log_user_event(author=processor,
                   message=deferred_gettext(u"User created.").to_json(),
                   user=new_user)

    user_send_mail(new_user, UserCreatedTemplate(), True)

    if email is not None and send_confirm_mail:
        send_confirmation_email(new_user)

    return new_user, plain_password
Example #13
0
def merge_member_request(user: User, prm: PreMember, merge_name: bool,
                         merge_email: bool, merge_person_id: bool,
                         merge_room: bool, merge_password: bool,
                         merge_birthdate: bool, processor: User):
    if prm.move_in_date is not None and prm.move_in_date < session.utcnow(
    ).date():
        prm.move_in_date = session.utcnow().date()

    if merge_name:
        user = edit_name(user, prm.name, processor)

    if merge_email:
        user = edit_email(user,
                          prm.email,
                          user.email_forwarded,
                          processor,
                          is_confirmed=prm.email_confirmed)

    if merge_person_id:
        user = edit_person_id(user, prm.swdd_person_id, processor)

    move_in_datetime = datetime.combine(prm.move_in_date, utc.time_min())

    if merge_room:
        if prm.room:
            if user.room:
                move(user,
                     prm.room.building_id,
                     prm.room.level,
                     prm.room.number,
                     processor=processor,
                     when=move_in_datetime)
            else:
                move_in(user,
                        prm.room.building_id,
                        prm.room.level,
                        prm.room.number,
                        mac=None,
                        processor=processor,
                        when=move_in_datetime)

    if not user.member_of(config.member_group):
        make_member_of(user, config.member_group, processor,
                       closed(move_in_datetime, None))

    if merge_birthdate:
        user = edit_birthdate(user, prm.birthdate, processor)

    log_msg = "Merged information from registration {}."

    if merge_password:
        user.passwd_hash = prm.passwd_hash

        log_msg += " Password overridden."
    else:
        log_msg += " Kept old password."

    log_user_event(
        deferred_gettext(log_msg).format(encode_type2_user_id(
            prm.id)).to_json(), processor, user)

    session.session.delete(prm)
Example #14
0
def move_in(user: User,
            building_id: int,
            level: int,
            room_number: str,
            mac: str | None,
            processor: User | None = None,
            birthdate: date = None,
            host_annex: bool = False,
            begin_membership: bool = True,
            when: datetime | None = None):
    """Move in a user in a given room and do some initialization.

    The user is given a new Host with an interface of the given mac, a
    UnixAccount, a finance Account, and is made member of important
    groups.  Networking is set up.

    :param User user: The user to move in
    :param building_id:
    :param level:
    :param room_number:
    :param mac: The mac address of the users pc.
    :param processor:
    :param birthdate: Date of birth`
    :param host_annex: when true: if MAC already in use,
        annex host to new user
    :param begin_membership: Starts a membership if true
    :param when: The date at which the user should be moved in

    :return: The user object.
    """

    if when and when > session.utcnow():
        task_params = UserMoveInParams(building_id=building_id,
                                       level=level,
                                       room_number=room_number,
                                       mac=mac,
                                       birthdate=birthdate,
                                       host_annex=host_annex,
                                       begin_membership=begin_membership)
        return schedule_user_task(task_type=TaskType.USER_MOVE_IN,
                                  due=when,
                                  user=user,
                                  parameters=task_params,
                                  processor=processor)
    if user.room is not None:
        raise ValueError("user is already living in a room.")

    room = get_room(building_id, level, room_number)

    if birthdate:
        user.birthdate = birthdate

    if begin_membership:
        for group in {config.external_group, config.pre_member_group}:
            if user.member_of(group):
                remove_member_of(user, group, processor,
                                 closedopen(session.utcnow(), None))

        for group in {config.member_group, config.network_access_group}:
            if not user.member_of(group):
                make_member_of(user, group, processor,
                               closed(session.utcnow(), None))

    if room:
        user.room = room
        user.address = room.address

        if mac and user.birthdate:
            interface_existing = Interface.q.filter_by(mac=mac).first()

            if interface_existing is not None:
                if host_annex:
                    host_existing = interface_existing.host
                    host_existing.owner_id = user.id

                    session.session.add(host_existing)
                    migrate_user_host(host_existing, user.room, processor)
                else:
                    raise MacExistsException
            else:
                new_host = Host(owner=user, room=room)
                session.session.add(new_host)
                session.session.add(Interface(mac=mac, host=new_host))
                setup_ipv4_networking(new_host)

    user_send_mail(user, UserMovedInTemplate(), True)

    msg = deferred_gettext("Moved in: {room}")

    log_user_event(author=processor if processor is not None else user,
                   message=msg.format(room=room.short_name).to_json(),
                   user=user)

    return user
Example #15
0
File: user.py Project: JuKu/pycroft
def move_in(user,
            building,
            level,
            room_number,
            mac,
            processor,
            birthdate=None,
            traffic_group_id=None,
            host_annex=False,
            begin_membership=True):
    """Create a new user in a given room and do some initialization.

    The user is given a new Host with an interface of the given mac, a
    UnixAccount, a finance Account, and is made member of important
    groups.  Networking is set up.

    :param User user: The user to move in
    :param Building building: See :py:func:`create_member`
    :param int level: See :py:func:`create_member`
    :param str room_number: See :py:func:`create_member`
    :param str mac: The mac address of the users pc.
    :param User processor: See :py:func:`create_member
    :param Date birthdate: Date of birth`
    :param int traffic_group_id: the id of the chosen traffic group to
        be used instead of the building's default one.
    :param bool host_annex: when true: if MAC already in use,
        annex host to new user
    :param bool begin_membership: Starts a membership if true
    :return: The user object.
    """

    room = Room.q.filter_by(number=room_number, level=level,
                            building=building).one()

    user.room = room

    if birthdate:
        user.birthdate = birthdate

    if begin_membership:
        if user.member_of(config.external_group):
            remove_member_of(user, config.external_group, processor,
                             closedopen(session.utcnow(), None))

        for group in {config.member_group, config.network_access_group}:
            if not user.member_of(group):
                make_member_of(user, group, processor,
                               closed(session.utcnow(), None))

    interface_existing = Interface.q.filter_by(mac=mac).first()

    if interface_existing is not None:
        if host_annex:
            host_existing = interface_existing.host
            host_existing.owner_id = user.id

            session.session.add(host_existing)
            migrate_user_host(host_existing, user.room, processor)
        else:
            raise MacExistsException
    else:
        new_host = Host(owner=user, room=room)
        session.session.add(new_host)
        session.session.add(Interface(mac=mac, host=new_host))
        setup_ipv4_networking(new_host)

    setup_traffic_group(user, processor, traffic_group_id)
    try:
        grant_initial_credit(user)
    except NoTrafficGroup as e:
        raise ValueError("User {} could not be assigned a traffic group. "
                         "Please specify one manually.".format(user)) from e

    msg = deferred_gettext(u"Moved in: {dorm} {level}-{room}")

    log_user_event(author=processor,
                   message=msg.format(dorm=building.short_name,
                                      level=level,
                                      room=room_number).to_json(),
                   user=user)

    return user
Example #16
0
 def add_membership(self, during):
     make_member_of(self.user, self.group, self.processor, during)
     session.session.commit()
Example #17
0
 def add_membership(self, during):
     make_member_of(self.user, self.group, self.processor, during)
     session.session.commit()