Example #1
0
def test_diff_fields_check_mismatch(dummy_user_dict, dummy_group_dict):
    """ Check we cannot diff two different objects"""
    user = User(dummy_user_dict)
    group = Group(dummy_group_dict)

    with pytest.raises(ValueError):
        user.diff_fields(group)
Example #2
0
def group(ipa, groupname):
    group = Group(group_or_404(ipa, groupname))
    sponsor_form = AddGroupMemberForm(groupname=groupname)
    remove_form = RemoveGroupMemberForm(groupname=groupname)

    members = [User(u) for u in ipa.user_find(in_group=groupname)['result']]

    batch_methods = [
        {"method": "user_find", "params": [[], {"uid": sponsorname, 'all': True}]}
        for sponsorname in group.sponsors
    ]
    sponsors = [
        User(u['result'][0]) for u in ipa.batch(methods=batch_methods)['results']
    ]

    # We can safely assume g.current_user exists after @with_ipa
    current_user_is_sponsor = g.current_user.username in group.sponsors

    return render_template(
        'group.html',
        group=group,
        members=members,
        sponsors=sponsors,
        sponsor_form=sponsor_form,
        remove_form=remove_form,
        current_user_is_sponsor=current_user_is_sponsor,
    )
Example #3
0
def user(ipa, username):
    user = User(user_or_404(ipa, username))
    # As a speed optimization, we make two separate calls.
    # Just doing a group_find (with all=True) is super slow here, with a lot of
    # groups.
    member_groups = [
        Group(group) for group in ipa.group_find(
            o_user=username, o_all=False, fasgroup=True)['result']
    ]
    managed_groups = [
        Group(group) for group in ipa.group_find(o_membermanager_user=username,
                                                 o_all=False,
                                                 fasgroup=True)['result']
    ]
    groups = [group for group in managed_groups if group not in member_groups
              ] + member_groups
    # Privacy setting
    if user != g.current_user and user.is_private:
        user.anonymize()

    return render_template(
        'user.html',
        user=user,
        groups=groups,
        managed_groups=managed_groups,
        member_groups=member_groups,
    )
Example #4
0
def test_spamcheck(client, dummy_stageuser, mocker, spamcheck_status,
                   spamcheck_on):
    user = User(ipa_admin.stageuser_show("dummy")["result"])
    assert user.status_note != spamcheck_status
    token = make_token({"sub": "dummy"}, audience=Audience.spam_check)
    with mailer.record_messages() as outbox:
        response = client.post(
            "/register/spamcheck-hook",
            json={
                "token": token,
                "status": spamcheck_status
            },
        )
    assert response.status_code == 200
    assert response.json == {"status": "success"}
    # Check that the status was changed
    user = User(ipa_admin.stageuser_show("dummy")["result"])
    assert user.status_note == spamcheck_status
    # Sent email
    if spamcheck_status == "active":
        assert len(outbox) == 1
        message = outbox[0]
        assert message.subject == "Verify your email address"
        assert message.recipients == ["*****@*****.**"]
    else:
        assert len(outbox) == 0
Example #5
0
def test_diff_fields(dummy_user_dict):
    """ Check the method to compare the diff between two User objects works"""
    user = User(dummy_user_dict)

    new_data = dummy_user_dict.copy()
    new_data["fasgithubusername"] = ["newusername"]
    changed_user = User(new_data)

    diff = user.diff_fields(changed_user)
    assert diff == ['github']
Example #6
0
def user_settings_profile(ipa, username):
    user = User(user_or_404(ipa, username))
    form = UserSettingsProfileForm(obj=user)

    if form.validate_on_submit():
        result = _user_mod(
            ipa,
            form,
            user,
            {
                'first_name': form.firstname.data,
                'last_name': form.lastname.data,
                'full_name': '%s %s' %
                (form.firstname.data, form.lastname.data),
                'display_name': '%s %s' %
                (form.firstname.data, form.lastname.data),
                'mail': form.mail.data,
                'fasircnick': form.ircnick.data,
                'faslocale': form.locale.data,
                'fastimezone': form.timezone.data,
                'fasgithubusername': form.github.data.lstrip('@'),
                'fasgitlabusername': form.gitlab.data.lstrip('@'),
                'fasrhbzemail': form.rhbz_mail.data,
                'faswebsiteurl': form.website_url.data,
            },
            "user_settings_profile",
        )
        if result:
            return result

    return render_template('user-settings-profile.html',
                           user=user,
                           form=form,
                           activetab="profile")
