Skip to content

Commit

Permalink
Implementing registering user on first SSO (#75)
Browse files Browse the repository at this point in the history
* Implementing registering user on first SSO

* Implement creating user from SSO without password

* Login attempt into the sso account will result in redirect to sso
  • Loading branch information
EduKav1813 authored Jul 11, 2024
1 parent 13f3ed0 commit 94f3a87
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 15 deletions.
23 changes: 20 additions & 3 deletions whois/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
class User(pw.Model):
id = pw.PrimaryKeyField()
username = pw.CharField(unique=True)
_password = pw.CharField(column_name="password")
_password = pw.CharField(column_name="password", null=True)
display_name = pw.CharField()
flags = pw.BitField(null=True)

Expand All @@ -45,13 +45,26 @@ def register(cls, username, password, display_name=None):
:param display_name: displayed username
:return: user instance
"""
# TODO: ehh
user = cls.create(
username=username, _password="todo", display_name=display_name
username=username, display_name=display_name
)
user.password = password
return user

@classmethod
def register_from_sso(cls, username, display_name=None):
"""
Creates user without any password. Such users can only login via SSO.
:param username: used in login
:param display_name: displayed username
:return: user instance
"""
user = cls.create(
username=username, display_name=display_name
)
user._password = None
return user

def __str__(self):
if self.is_name_anonymous or self.is_hidden:
return "anonymous"
Expand All @@ -74,6 +87,10 @@ def is_anonymous(self):
"""
return False

@property
def is_sso(self) -> bool:
return not self._password

@property
def password(self):
return self._password
Expand Down
34 changes: 22 additions & 12 deletions whois/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,7 @@

cors = CORS(app, resources={r"/api/*": {"origins": "*"}})

common_vars_tpl = {
"app": app.config.get_namespace('APP_')
}
common_vars_tpl = {"app": app.config.get_namespace("APP_")}


@app.template_filter("local_time")
Expand Down Expand Up @@ -111,7 +109,7 @@ def index():
users=filter_anon_names(users),
headcount=len(users),
unknowncount=len(unclaimed_devices(recent)),
**common_vars_tpl
**common_vars_tpl,
)


Expand All @@ -132,7 +130,7 @@ def devices():
my_devices=mine,
users=filter_anon_names(users),
headcount=len(users),
**common_vars_tpl
**common_vars_tpl,
)


Expand Down Expand Up @@ -275,9 +273,19 @@ def login():
except User.DoesNotExist:
user = None

if user is not None and user.auth(request.form["password"]) is True:
login_user(user)
app.logger.info("logged in: {}".format(user.username))
if user is not None:
if user.is_sso:
# User created via sso -> redirect to sso login
app.logger.info("Redirect to SSO user: {}".format(user.username))
return redirect(url_for("login_oauth"))
elif user.auth(request.form["password"]) is True:
# User password hash match -> login user successfully
login_user(user)
app.logger.info("logged in: {}".format(user.username))
else:
pass

if current_user.is_authenticated:
flash(
"Hello {}! You can now claim and manage your devices.".format(
current_user.username
Expand Down Expand Up @@ -305,12 +313,15 @@ def callback():
token = oauth.sso.authorize_access_token()
user_info = oauth.sso.parse_id_token(token)
if user_info:
print(user_info)
try:
user = User.get(User.username == user_info["preferred_username"])
except User.DoesNotExist:
user = None
app.logger.warning("no user: {}".format(user_info["preferred_username"]))
username = user_info["preferred_username"]
app.logger.info(
f"No SSO-loggined user: {username}.\n"
f"Register user {username}",
)
user = User.register_from_sso(username=username, display_name=username)

if user is not None:
login_user(user)
Expand All @@ -326,7 +337,6 @@ def callback():
app.logger.info("failed log in: {}".format(user_info["preferred_username"]))
flash("Invalid credentials", "error")
return redirect(url_for("login"))



@app.route("/logout")
Expand Down

0 comments on commit 94f3a87

Please sign in to comment.