epicyon/webapp_login.py

195 lines
7.7 KiB
Python
Raw Normal View History

2020-11-10 09:45:18 +00:00
__filename__ = "webapp_login.py"
__author__ = "Bob Mottram"
__license__ = "AGPL3+"
2022-02-03 13:58:20 +00:00
__version__ = "1.3.0"
2020-11-10 09:45:18 +00:00
__maintainer__ = "Bob Mottram"
2021-09-10 16:14:50 +00:00
__email__ = "bob@libreserver.org"
2020-11-10 09:45:18 +00:00
__status__ = "Production"
2021-06-15 15:08:12 +00:00
__module_group__ = "Web Interface"
2020-11-10 09:45:18 +00:00
import os
import time
from shutil import copyfile
2021-12-26 14:08:58 +00:00
from utils import get_config_param
2021-12-28 14:41:10 +00:00
from utils import no_of_accounts
2021-12-28 14:55:45 +00:00
from utils import get_nickname_validation_pattern
2021-12-29 21:55:09 +00:00
from webapp_utils import set_custom_background
from webapp_utils import html_header_with_website_markup
from webapp_utils import html_footer
from webapp_utils import html_keyboard_navigation
from theme import get_text_mode_logo
2020-11-10 09:45:18 +00:00
2021-12-29 21:55:09 +00:00
def html_get_login_credentials(loginParams: str,
last_login_time: int,
domain: str) -> (str, str, bool):
2020-11-10 09:45:18 +00:00
"""Receives login credentials via HTTPServer POST
"""
if not loginParams.startswith('username='):
return None, None, None
# minimum time between login attempts
2021-12-26 13:17:46 +00:00
curr_time = int(time.time())
if curr_time < last_login_time+10:
2020-11-10 09:45:18 +00:00
return None, None, None
if '&' not in loginParams:
return None, None, None
2022-01-03 23:30:31 +00:00
login_args = loginParams.split('&')
2020-11-10 09:45:18 +00:00
nickname = None
password = None
register = False
2022-01-03 23:30:31 +00:00
for arg in login_args:
2021-07-06 09:44:45 +00:00
if '=' not in arg:
continue
if arg.split('=', 1)[0] == 'username':
nickname = arg.split('=', 1)[1]
if nickname.startswith('@'):
nickname = nickname[1:]
if '@' in nickname:
# the full nickname@domain has been entered
nickname = nickname.split('@')[0]
elif arg.split('=', 1)[0] == 'password':
password = arg.split('=', 1)[1]
elif arg.split('=', 1)[0] == 'register':
register = True
2020-11-10 09:45:18 +00:00
return nickname, password, register
2021-12-29 21:55:09 +00:00
def html_login(css_cache: {}, translate: {},
base_dir: str,
http_prefix: str, domain: str,
system_language: str,
autocomplete: bool) -> str:
2020-11-10 09:45:18 +00:00
"""Shows the login screen
"""
2021-12-28 14:41:10 +00:00
accounts = no_of_accounts(base_dir)
2020-11-10 09:45:18 +00:00
2022-01-03 23:30:31 +00:00
login_image = 'login.png'
login_image_filename = None
if os.path.isfile(base_dir + '/accounts/' + login_image):
login_image_filename = base_dir + '/accounts/' + login_image
2021-12-25 16:17:53 +00:00
elif os.path.isfile(base_dir + '/accounts/login.jpg'):
2022-01-03 23:30:31 +00:00
login_image = 'login.jpg'
login_image_filename = base_dir + '/accounts/' + login_image
2021-12-25 16:17:53 +00:00
elif os.path.isfile(base_dir + '/accounts/login.jpeg'):
2022-01-03 23:30:31 +00:00
login_image = 'login.jpeg'
login_image_filename = base_dir + '/accounts/' + login_image
2021-12-25 16:17:53 +00:00
elif os.path.isfile(base_dir + '/accounts/login.gif'):
2022-01-03 23:30:31 +00:00
login_image = 'login.gif'
login_image_filename = base_dir + '/accounts/' + login_image
2021-12-25 16:17:53 +00:00
elif os.path.isfile(base_dir + '/accounts/login.svg'):
2022-01-03 23:30:31 +00:00
login_image = 'login.svg'
login_image_filename = base_dir + '/accounts/' + login_image
2021-12-25 16:17:53 +00:00
elif os.path.isfile(base_dir + '/accounts/login.webp'):
2022-01-03 23:30:31 +00:00
login_image = 'login.webp'
login_image_filename = base_dir + '/accounts/' + login_image
2021-12-25 16:17:53 +00:00
elif os.path.isfile(base_dir + '/accounts/login.avif'):
2022-01-03 23:30:31 +00:00
login_image = 'login.avif'
login_image_filename = base_dir + '/accounts/' + login_image
2022-02-06 11:04:49 +00:00
elif os.path.isfile(base_dir + '/accounts/login.jxl'):
login_image = 'login.jxl'
login_image_filename = base_dir + '/accounts/' + login_image
2020-11-10 09:45:18 +00:00
2022-01-03 23:30:31 +00:00
if not login_image_filename:
login_image_filename = base_dir + '/accounts/' + login_image
copyfile(base_dir + '/img/login.png', login_image_filename)
2020-11-10 09:45:18 +00:00
2022-01-03 23:30:31 +00:00
text_mode_logo = get_text_mode_logo(base_dir)
text_mode_logo_html = html_keyboard_navigation(text_mode_logo, {}, {})
2021-02-06 14:30:18 +00:00
2021-12-29 21:55:09 +00:00
set_custom_background(base_dir, 'login-background-custom',
'login-background')
2020-11-10 09:45:18 +00:00
if accounts > 0:
2022-01-03 23:30:31 +00:00
login_text = \
2020-11-10 09:45:18 +00:00
'<p class="login-text">' + \
translate['Welcome. Please enter your login details below.'] + \
'</p>'
else:
2022-01-03 23:30:31 +00:00
login_text = \
2020-11-10 09:45:18 +00:00
'<p class="login-text">' + \
2021-07-06 09:44:45 +00:00
translate['Please enter some credentials'] + '</p>' + \
2020-11-10 09:45:18 +00:00
'<p class="login-text">' + \
translate['You will become the admin of this site.'] + \
'</p>'
2021-12-25 16:17:53 +00:00
if os.path.isfile(base_dir + '/accounts/login.txt'):
2020-11-10 09:45:18 +00:00
# custom login message
2021-12-25 16:17:53 +00:00
with open(base_dir + '/accounts/login.txt', 'r') as file:
2022-01-03 23:30:31 +00:00
login_text = '<p class="login-text">' + file.read() + '</p>'
2020-11-10 09:45:18 +00:00
2021-12-31 21:18:12 +00:00
css_filename = base_dir + '/epicyon-login.css'
2021-12-25 16:17:53 +00:00
if os.path.isfile(base_dir + '/login.css'):
2021-12-31 21:18:12 +00:00
css_filename = base_dir + '/login.css'
2020-11-10 09:45:18 +00:00
# show the register button
2022-01-03 23:30:31 +00:00
register_button_str = ''
2021-12-26 14:08:58 +00:00
if get_config_param(base_dir, 'registration') == 'open':
if int(get_config_param(base_dir, 'registrationsRemaining')) > 0:
2020-11-10 09:45:18 +00:00
if accounts > 0:
idx = 'Welcome. Please login or register a new account.'
2022-01-03 23:30:31 +00:00
login_text = \
2020-11-10 09:45:18 +00:00
'<p class="login-text">' + \
translate[idx] + \
'</p>'
2022-01-03 23:30:31 +00:00
register_button_str = \
2020-11-10 09:45:18 +00:00
'<button type="submit" name="register">Register</button>'
2022-01-03 23:30:31 +00:00
tos_str = \
2020-11-10 09:45:18 +00:00
'<p class="login-text"><a href="/about">' + \
2021-07-06 09:44:45 +00:00
translate['About this Instance'] + '</a></p>' + \
2020-11-10 11:38:27 +00:00
'<p class="login-text"><a href="/terms">' + \
translate['Terms of Service'] + '</a></p>'
2020-11-10 09:45:18 +00:00
2022-01-03 23:30:31 +00:00
login_button_str = ''
2020-11-10 09:45:18 +00:00
if accounts > 0:
2022-01-03 23:30:31 +00:00
login_button_str = \
2020-11-10 09:45:18 +00:00
'<button type="submit" name="submit">' + \
translate['Login'] + '</button>'
2022-01-03 23:30:31 +00:00
autocomplete_nickname_str = 'autocomplete="username"'
autocomplete_password_str = 'autocomplete="current-password"'
2020-11-10 09:45:18 +00:00
if not autocomplete:
2022-01-03 23:30:31 +00:00
autocomplete_nickname_str = 'autocomplete="username" value=""'
autocomplete_password_str = 'autocomplete="off" value=""'
2020-11-10 09:45:18 +00:00
2022-01-03 23:30:31 +00:00
instance_title = \
2021-12-26 14:08:58 +00:00
get_config_param(base_dir, 'instanceTitle')
2022-01-03 23:30:31 +00:00
login_form = \
html_header_with_website_markup(css_filename, instance_title,
2021-12-29 21:55:09 +00:00
http_prefix, domain,
system_language)
2022-01-03 23:30:31 +00:00
nickname_pattern = get_nickname_validation_pattern()
instance_title = get_config_param(base_dir, 'instanceTitle')
login_form += \
2021-07-06 09:44:45 +00:00
'<br>\n' + \
'<form method="POST" action="/login">\n' + \
' <div class="imgcontainer">\n' + \
2022-01-03 23:30:31 +00:00
text_mode_logo_html + '\n' + \
' <img loading="lazy" src="' + login_image + \
'" alt="' + instance_title + '" class="loginimage">\n' + \
login_text + tos_str + '\n' + \
2021-07-06 09:44:45 +00:00
' </div>\n' + \
'\n' + \
' <div class="container">\n' + \
' <label for="nickname"><b>' + \
translate['Nickname'] + '</b></label>\n' + \
2022-01-03 23:30:31 +00:00
' <input type="text" ' + autocomplete_nickname_str + \
' placeholder="' + translate['Enter Nickname'] + '" ' + \
2022-01-03 23:30:31 +00:00
'pattern="' + nickname_pattern + '" name="username" ' + \
2021-07-29 13:21:04 +00:00
'required autofocus>\n' + \
2021-07-06 09:44:45 +00:00
'\n' + \
' <label for="password"><b>' + \
translate['Password'] + '</b></label>\n' + \
2022-01-03 23:30:31 +00:00
' <input type="password" ' + autocomplete_password_str + \
2021-07-29 14:15:44 +00:00
' placeholder="' + translate['Enter Password'] + '" ' + \
'pattern="{8,256}" name="password" required>\n' + \
2022-01-03 23:30:31 +00:00
login_button_str + register_button_str + '\n' + \
2021-07-06 09:44:45 +00:00
' </div>\n' + \
'</form>\n' + \
2020-11-10 09:45:18 +00:00
'<a href="https://gitlab.com/bashrc2/epicyon">' + \
'<img loading="lazy" class="license" title="' + \
translate['Get the source code'] + '" alt="' + \
translate['Get the source code'] + '" src="/icons/agpl.png" /></a>\n'
2022-01-03 23:30:31 +00:00
login_form += html_footer()
return login_form