Example #7
0
def search_json(ipa):
    username = request.args.get('username')
    groupname = request.args.get('group')

    res = []

    if username:
        users_ = [
            User(u) for u in ipa.user_find(
                username, fasuser=True, sizelimit=10)['result']
        ]

        for user_ in users_:
            res.append({
                'uid': user_.username,
                'cn': user_.name,
                'url': url_for(".user", username=user_.username),
            })

    if groupname:
        groups_ = [
            Group(g) for g in ipa.group_find(
                groupname, fasgroup=True, sizelimit=10)['result']
        ]
        for group_ in groups_:
            res.append({
                'cn': group_.name,
                'description': group_.description,
                'url': url_for(".group", groupname=group_.name),
            })

    return jsonify(res)
Example #8
0
def confirm_registration():
    username = request.args.get('username')
    if not username:
        abort(400, "No username provided")
    try:
        user = User(ipa_admin.stageuser_show(a_uid=username)['result'])
    except python_freeipa.exceptions.NotFound:
        flash(_("The registration seems to have failed, please try again."),
              "warning")
        return redirect(f"{url_for('.root')}?tab=register")

    if current_app.config["BASSET_URL"] and user.status_note != "active":
        abort(401, "You should not be here")

    form = ResendValidationEmailForm()
    if form.validate_on_submit():
        _send_validation_email(user)
        flash(
            _('The address validation email has be sent again. Make sure it did not land in '
              'your spam folder'),
            'success',
        )
        return redirect(request.url)

    return render_template('registration-confirmation.html',
                           user=user,
                           form=form)
Example #9
0
def test_user_no_displayname_no_gcos_no_cn(dummy_user_dict):
    """Test that we fallback to cn if there is no displayname nor gcos"""
    del dummy_user_dict["displayname"]
    del dummy_user_dict["gecos"]
    del dummy_user_dict["cn"]
    user = User(dummy_user_dict)
    assert user.name is None
Example #10
0
def user_settings_keys(ipa, username):
    user = User(user_or_404(ipa, username))
    form = UserSettingsKeysForm(obj=user)

    if form.validate_on_submit():
        result = _user_mod(
            ipa,
            form,
            user,
            {
                'ipasshpubkey': form.sshpubkeys.data,
                'fasgpgkeyid': form.gpgkeys.data
            },
            "user_settings_keys",
        )
        if result:
            return result

    # if the form has errors, we don't want to add new fields. otherwise,
    # more fields will show up with every validation error
    if not form.errors:
        # Append 2 empty entries at the bottom of the gpgkeys fieldlist
        for i in range(2):
            form.gpgkeys.append_entry()
            form.sshpubkeys.append_entry()

    return render_template('user-settings-keys.html',
                           user=user,
                           form=form,
                           activetab="keys")
Example #11
0
def _user_mod(ipa, form, user, details, redirect_to):
    with handle_form_errors(form):
        try:
            updated_user = User(
                ipa.user_mod(user.username, **details, all=True))
        except python_freeipa.exceptions.BadRequest as e:
            if e.message == 'no modifications to be performed':
                raise FormError("non_field_errors", e.message)
            else:
                app.logger.error(
                    f'An error happened while editing user {user.username}: {e.message}'
                )
                raise FormError("non_field_errors", e.message)
        flash(
            Markup(
                f'Profile Updated: <a href=\"{url_for("user", username=user.username)}\">'
                'view your profile</a>'),
            'success',
        )

        messaging.publish(
            UserUpdateV1({
                "msg": {
                    "agent": user.username,
                    "user": user.username,
                    "fields": user.diff_fields(updated_user),
                }
            }))

        return redirect(url_for(redirect_to, username=user.username))
Example #12
0
def spamcheck_hook():
    if not current_app.config.get("BASSET_URL"):
        return jsonify({"error": "Spamcheck disabled"}), 501

    data = request.get_json()
    if not data:
        return jsonify({"error": "Bad payload"}), 400

    try:
        token = data["token"]
        status = data["status"]
    except KeyError as e:
        return jsonify({"error": f"Missing key: {e}"}), 400

    try:
        token_data = read_token(token, audience=Audience.spam_check)
    except jwt.ExpiredSignatureError:
        return jsonify({"error": "The token has expired"}), 400
    except jwt.InvalidTokenError as e:
        return jsonify({"error": f"Invalid token: {e}"}), 400

    username = token_data["sub"]

    if status not in ("active", "spamcheck_denied", "spamcheck_manual"):
        return jsonify({"error": f"Invalid status: {status}."}), 400
    result = ipa_admin.stageuser_mod(a_uid=username, fasstatusnote=status)
    user = User(result["result"])

    if status == "active":
        # Send the address validation email
        _send_validation_email(user)

    return jsonify({"status": "success"})
