Skip to content

Commit

Permalink
Refs #253, working Qt with webchannel.
Browse files Browse the repository at this point in the history
  • Loading branch information
doumdi committed Sep 19, 2024
1 parent c0c9b6a commit 17ae671
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 13 deletions.
38 changes: 27 additions & 11 deletions teraserver/python/modules/FlaskModule/API/user/UserLogin2FA.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,35 @@
import pyotp
from opentera.db.models.TeraUser import TeraUser

# Get parser
get_parser = api.parser()
get_parser.add_argument('otp_code', type=str, required=True, help='2FA otp code')
get_parser.add_argument('with_websocket', type=inputs.boolean,
help='If set, requires that a websocket url is returned.'
'If not possible to do so, return a 403 error.',
default=False)

get_parser.add_argument('otp_code', type=str, required=True, help='2FA otp code')
# Post parser
post_parser = api.parser()
post_parser.add_argument('otp_code', type=str, required=True, help='2FA otp code')
post_parser.add_argument('with_websocket', type=inputs.boolean,
help='If set, requires that a websocket url is returned.'
'If not possible to do so, return a 403 error.',
default=False)


class UserLogin2FA(UserLoginBase):

def __init__(self, _api, *args, **kwargs):
UserLoginBase.__init__(self, _api, *args, **kwargs)

@api.doc(description='Login to the server using HTTP Basic Authentication (HTTPAuth) and 2FA')
@api.expect(get_parser, validate=True)
@user_http_auth.login_required
def get(self):
# TODO Move this to UserLoginBase ?
def _common_2fa_login_response(self, parser):
try:
args = get_parser.parse_args(strict=True)
# Validate args
args = parser.parse_args(strict=True)

# Current user is logged in with HTTPAuth
# Current user is logged in with HTTPAuth, or session
# Let's verify if 2FA is enabled and if OTP is valid
if not current_user.user_2fa_enabled:
self._user_logout()
Expand Down Expand Up @@ -77,9 +84,9 @@ def get(self):
'current_version': e.current_version,
'version_error': e.version_error,
'message': gettext('Client major version too old, not accepting login')}, 426
# except InvalidClientVersionError as e:
# # Invalid client version, will not be handled for now
# pass
# except InvalidClientVersionError as e:
# # Invalid client version, will not be handled for now
# pass
except UserAlreadyLoggedInError as e:
self._user_logout()
return gettext('User already logged in.'), 403
Expand All @@ -92,6 +99,15 @@ def get(self):
self._send_login_success_message()
return response, 200

@api.doc(description='Login to the server using HTTP Basic Authentication (HTTPAuth) and 2FA')
@api.expect(get_parser, validate=True)
@user_http_auth.login_required
def get(self):
return self._common_2fa_login_response(get_parser)


@api.doc(description='Login to the server using HTTP Basic Authentication (session auth) and 2FA')
@api.expect(post_parser, validate=True)
@LoginModule.user_session_required
def post(self):
return self._common_2fa_login_response(post_parser)

Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@ def _verify_client_version(self) -> dict or None:
return reply

def _generate_websocket_url(self) -> str:
websocket_url = f"wss://{self.servername}:{str(self.port)}/wss/user?id=\"{session['_id']}\""
# The key is set with an expiration of 60s, will be verify when the websocket is opened in the TwistedModule
websocket_url = f"wss://{self.servername}:{str(self.port)}/wss/user?id={session['_id']}"
# The key is set with an expiration of 60s, will be verified when the websocket is opened in the TwistedModule
self.module.redisSet(session['_id'], session['_user_id'], ex=60)
return websocket_url

Expand Down
67 changes: 67 additions & 0 deletions teraserver/python/templates/login_validate_2fa.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,48 @@
qtObject.handleToken(token);
}
</script>

<!-- call function when document is loaded -->
<script>
$(document).ready(function() {
qtObject.debugPrint("Document is ready");
});
</script>

<script>
function post_form_data_and_validate_login() {
const otp_code = document.getElementById("2fa_code").value;
qtObject.debugPrint("2FA code validation");

// Send the OTP code to the backend with a post request
// Use the login API for this purpose
$.ajax({
type: "POST",
url: "/api/user/login_2fa",
data: {
otp_code: otp_code,
with_websocket: true
},
success: function(data, textStatus, jqXHR) {
qtObject.debugPrint("2FA code validation, success called");
if (jqXHR.status === 200) {
// If the status is 200, the 2FA code is valid
// Send the token to the Qt application
// Answer will contain,user_uuid, user_token, websocket_url
qtObject.sendLoginSuccess(data.user_token, data.websocket_url, data.user_uuid);
} else {
alert("Error validating 2FA code");
}
},
error: function() {
alert("Error validating 2FA code");
}
});

}

</script>

</head>
<body>
<!-- Create a form to enter the 2FA code -->
Expand All @@ -29,6 +71,9 @@
<div class="card">
<div class="card-header">2FA</div>
<div class="card-body">

<!-- This should be enabled for web only logins -->
<!-- Form based, will post data to /login_validate_2fa
<form action="/login_validate_2fa" method="post">
<div class="form-group row">
<label for="2fa_code" class="col-md-4 col-form-label text-md-right">2FA Code</label>
Expand All @@ -40,6 +85,28 @@
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
-->

<!-- This should be enabled for desktop only login, users enter code and then we call
the post_form_data_and_validate_login with the validate button -->
<form id="login_form">
<div class="form-group
row">
<label for="2fa_code" class="col-md-4 col-form-label text-md-right">2FA Code</label>
<div class="col-md-6">
<input type="text" id="2fa_code" class="form-control" name="2fa_code" required autofocus>
</div>

<!-- Validation button -->
<div class="col-md-6 offset-md-4">
<button type="button" class="btn btn-primary" onclick="post_form_data_and_validate_login()">Submit</button>
</div>
</div>
</form>




</div>
</div>
</div>
Expand Down

0 comments on commit 17ae671

Please sign in to comment.