Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 9 additions & 27 deletions selfservice/blueprints/otp.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
"""

import logging
import pyotp

import pyotp
from flask import Blueprint, render_template, request, redirect, flash
from flask import session as flask_session


from selfservice import version, auth, OIDC_PROVIDER
from selfservice.utilities.app_passwd import delete_app_passwd
from selfservice.utilities.keycloak import (
OTPConfigError,
OTPInvalidCode,
Expand All @@ -18,9 +19,7 @@
register_kc_otp,
delete_kc_otp,
)
from selfservice.utilities.ldap import create_ipa_otp, has_ipa_otp, delete_ipa_otp
from selfservice.utilities.app_passwd import set_app_passwd, delete_app_passwd
from selfservice import version, auth, OIDC_PROVIDER
from selfservice.utilities.ldap import delete_ipa_otp

otp_bp = Blueprint("otp", __name__)

Expand All @@ -31,29 +30,17 @@
@auth.oidc_auth(OIDC_PROVIDER)
def enable():
"""
Creates a Keycloak OTP secret and then displays that to the user. Once
the user has verified their token, it is then replicated in FreeIPA.
Creates a Keycloak OTP secret and then displays that to the user.
"""
username = flask_session["userinfo"].get("preferred_username")
secret = request.args.get("secret", default="", type=str)
otp_code = request.form.get("otp-code", default="")

if request.method == "GET":
kc_registered = get_kc_otp_is_registered(username)
ipa_registered = has_ipa_otp(username)

# If its registered in one place but not the other
if kc_registered != ipa_registered:
LOG.warning(
"%s does not have TOTP in both Keycloak and LDAP "
"(kc_registered=%s, ipa_registered=%s)",
username,
kc_registered,
ipa_registered,
)

# If already registered *somewhere*
if kc_registered or ipa_registered:

# If already registered
if kc_registered:
return render_template("otp.html", version=version, configured=True)

secret = generate_kc_otp(username)
Expand Down Expand Up @@ -97,12 +84,7 @@ def enable():
flash("2FA already configured.")
return redirect("/otp")

create_ipa_otp(username, secret)
app_passwd = set_app_passwd(username)

return render_template(
"otp.html", version=version, configured=True, passwd=app_passwd
)
return render_template("otp.html", version=version, configured=True)


@otp_bp.route("/otp/remove", methods=["GET"])
Expand Down
9 changes: 0 additions & 9 deletions selfservice/templates/otp.html
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,6 @@ <h3 class="card-title">Two Factor Settings</h3>
<div class="alert alert-warning" role="alert">
<strong>Keep this stored in a safe place!</strong> It can't be recovered after you leave this page.
</div>
<p class="card-text mt-3">
In order for you to use services like mail that don't support two-factor, we have generated you a
random password that you will need to use to access those services.

</p>
<p class="otp-secret">{{passwd}}</p>
<a href="/otp" class="btn btn-info" style="width:100%">
<i class="fas fa-check"></i> Okay, I saved it!
</a>
{% else %}
<p class="card-text mb-3">
You already have two-factor configured. If you would like to disable it, please click the button below.
Expand Down
27 changes: 1 addition & 26 deletions selfservice/utilities/ldap.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
Funtions dealing with direct LDAP and FreeIPA communications.
Functions dealing with direct LDAP and FreeIPA communications.
"""

import re
Expand Down Expand Up @@ -80,31 +80,6 @@ def ipa_login():
ipa.login(username, password)


def create_ipa_otp(username, secret):
"""
Create an OTP object in FreeIPA for the given user.

Keyword arguments:
username -- Username of account to use as object owner
secret -- Secret generated by Keycloak
"""
ipa_login()
data = {"ipatokenowner": username, "ipatokenotpkey": secret}
ipa._request("otptoken_add", params=data)


def has_ipa_otp(username):
"""
Check if the given user has any OTP tokens configured in FreeIPA.

Keyword arguments:
username -- Username of account to check
"""
ipa_login()
token_info = ipa._request("otptoken_find", params={"ipatokenowner": username})
return len(token_info["result"]) > 0


def delete_ipa_otp(username):
"""
Remove all OTP tokens from the given user's account.
Expand Down