Example #13
0
 def fn(*args, **kwargs):
     ipa = maybe_ipa_session(app, session)
     if ipa:
         g.ipa = ipa
         g.current_user = User(g.ipa.user_find(whoami=True)['result'][0])
         return f(*args, **kwargs, ipa=ipa)
     flash('Please log in to continue.', 'warning')
     return redirect(url_for('root'))
Example #14
0
def forgot_password_ask():
    form = ForgottenPasswordForm()
    if form.validate_on_submit():
        username = form.username.data
        lock = PasswordResetLock(username)
        valid_until = lock.valid_until()
        now = datetime.datetime.now()
        with handle_form_errors(form):
            if valid_until is not None and now < valid_until:
                wait_min = int((valid_until - now).total_seconds() / 60)
                wait_sec = int((valid_until - now).total_seconds() % 60)
                raise FormError(
                    "non_field_errors",
                    _(
                        'You have already requested a password reset, you need to wait '
                        '%(wait_min)s minute(s) and %(wait_sec)s seconds before you can request '
                        'another.',
                        wait_min=wait_min,
                        wait_sec=wait_sec,
                    ),
                )
            try:
                user = User(ipa_admin.user_show(username))
            except python_freeipa.exceptions.NotFound:
                raise FormError(
                    "username",
                    _("User %(username)s does not exist", username=username))
            token = PasswordResetToken.from_user(user).as_string()
            # Send the email
            email_context = {"token": token, "username": username}
            email = Message(
                body=render_template("forgot-password-email.txt",
                                     **email_context),
                html=render_template("forgot-password-email.html",
                                     **email_context),
                recipients=[user.mail],
                subject="Password reset procedure",
            )
            try:
                mailer.send(email)
            except ConnectionRefusedError as e:
                app.logger.error(
                    f"Impossible to send a password reset email: {e}")
                flash(_("We could not send you an email, please retry later"),
                      "danger")
                return redirect(url_for('root'))
            if app.config["DEBUG"]:  # pragma: no cover
                app.logger.debug(email)
            lock.store()
            app.logger.info(
                f'{username} forgot their password and requested a token')
            flash(
                _('An email has been sent to your address with instructions on how to reset '
                  'your password'),
                "success",
            )
            return redirect(url_for('root'))
    return render_template('forgot-password-ask.html', form=form)
Example #15
0
def test_strip(client, post_data_step_1, cleanup_dummy_user, field_name):
    """Register a user with fields that contain trailing spaces"""
    post_data_step_1[f"register-{field_name}"] = "Dummy "
    with mailer.record_messages() as outbox:
        result = client.post('/', data=post_data_step_1)
    assert result.status_code == 302, str(result.data, "utf8")
    user = User(ipa_admin.stageuser_show(a_uid="dummy")['result'])
    assert getattr(user, field_name) == "Dummy"
    assert len(outbox) == 1
Example #16
0
def token_for_dummy_user(dummy_user):
    user = User(ipa_admin.user_show("dummy")["result"])
    return make_token(
        {
            "sub": user.username,
            "lpc": user.last_password_change
        },
        audience=Audience.password_reset,
    )
Example #17
0
 def fn(*args, **kwargs):
     ipa = maybe_ipa_session(current_app, session)
     if ipa:
         g.ipa = ipa
         g.current_user = User(g.ipa.user_find(whoami=True)['result'][0])
         return f(*args, **kwargs, ipa=ipa)
     coming_from = quote(request.full_path)
     flash('Please log in to continue.', 'warning')
     return redirect(f"{url_for('.root')}?next={coming_from}")
