Fixed password flow

This commit is contained in:
Éloi Rivard 2020-08-16 19:39:14 +02:00
parent eb3a9e97f3
commit 9f16c8c208
4 changed files with 51 additions and 38 deletions

View file

@ -293,11 +293,10 @@ olcObjectClasses: ( 1.3.6.1.4.1.56207.1.2.3 NAME 'oauthToken'
DESC 'OAuth 2.0 Token'
SUP top
STRUCTURAL
MUST oauthToken
MUST oauthAccessToken
MAY ( description $
oauthClientID $
oauthTokenType $
oauthAccessToken $
oauthRefreshToken $
oauthScope $
oauthIssueDate $

View file

@ -196,7 +196,7 @@ class Client(LDAPObjectHelper, ClientMixin):
class AuthorizationCode(LDAPObjectHelper, AuthorizationCodeMixin):
objectClass = ["oauth2AuthorizationCode"]
objectClass = ["oauthAuthorizationCode"]
base = "ou=authorizations,dc=mydomain,dc=tld"
id = "oauthCode"
@ -223,25 +223,23 @@ class AuthorizationCode(LDAPObjectHelper, AuthorizationCodeMixin):
class Token(LDAPObjectHelper, TokenMixin):
objectClass = ["oauth2Token"]
objectClass = ["oauthToken"]
base = "ou=tokens,dc=mydomain,dc=tld"
id = "oauthToken"
id = "oauthAccessToken"
def get_client_id(self):
return self.authzClientID[0]
def get_scope(self):
return self.authzScopeValue[0]
return " ".join(self.oauthScope)
def get_expires_in(self):
return int(self.authzAccessTokenLifetime[0])
return int(self.oauthTokenLifetime[0])
def get_expires_at(self):
issue_date = datetime.datetime.strptime(
self.authzAccessTokenIssueDate[0], "%Y%m%d%H%M%SZ"
)
issue_date = datetime.datetime.strptime(self.oauthIssueDate[0], "%Y%m%d%H%M%SZ")
issue_timestamp = (issue_date - datetime.datetime(1970, 1, 1)).total_seconds()
return issue_timestamp + int(self.authzAccessTokenLifetime[0])
return issue_timestamp + int(self.oauthTokenLifetime[0])
def is_refresh_token_active(self):
if self.revoked:

View file

@ -1,3 +1,4 @@
import datetime
from authlib.integrations.flask_oauth2 import AuthorizationServer, ResourceProtector
from authlib.oauth2.rfc6749.grants import (
AuthorizationCodeGrant as _AuthorizationCodeGrant,
@ -99,6 +100,7 @@ class RefreshTokenGrant(_RefreshTokenGrant):
raise NotImplementedError()
credential.revoked = True
class ImplicitGrant(_OpenIDImplicitGrant):
def exists_nonce(self, nonce, request):
return exists_nonce(nonce, request)
@ -129,7 +131,17 @@ def query_client(client_id):
def save_token(token, request):
raise NotImplementedError()
now = datetime.datetime.now()
token = Token(
oauthTokenType=token["token_type"],
oauthAccessToken=token["access_token"],
oauthRefreshToken=token["refresh_token"],
oauthIssueDate=now.strftime("%Y%m%d%H%M%SZ"),
oauthTokenLifetime=str(token["expires_in"]),
oauthScope=token["scope"].split(" "),
oauthClientID=request.client.oauthClientID[0],
)
token.save()
class BearerTokenValidator(_BearerTokenValidator):

View file

@ -7,45 +7,45 @@ from .models import User, Client
from .oauth2 import authorization, require_oauth
bp = Blueprint(__name__, 'home')
bp = Blueprint(__name__, "home")
def current_user():
if 'user_dn' in session:
if "user_dn" in session:
return User.get(session["user_dn"])
return None
@bp.route('/', methods=('GET', 'POST'))
@bp.route("/", methods=("GET", "POST"))
def home():
if request.method == 'POST':
username = request.form.get('username')
if request.method == "POST":
username = request.form.get("username")
user = User.get(username)
if not user:
user = User(cn=username, sn=username)
user.save()
session["user_dn"] = user.dn
return redirect('/')
return redirect("/")
user = current_user()
if user:
clients = Client.filter()
else:
clients = []
return render_template('home.html', user=user, clients=clients)
return render_template("home.html", user=user, clients=clients)
def split_by_crlf(s):
return [v for v in s.splitlines() if v]
@bp.route('/create_client', methods=('GET', 'POST'))
@bp.route("/create_client", methods=("GET", "POST"))
def create_client():
user = current_user()
if not user:
return redirect('/')
if request.method == 'GET':
return render_template('create_client.html')
return redirect("/")
if request.method == "GET":
return render_template("create_client.html")
form = request.form
client_id = gen_salt(24)
client_id_issued_at = datetime.datetime.now().strftime("%Y%m%d%H%M%SZ")
@ -59,41 +59,45 @@ def create_client():
oauthResponseType=split_by_crlf(form["response_type"]),
oauthScope=form["scope"],
oauthTokenEndpointAuthMethod=form["token_endpoint_auth_method"],
oauthClientSecret='' if form['token_endpoint_auth_method'] == 'none' else gen_salt(48),
oauthClientSecret=""
if form["token_endpoint_auth_method"] == "none"
else gen_salt(48),
)
client.save()
return redirect('/')
return redirect("/")
@bp.route('/oauth/authorize', methods=['GET', 'POST'])
@bp.route("/oauth/authorize", methods=["GET", "POST"])
def authorize():
user = current_user()
if request.method == 'GET':
if request.method == "GET":
try:
grant = authorization.validate_consent_request(end_user=user)
except OAuth2Error as error:
return jsonify(dict(error.get_body()))
return render_template('authorize.html', user=user, grant=grant)
if not user and 'username' in request.form:
username = request.form.get('username')
return render_template("authorize.html", user=user, grant=grant)
if not user and "username" in request.form:
username = request.form.get("username")
user = User.get(username)
if request.form['confirm']:
if request.form["confirm"]:
grant_user = user
else:
grant_user = None
return authorization.create_authorization_response(grant_user=grant_user)
@bp.route('/logout')
def logout():
del session['user_dn']
return redirect('/')
@bp.route('/oauth/token', methods=['POST'])
@bp.route("/logout")
def logout():
del session["user_dn"]
return redirect("/")
@bp.route("/oauth/token", methods=["POST"])
def issue_token():
return authorization.create_token_response()
@bp.route('/api/me')
@require_oauth('profile')
@bp.route("/api/me")
@require_oauth("profile")
def api_me():
return jsonify(foo="bar")