Example #18
0
def test_signal_basset(client, mocker, dummy_user):
    mocked_requests = mocker.patch("noggin.signals.requests")
    mocker.patch.dict(current_app.config, {"BASSET_URL": "http://basset.test"})
    user = User(ipa_admin.user_show("dummy")["result"])
    with current_app.test_request_context('/'):
        request_basset_check(user)
    call_args = mocked_requests.post.call_args_list[0]
    assert list(call_args[0]) == ["http://basset.test"]
    json_data = call_args[1]["json"]
    assert json_data["action"] == "fedora.noggin.registration"
    expected_dict = user.as_dict()
    expected_dict["human_name"] = user.commonname
    expected_dict["email"] = user.mail
    assert json_data["data"]["user"] == expected_dict
    assert json_data["data"]["request_headers"] == {"Host": "localhost"}
    assert json_data["data"]["callback"] == "http://localhost/register/spamcheck-hook"
    token = json_data["data"]["token"]
    token_data = read_token(token, audience=Audience.spam_check)
    assert token_data["sub"] == "dummy"
Example #19
0
def test_gecos(client, post_data_non_ascii, cleanup_dummy_user, mocker):
    record_signal = mocker.Mock()
    with mailer.record_messages() as _, stageuser_created.connected_to(
            record_signal):
        result = client.post('/', data=post_data_non_ascii)
    assert result.status_code == 302

    # Check that default values are added
    user = User(ipa_admin.stageuser_show("dummy")['result'])

    assert user.gecos == "Xi Jin Ping aeoeue ss AeOeUe Ss An Bei Jin San"
Example #20
0
def user(ipa, username):
    user = User(user_or_404(ipa, username))
    # As a speed optimization, we make two separate calls.
    # Just doing a group_find (with all=True) is super slow here, with a lot of
    # groups.
    batch_methods = [{
        "method": "group_show",
        "params": [[name], {
            "no_members": True
        }]
    } for name in user.groups]
    # Don't call remote batch method with an empty list
    if batch_methods:
        member_groups = [
            Group(g["result"]) for g in ipa.batch(batch_methods)["results"]
            if g["result"].get("fasgroup", False)
        ]
    else:
        member_groups = []

    managed_groups = [
        Group(group) for group in ipa.group_find(o_membermanager_user=username,
                                                 o_all=False,
                                                 fasgroup=True)['result']
    ]
    groups = sorted(list(set(managed_groups + member_groups)),
                    key=lambda g: g.name)

    # Privacy setting
    if user != g.current_user and user.is_private:
        user.anonymize()

    return render_template(
        'user.html',
        user=user,
        groups=groups,
        managed_groups=managed_groups,
        member_groups=member_groups,
    )
Example #21
0
def user_settings_otp(ipa, username):
    addotpform = UserSettingsAddOTPForm()
    user = User(user_or_404(ipa, username))
    if addotpform.validate_on_submit():
        try:
            maybe_ipa_login(current_app, session, username,
                            addotpform.password.data)
            result = ipa.otptoken_add(
                o_ipatokenowner=username,
                o_ipatokenotpalgorithm='sha512',
                o_description=addotpform.description.data,
            )['result']

            uri = urlparse(result['uri'])

            # Use the provided description in the token, so it shows up in the user's app instead of
            # the token's UUID
            principal = uri.path.split(":", 1)[0]
            new_uri = uri._replace(
                path=f"{principal.lower()}:{quote(addotpform.description.data)}"
            )
            session['otp_uri'] = new_uri.geturl()
        except python_freeipa.exceptions.InvalidSessionPassword:
            addotpform.password.errors.append(_("Incorrect password"))
        except python_freeipa.exceptions.FreeIPAError as e:
            current_app.logger.error(
                f'An error happened while creating an OTP token for user {username}: {e.message}'
            )
            addotpform.non_field_errors.errors.append(
                _('Cannot create the token.'))
        else:
            return redirect(url_for('.user_settings_otp', username=username))

    otp_uri = session.get('otp_uri')
    session['otp_uri'] = None

    tokens = [
        OTPToken(t)
        for t in ipa.otptoken_find(o_ipatokenowner=username)["result"]
    ]
    tokens.sort(key=lambda t: t.description or "")

    return render_template(
        'user-settings-otp.html',
        addotpform=addotpform,
        user=user,
        activetab="otp",
        tokens=tokens,
        otp_uri=otp_uri,
    )
Example #22
0
def dummy_stageuser(ipa_testing_config):
    now = datetime.datetime.utcnow().replace(microsecond=0)
    user = ipa_admin.stageuser_add(
        "dummy",
        "Dummy",
        'User',
        mail="*****@*****.**",
        login_shell='/bin/bash',
        fascreationtime=f"{now.isoformat()}Z",
    )
    yield User(user)
    try:
        ipa_admin.stageuser_del("dummy")
    except python_freeipa.exceptions.NotFound:
        pass
Example #23
0
def handle_register_form(form):
    username = form.username.data
    now = datetime.datetime.utcnow().replace(microsecond=0)
    common_name = form.firstname.data + " " + form.lastname.data
    gecos = (unidecode(codecs.encode(common_name,
                                     "translit/long")).replace("  ",
                                                               " ").strip())
    # First, create the stage user.
    try:
        user = ipa_admin.stageuser_add(
            a_uid=username,
            o_givenname=form.firstname.data,
            o_sn=form.lastname.data,
            o_cn=common_name,
            o_mail=form.mail.data,
            o_loginshell='/bin/bash',
            o_gecos=gecos,
            fascreationtime=f"{now.isoformat()}Z",
            faslocale=guess_locale(),
            fastimezone=current_app.config["USER_DEFAULTS"]["timezone"],
            fasstatusnote=current_app.config["USER_DEFAULTS"]["status_note"],
        )['result']
        user = User(user)
    except python_freeipa.exceptions.DuplicateEntry:
        raise FormError(
            "username",
            _("This username is already taken, please choose another one."))
    except python_freeipa.exceptions.ValidationError as e:
        # for example: invalid username. We don't know which field to link it to
        _handle_registration_validation_error(username, e)
    except python_freeipa.exceptions.FreeIPAError as e:
        current_app.logger.error(
            f'An unhandled error {e.__class__.__name__} happened while registering user '
            f'{username}: {e.message}')
        raise FormError(
            "non_field_errors",
            _('An error occurred while creating the account, please try again.'
              ),
        )

    stageuser_created.send(user, request=request._get_current_object())
    if current_app.config["BASSET_URL"]:
        return redirect(f"{url_for('.spamcheck_wait')}?username={username}")
    else:
        # Send the address validation email
        _send_validation_email(user)
        return redirect(
            f"{url_for('.confirm_registration')}?username={username}")
Example #24
0
def test_signal_basset_failed(client, mocker, dummy_user):
    mocked_requests = mocker.patch("noggin.signals.requests")
    failure = requests.Response()
    failure.status_code = 500
    failure.reason = "Server Error"
    failure.raw = BytesIO(b"nope.")
    mocked_requests.post.return_value = failure
    mocker.patch.dict(current_app.config, {"BASSET_URL": "http://basset.test"})
    logger = mocker.patch.object(current_app._get_current_object(), "logger")
    user = User(ipa_admin.user_show("dummy"))
    with current_app.test_request_context('/'):
        request_basset_check(user)
    mocked_requests.post.assert_called()
    logger.warning.assert_called_with(
        "Error requesting a Basset check: 500 Server Error: nope."
    )
Example #25
0
def dummy_stageuser(ipa_testing_config):
    now = datetime.datetime.utcnow().replace(microsecond=0)
    user = ipa_admin.stageuser_add(
        a_uid="dummy",
        o_givenname="Dummy",
        o_sn="User",
        o_cn="Dummy User",
        o_mail="*****@*****.**",
        o_loginshell='/bin/bash',
        fascreationtime=f"{now.isoformat()}Z",
    )['result']
    yield User(user)
    try:
        ipa_admin.stageuser_del(a_uid="dummy")
    except python_freeipa.exceptions.NotFound:
        pass
Example #26
0
def user(ipa, username):
    user = User(user_or_404(ipa, username))
    # As a speed optimization, we make two separate calls.
    # Just doing a group_find (with all=True) is super slow here, with a lot of
    # groups.
    groups = [
        Group(g) for g in ipa.group_find(
            user=username, all=False, fasgroup=True)['result']
    ]
    managed_groups = [
        Group(g) for g in ipa.group_find(
            membermanager_user=username, all=False, fasgroup=True)['result']
    ]
    return render_template('user.html',
                           user=user,
                           groups=groups,
                           managed_groups=managed_groups)
Example #27
0
def spamcheck_wait():
    username = request.args.get('username')
    if not username:
        abort(400, "No username provided")

    try:
        user = User(ipa_admin.stageuser_show(a_uid=username)["result"])
    except python_freeipa.exceptions.NotFound:
        flash(_("The registration seems to have failed, please try again."),
              "warning")
        return redirect(f"{url_for('.root')}?tab=register")

    if user.status_note == "active":
        return redirect(
            f"{url_for('.confirm_registration')}?username={username}")

    return render_template('registration-spamcheck-wait.html', user=user)
Example #28
0
def search_json(ipa):
    username = request.args.get('username')
    groupname = request.args.get('group')

    res = []

    if username:
        users_ = [User(u) for u in ipa.user_find(username)['result']]

        for user_ in users_:
            res.append({'uid': user_.username, 'cn': user_.name})

    if groupname:
        groups_ = [Group(g) for g in ipa.group_find(groupname)['result']]
        for group_ in groups_:
            res.append({'cn': group_.name, 'description': group_.description})

    return jsonify(res)
Example #29
0
def user_settings_agreements(ipa, username):
    user = User(user_or_404(ipa, username))
    agreements = [
        Agreement(a)
        for a in ipa.fasagreement_find(all=False, ipaenabledflag=True)
    ]
    form = UserSettingsAgreementSign()
    if form.validate_on_submit():
        agreement_name = form.agreement.data
        if agreement_name not in [a.name for a in agreements]:
            flash(_("Unknown agreement: %(name)s.", name=agreement_name),
                  "warning")
            return redirect(
                url_for('.user_settings_agreements', username=username))
        try:
            ipa.fasagreement_add_user(agreement_name, user=user.username)
        except python_freeipa.exceptions.BadRequest as e:
            current_app.logger.error(
                f"Cannot sign the agreement {agreement_name!r}: {e}")
            flash(
                _(
                    'Cannot sign the agreement "%(name)s": %(error)s',
                    name=agreement_name,
                    error=e,
                ),
                'danger',
            )
        else:
            flash(
                _('You signed the "%(name)s" agreement.', name=agreement_name),
                "success",
            )
        return redirect(url_for('.user_settings_agreements',
                                username=username))

    return render_template(
        'user-settings-agreements.html',
        user=user,
        activetab="agreements",
        agreementslist=agreements,
        raw=ipa.fasagreement_find(all=True),
    )
Example #30
0
def test_user(dummy_user_dict):
    """Test the User representation"""
    user = User(dummy_user_dict)
    assert user.username == "dummy"
    assert user.firstname == "Dummy"
    assert user.lastname == "User"
    assert user.name == "Dummy User"
    assert user.mail == "*****@*****.**"
    assert user.sshpubkeys == [
        'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCtX/SK86GrOa0xUadeZVbDXCj6wseamJQTpvjzNdKLgIBuQnA2dnR+jBS54rxUzHD1In/yI9r1VXr+KVZG4ULHmSuP3Icl0SUiVs+u+qeHP77Fa9rnQaxxCFL7uZgDSGSgMx0XtiQUrcumlD/9mrahCefU0BIKfS6e9chWwJnDnPSpyWf0y0NpaGYqPaV6Ukg2Z5tBvei6ghBb0e9Tusg9dHGvpv2B23dCzps6s5WBYY2TqjTHAEuRe6xR0agtPUE1AZ/DvSBKgwEz6RXIFOtv/fnZ0tERh238+n2nohMZNo1QAtQ6I0U9Kx2gdAgHRaMN6GzmbThji/MLgKlIJPSh',  # noqa: E501
        'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDuxGxBwWH5xMLAuIUAVU3O8ZViYWW64V3tJRob+eZngeR95PzUDeH0UlZ58bPyucpMowZNgJucsHyUjqal5bctv9Q5r224Of1R3DJqIViE16W3zncGNjbgiuc66wcO2o84HEm2Zi+v4cwU8ykM0m9zeG0257aVW4/L/fDAyR55NRJ7zLIyRmGMcjkN6j02wbGK89xXJKHMtRKa5Kg4GJx3HUae79C3B7SyoRAuyzLT6GmpMZ3XRa/khZ3t4xfUtSMV6DuvR5KJ9Wg5B20ecua1tNXOLHC3dU5L+P6Pb7+HL1sxHiYbaiBPJbosMkM2wqd3VyduQDQTO4BJyly/ruIN',  # noqa: E501
    ]
    assert user.timezone == "UTC"
    assert user.locale == "en-US"
    assert user.ircnick == ["dummy", "dummy_"]
    assert user.gpgkeys == ["key1", "key2"]
    assert user.groups == ["ipausers"]
    assert user.github == "dummy"
    assert user.gitlab == "dummy"
    assert user.rhbz_mail == "*****@*****.**"