Author SHA1 Message Date
aitzol b0499c6593 user agent 2023-04-29 11:46:01 +02:00
aitzol 8cbd4b3775 README 2023-04-23 23:10:30 +02:00
aitzol 80455d7051 README 2023-04-23 23:04:18 +02:00
aitzol 824bb63bd3 README 2023-04-23 23:01:42 +02:00
aitzol 1a164bbba3 README 2023-04-23 23:00:26 +02:00
aitzol 71de5c86bf tz 2023-04-23 15:04:05 +02:00
aitzol d90087c3c7 zuzenketa 2023-04-23 11:22:48 +02:00
aitzol 3abac37ba4 docker 2023-04-20 11:55:17 +02:00
aitzol f7a4b6ab72 docker 2023-04-19 20:13:35 +02:00
aitzol fe13e89d8a README 2023-04-19 15:20:43 +02:00
aitzol 9d3f205b53 settings 2023-04-19 12:54:05 +02:00
aitzol e6c9b21447 docker 2023-04-18 17:17:27 +02:00
aitzol 3bb9646bc4 docker 2023-04-18 05:38:19 +02:00
aitzol 4f3d8f9ace docker 2023-04-18 05:17:08 +02:00
aitzol 5221f1b826 docker 2023-04-17 05:26:22 +02:00
aitzol 50464d5247 find_device 2023-04-11 18:22:56 +02:00
aitzol f8ed4e028a find_device 2023-04-11 18:19:16 +02:00
aitzol 3b8582a7df ip eta gailu erregistroa 2023-04-07 15:21:44 +02:00
aitzol d82d827079 erregistroak gehitzen 2023-04-06 22:09:26 +02:00
aitzol 35584086da segurtasuna hobetzeko lanetan 2023-04-06 16:45:26 +02:00
aitzol bbd157d82e segurtasuna hobetzeko lanetan 2023-04-06 16:43:22 +02:00
25 changed files with 540 additions and 302 deletions
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
+3 -1
View File
@@ -1,6 +1,8 @@
/settings.ini
/settings.ini.example.original
/uwsgi.ini
/*.sw*
*.swp
*.swo
*~
session
libs/__pycache__
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+19
View File
@@ -0,0 +1,19 @@
FROM python:3-alpine
ARG UID_
ENV UID_=1000
RUN apk add --no-cache --upgrade bash
ADD --chown=$UID_:$UID_ . /www
WORKDIR /www
RUN chmod +x start.sh
RUN set -e; \
apk add --no-cache --virtual .build-deps \
gcc \
libc-dev \
linux-headers \
; \
pip install -r requirements.txt; \
apk del .build-deps;
ENTRYPOINT ["./start.sh"]
+38 -8
View File
@@ -4,8 +4,10 @@
[git-izena]: aitzol/[proiektu-izena]
[pypi-bottle]: https://pypi.python.org/pypi/bottle/
[pypi-ldap3]: https://pypi.python.org/pypi/ldap3
[ua]: https://pypi.org/project/user-agents/
[settings]: https://git.lainoa.eus/aitzol/ldap-python-webui/src/branch/master/settings.ini.example
[uwsgi]: https://git.lainoa.eus/aitzol/ldap-python-webui/src/branch/master/uwsgi.ini.example
[uwsgi-example]: https://git.lainoa.eus/aitzol/ldap-python-webui/src/branch/master/uwsgi.ini.example
[uwsgi]: https://pypi.org/project/uWSGI/
[GPL3]: https://www.gnu.org/licenses/gpl-3.0.txt
[LICENSE]: https://www.gnu.org/licenses/licenses.html
[wsgiref]: https://docs.python.org/3/library/wsgiref.html#module-wsgiref.simple_server
@@ -20,13 +22,15 @@ Probak egiteko LDAP zerbitzari bat instalatu da ondorengo [eredua][server] jarra
## Instalakuntza
### Ostalarian
#### Baldintzak
* Python 3.x
* [bottle][pypi-bottle]
* [ldap3][pypi-ldap3] 2.x
#### Urratsak
* [uwsgi][uwsgi]
* [user-agents][ua]
Biltegi honetako edukiak klonatu eta menpekotasunak instalatu:
@@ -34,9 +38,29 @@ Biltegi honetako edukiak klonatu eta menpekotasunak instalatu:
cd ldap-python-webui
pip install -r requirements.txt
## Abian jarri
### Docker bidez
#### Konfiguraketa
#### Prestakuntza
Konfiguraketa fitxategia sortu:
cp settings.ini.example settings.ini
#### Docker irudia eraiki
docker build -t aitzol/ldap-webui:latest .
edo
docker build -t aitzol/ldap-webui:latest . --build-arg UID_=$UID
#### Edukiontzia sortu
docker-compose up -d
## Nola abiarazi
#### Ezarpenak
Konfiguraketa [settings.ini][settings] fitxategian ezartzen da. Fitxategi honen kokapena `CONF_FILE` ingurumen-aldagaia erabiliz zehaztu daiteke.
@@ -49,9 +73,9 @@ Konfiguraketa [settings.ini][settings] fitxategian ezartzen da. Fitxategi honen
* [WSGI][WSGI] zerbitzariaren bidez, [wsgiref][wsgiref]-en oinarritua:
```
uwsgi --http :8080 --enable-threads --wsgi-file app.py
uwsgi --http :9090 --enable-threads --wsgi-file app.py
```
edo [uwsgi.ini][ uwsgi ] fitxategia sortu eta exekutatu:
edo [uwsgi.ini][ uwsgi-example ] fitxategia sortu eta exekutatu:
```
uwsgi -i uwsgi.ini
@@ -62,8 +86,12 @@ edo [uwsgi.ini][ uwsgi ] fitxategia sortu eta exekutatu:
cd ldap-python-webui
python3 app.py
```
* Komando lerroan **start.sh** script-a erabiliz:
* Ondoren nabigatzailean http://localhost:8080 helbidea ireki
```
./start.sh $UID
```
* Ondoren nabigatzailean http://localhost:9090 helbidea ireki
## Ezaugarriak
* Saioa hasi
@@ -75,12 +103,14 @@ edo [uwsgi.ini][ uwsgi ] fitxategia sortu eta exekutatu:
* Kontua sortu
> Gonbidapen kodea erabiliz
* Lokalizazioa/Hizkuntza egokitzeko aukera
* Ip helbidea eta gailua atzeman
## Egiteke
* Erabiltzaileari ePosta bidez kontua aktibatzeko eskatzea.
* Pasahitza berrezartzen denean erabiltzaileari ePosta bidez jakinaraztea.
* Pasahitz berreskuratzea.
* Ip helbide edo gailu susmagarria atzemanez gero erabiltzailea jakinaraztea.
## Screenshot
+58 -27
View File
@@ -32,9 +32,9 @@ import logging
from os import getenv, environ, path
from libs import flist, slist
from libs.localization import *
from libs.helper import *
from libs.helper import tools
import random
from user_agents import parse
from user_agents import parse as ua_parse
from datetime import datetime
BASE_DIR = path.dirname(__file__)
@@ -86,6 +86,13 @@ def get_index():
except Exception as e:
return index_tpl(str=i18n.str)
@get('/logs')
def get_index():
try:
return logs_tpl(data=newSession().get(), str=i18n.str)
except Exception as e:
return index_tpl(str=i18n.str)
@get('/delete')
def get_index():
try:
@@ -93,6 +100,7 @@ def get_index():
except Exception as e:
return index_tpl(str=i18n.str)
@get('/logout')
def get_index():
@@ -112,7 +120,6 @@ def get_index():
@post('/user')
def post_user():
form = request.forms.getunicode
tools = Tools()
def error(msg):
return index_tpl(alerts=[('error', msg, 'fadeOut')], str=i18n.str)
@@ -143,7 +150,6 @@ def post_signup():
form = request.forms.getunicode
isFake = False
tools = Tools()
db = 'data/invite-codes.db'
def auto_complete(arg):
@@ -206,7 +212,6 @@ def post_signup():
@post('/edit_fullname')
def post_edit_fullname():
form = request.forms.getunicode
tools = Tools()
try:
username = newSession().get()['username']
@@ -239,7 +244,6 @@ def post_edit_fullname():
@post('/edit_email')
def post_edit_email():
form = request.forms.getunicode
tools = Tools()
try:
username = newSession().get()['username']
@@ -264,7 +268,6 @@ def post_edit_email():
@post('/change_pwd')
def post_change_pwd():
form = request.forms.getunicode
tools = Tools()
try:
username=newSession().get()['username']
@@ -297,7 +300,6 @@ def post_change_pwd():
@post('/delete')
def post_delete():
form = request.forms.getunicode
tools = Tools()
def error(msg):
return delete_tpl(alerts=[('error', msg, 'fadeOut')], str=i18n.str)
@@ -342,6 +344,9 @@ def edit_fullname_tpl(**kwargs):
def delete_tpl(**kwargs):
return template('delete', **kwargs)
def logs_tpl(**kwargs):
return template('logs', **kwargs)
def connect_ldap(conf, **kwargs):
server = Server(host=conf['host'],
port=conf.getint('port', None),
@@ -391,15 +396,13 @@ def login_user_ldap(conf, username, password):
#with connect_ldap(conf) as c:
with connect_ldap(conf, user=superUser.readonly_dn, password=superUser.readonly_pwd) as c:
user_dn = find_user_dn(conf, c, username)
cur_dev = get_dev()
known_device = find_device(conf, c, cur_dev)
print('KNOWN DEVICE:',known_device)
print(request.environ.get('HTTP_X_REAL_IP', request.remote_addr))
# Note: raises LDAPUserNameIsMandatoryError when user_dn is None.
with connect_ldap(conf, authentication=SIMPLE, user=user_dn, password=password) as c:
c.bind()
update_login_info(conf, user_dn)
if is_trusted_device(conf, user_dn):
newSession().set(get_user_data(user_dn, c))
#update timestamp + ip address
update_login_info(conf, user_dn)
LOG.debug("%s logged in to %s" % (username, conf['base']))
#LOGOUT
@@ -514,10 +517,10 @@ def register(conf, username, firstname, surname, password, email, isFake, device
uidNumber = find_uid_number(conf,c)+1
directory = 'home/user/'+to_ascii(username)
OBJECT_CLASS = ['top', 'inetOrgPerson', 'posixAccount', 'accountsManagement']
t = datetime.now().strftime('%Y%m%d%H%M%S')+'Z'
ts = datetime.now().strftime('%Y%m%d%H%M%S')+'Z'
attributes = {'gidNumber': '501', 'uidNumber': uidNumber, 'homeDirectory': directory, 'givenName':
firstname, 'sn': surname, 'uid' : username, 'mail': email, 'active': False, 'fakeCn': isFake,
'devices':device, 'ip':request.environ.get('HTTP_X_REAL_IP', request.remote_addr), 'lastLogin': t}
'devices':device, 'ip':request.environ.get('HTTP_X_REAL_IP', request.remote_addr), 'lastLogin': ts}
new_user_dn = "cn="+firstname+" "+surname+" - "+username+",cn=users,"+conf['base']
c.add(dn=new_user_dn,object_class=OBJECT_CLASS, attributes=attributes)
#create/change user password
@@ -767,10 +770,10 @@ def find_email(conf, conn, email):
return False
#find devices
def find_device(conf, conn, device):
search_filter = '(uid=*)'
if conn.search(conf['base'], search_filter, attributes=['devices']):
#find device
def find_device(user_dn, conn, device):
search_filter = '(objectClass=*)'
if conn.search(user_dn, search_filter, attributes=['devices']):
for i in conn.response:
for j in i['attributes']['devices']:
if(j == device):
@@ -804,7 +807,7 @@ def get_user_email_array(user_dn, conn, old_email, new_email):
def get_user_data(user_dn, conn):
search_filter = '(objectClass=*)'
conn.search(user_dn, search_filter, attributes=['active','fakeCn','givenName','sn','uid','mail','devices'])
conn.search(user_dn, search_filter, attributes=['active','fakeCn','givenName','sn','uid','mail','devices','ip','lastLogin'])
data = []
data.append(conn.entries[0].active.values[0])
data.append(conn.entries[0].fakeCn.values[0])
@@ -813,6 +816,12 @@ def get_user_data(user_dn, conn):
data.append(conn.entries[0].uid.values[0])
data.append(conn.entries[0].mail.values[0])
data.append(conn.entries[0].devices.values)
data.append(conn.entries[0].ip.values[0])
#ts = conn.entries[0].lastLogin.values[0]
#ts = datetime.strptime(ts, '%Y-%m-%d %H:%M:%S%z')
#ts = datetime.strftime(t, '%Y-%m-%d %H:%M:%S')
data.append(str(conn.entries[0].lastLogin.values[0])[:-6])
return(data)
def read_config():
@@ -840,19 +849,37 @@ allowed = reg()
def get_dev():
ua_string = bottle.request.environ.get('HTTP_USER_AGENT')
user_agent = parse(ua_string)
user_agent = ua_parse(ua_string)
return str(user_agent)
def is_trusted_device(conf, user_dn):
superUser = SuperUsers(conf)
with connect_ldap(conf, user=superUser.admin_dn, password=superUser.admin_pwd) as c:
d = get_dev()
try:
if not find_device(user_dn, c, d):
OBJECT_CLASS = ['top', 'inetOrgPerson', 'posixAccount', 'accountsManagement']
c.modify(user_dn, {'devices': [( MODIFY_ADD, d )] })
'''
if find_device(user_dn, c, 'unknown'):
OBJECT_CLASS = ['top', 'inetOrgPerson', 'posixAccount', 'accountsManagement']
c.modify(user_dn, {'devices': [( MODIFY_REPLACE, d )] })
else:
OBJECT_CLASS = ['top', 'inetOrgPerson', 'posixAccount', 'accountsManagement']
c.modify(user_dn, {'devices': [( MODIFY_ADD, d )] })
'''
c.unbind()
return True
except Exception as e:
print(e)
return True
def update_login_info(conf, user_dn):
superUser = SuperUsers(conf)
with connect_ldap(conf, user=superUser.admin_dn, password=superUser.admin_pwd) as c:
ip = request.environ.get('HTTP_X_REAL_IP', request.remote_addr)
t = datetime.now().strftime('%Y%m%d%H%M%S')+'Z'
c.modify(user_dn, {'ip': [( MODIFY_REPLACE, str(ip) )], 'lastLogin': [( MODIFY_REPLACE, t )] })
d = get_dev()
if not find_device(conf, c, d):
OBJECT_CLASS = ['top', 'inetOrgPerson', 'posixAccount', 'accountsManagement']
c.modify(user_dn, {'devices': [( MODIFY_ADD, d )] })
ts = datetime.now().strftime('%Y%m%d%H%M%S')+'Z'
c.modify(user_dn, {'ip': [( MODIFY_REPLACE, str(ip) )], 'lastLogin': [( MODIFY_REPLACE, ts )] })
c.unbind()
class Error(Exception):
@@ -893,6 +920,8 @@ def newSession():
self.username = data[4]
self.mail = data[5]
self.devices = data[6]
self.ip = data[7]
self.lastLogin = data[8]
self.data['active'] = self.active
self.data['fakeCn'] = self.fakeCn
@@ -901,6 +930,8 @@ def newSession():
self.data['username'] = self.username
self.data['mail'] = self.mail
self.data['devices'] = self.devices
self.data['ip'] = self.ip
self.data['lastLogin'] = self.lastLogin
def close(self):
self.data.pop('username')
+15
View File
@@ -0,0 +1,15 @@
version: '3'
services:
ldap-python-webui:
image: aitzol/ldap-webui:latest
container_name : ldap-python-webui
network_mode : host
volumes:
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
- ./data:/www/data:rw
- ./session:/www/session:rw
- ./settings.ini:/www/settings.ini
environment:
LDAP_ADMIN_PASSWORD: "admin"
LDAP_READONLY_PASSWORD: "readonly"
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+2
View File
@@ -42,3 +42,5 @@ class Tools():
def pwd_validation(self, e):
regex = r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!#%*?&]{8,18}$'
return(bool(re.fullmatch(regex, e)))
tools = Tools()
+10 -1
View File
@@ -36,6 +36,10 @@ class LocalizeTo(object):
str_21 = _("Change your password")
str_22 = _("Delete your account")
str_23 = _("Welcome")
str_24 = _("Logs")
str_25 = _("Last login")
str_26 = _("Devices")
str_27 = _("show")
#messages
msg_00 = _("The session was closed.")
@@ -68,5 +72,10 @@ class LocalizeTo(object):
msg_27 = _("The session has expired.")
msg_28 = _("Registration is currently closed. We apologize for the inconvenience.")
self.str = {'usr':str_00, 'usrn':str_01, 'fn':str_02, 'sn':str_03, 'pwd':str_04, 'old-pwd':str_05, 'new-pwd':str_06, 'conf-pwd':str_07, 'email':str_08, 'edit':str_09, 'login':str_10, 'log-out':str_11, 'del':str_12, 'sign-up':str_13, 'back':str_14, 'update':str_15, 'or-sign-in':str_16, 'or-sign-up':str_17, 'inv-code':str_18, 'edit-fn':str_19, 'edit-email':str_20, 'ch-pwd':str_21, 'del-account':str_22, 'welcome':str_23, 'pwd-pattern': msg_08}
self.str = {'usr':str_00, 'usrn':str_01, 'fn':str_02, 'sn':str_03, 'pwd':str_04, 'old-pwd':str_05,
'new-pwd':str_06, 'conf-pwd':str_07, 'email':str_08, 'edit':str_09, 'login':str_10, 'log-out':str_11,
'del':str_12, 'sign-up':str_13, 'back':str_14, 'update':str_15, 'or-sign-in':str_16,
'or-sign-up':str_17, 'inv-code':str_18, 'edit-fn':str_19, 'edit-email':str_20, 'ch-pwd':str_21,
'del-account':str_22, 'welcome':str_23, 'logs':str_24, 'last-login':str_25, 'devices':str_26,
'show':str_27, 'pwd-pattern': msg_08}
self.msg = (msg_00, msg_01, msg_02, msg_03, msg_04, msg_05, msg_06, msg_07, msg_08, msg_09, msg_10, msg_11, msg_12, msg_13, msg_14, msg_15, msg_16, msg_17, msg_18, msg_19, msg_20, msg_21, msg_22, msg_23, msg_24, msg_25, msg_26, msg_27, msg_28)
+142 -123
View File
@@ -9,7 +9,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-04-25 16:52+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"PO-Revision-Date: 2023-04-07 13:28+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
@@ -17,213 +17,232 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: libs/localization.py:12
msgid "User"
msgstr ""
#: libs/localization.py:13
msgid "Username"
msgstr ""
#: libs/localization.py:14
msgid "Firstname"
msgstr ""
#: libs/localization.py:15
msgid "Surname"
msgstr ""
msgid "User"
msgstr "User"
#: libs/localization.py:16
msgid "Password"
msgstr ""
msgid "Username"
msgstr "Username"
#: libs/localization.py:17
msgid "Old password"
msgstr ""
msgid "Firstname"
msgstr "Firstname"
#: libs/localization.py:18
msgid "New password"
msgstr ""
msgid "Surname"
msgstr "Surname"
#: libs/localization.py:19
msgid "Confirm password"
msgstr ""
msgid "Password"
msgstr "Password"
#: libs/localization.py:20
msgid "Email"
msgstr ""
msgid "Old password"
msgstr "Old password"
#: libs/localization.py:21
msgid "edit"
msgstr ""
msgid "New password"
msgstr "New password"
#: libs/localization.py:22
msgid "Login"
msgstr ""
msgid "Confirm password"
msgstr "Confirm password"
#: libs/localization.py:23
msgid "Logout"
msgstr ""
msgid "Email"
msgstr "Email"
#: libs/localization.py:24
msgid "Delete"
msgstr ""
msgid "edit"
msgstr "edit"
#: libs/localization.py:25
msgid "Sign Up"
msgstr ""
msgid "Login"
msgstr "Login"
#: libs/localization.py:26
msgid "Back"
msgstr ""
msgid "Logout"
msgstr "Logout"
#: libs/localization.py:27
msgid "Update"
msgstr ""
msgid "Delete"
msgstr "Delete"
#: libs/localization.py:28
msgid "Or Sign In"
msgstr ""
msgid "Sign Up"
msgstr "Sign Up"
#: libs/localization.py:29
msgid "Or Sign Up"
msgstr ""
msgid "Back"
msgstr "Back"
#: libs/localization.py:30
msgid "Invite code"
msgstr ""
msgid "Update"
msgstr "Update"
#: libs/localization.py:31
msgid "Edit your fullname"
msgstr ""
msgid "Or Sign In"
msgstr "Or Sign In"
#: libs/localization.py:32
msgid "Edit your email"
msgstr ""
msgid "Or Sign Up"
msgstr "Or Sign Up"
#: libs/localization.py:33
msgid "Change your password"
msgstr ""
msgid "Invite code"
msgstr "Invite code"
#: libs/localization.py:34
msgid "Delete your account"
msgstr ""
msgid "Edit your fullname"
msgstr "Edit your fullname"
#: libs/localization.py:35 libs/localization.py:39
#: libs/localization.py:35
msgid "Edit your email"
msgstr "Edit your email"
#: libs/localization.py:36
msgid "Change your password"
msgstr "Change your password"
#: libs/localization.py:37
msgid "Delete your account"
msgstr "Delete your account"
#: libs/localization.py:38 libs/localization.py:46
msgid "Welcome"
msgstr ""
msgstr "Welcome"
#: libs/localization.py:39
msgid "Logs"
msgstr "Logs"
#: libs/localization.py:40
msgid "The session was closed."
msgstr ""
msgid "Last login"
msgstr "Last login"
#: libs/localization.py:41
msgid "Devices"
msgstr "Devices"
#: libs/localization.py:42
msgid "Username must be at least 3 characters long!"
msgstr ""
#: libs/localization.py:43
msgid "Not allowed characters for the username field."
msgstr ""
#: libs/localization.py:44
msgid "Not allowed characters for the firstname field."
msgstr ""
msgid "show"
msgstr "show"
#: libs/localization.py:45
msgid "Not allowed characters for the surname field."
msgstr ""
#: libs/localization.py:46
msgid "The code is invalid or has expired."
msgstr ""
msgid "The session was closed."
msgstr "The session was closed."
#: libs/localization.py:47
msgid "Passwords do not match!"
msgstr ""
msgid "Username must be at least 3 characters long!"
msgstr "Username must be at least 3 characters long!"
#: libs/localization.py:48
msgid "Not allowed characters for the username field."
msgstr "Not allowed characters for the username field."
#: libs/localization.py:49
msgid "Not allowed characters for the firstname field."
msgstr "Not allowed characters for the firstname field."
#: libs/localization.py:50
msgid "Not allowed characters for the surname field."
msgstr "Not allowed characters for the surname field."
#: libs/localization.py:51
msgid "The code is invalid or has expired."
msgstr "The code is invalid or has expired."
#: libs/localization.py:52
msgid "Passwords do not match!"
msgstr "Passwords do not match!"
#: libs/localization.py:53
msgid ""
"The password must contain at least 8 characters, at least one number, "
"a capital letter and a special character."
msgstr ""
#: libs/localization.py:49
msgid "Congratulations, your account has been created!"
msgstr ""
#: libs/localization.py:50
msgid "Your first and last name have not been changed."
msgstr ""
#: libs/localization.py:51
msgid "Your firstname is a bit short, don't you think?"
msgstr ""
#: libs/localization.py:52
msgid "Your surname is a bit short, don't you think?"
msgstr ""
#: libs/localization.py:53
msgid "Your first and last name have been successfully updated."
msgstr ""
"The password must contain at least 8 characters, at least one number, "
"a capital letter and a special character."
#: libs/localization.py:54
msgid "Invalid email address. Please try again."
msgstr ""
msgid "Congratulations, your account has been created!"
msgstr "Congratulations, your account has been created!"
#: libs/localization.py:55
msgid "Email address has not been changed."
msgstr ""
msgid "Your first and last name have not been changed."
msgstr "Your first and last name have not been changed."
#: libs/localization.py:56
msgid "Your email has been successfully updated."
msgstr ""
msgid "Your firstname is a bit short, don't you think?"
msgstr "Your firstname is a bit short, don't you think?"
#: libs/localization.py:57
msgid "The password entered is the same as the current password."
msgstr ""
msgid "Your surname is a bit short, don't you think?"
msgstr "Your surname is a bit short, don't you think?"
#: libs/localization.py:58
msgid "Password has been changed!"
msgstr ""
msgid "Your first and last name have been successfully updated."
msgstr "Your first and last name have been successfully updated."
#: libs/localization.py:59
msgid "Please, type your username for account deletion."
msgstr ""
msgid "Invalid email address. Please try again."
msgstr "Invalid email address. Please try again."
#: libs/localization.py:60
msgid "Account successfully deleted!"
msgstr ""
msgid "Email address has not been changed."
msgstr "Email address has not been changed."
#: libs/localization.py:61
msgid "Username or password is incorrect!"
msgstr ""
msgid "Your email has been successfully updated."
msgstr "Your email has been successfully updated."
#: libs/localization.py:62
msgid "Unable to connect to the remote server."
msgstr ""
msgid "The password entered is the same as the current password."
msgstr "The password entered is the same as the current password."
#: libs/localization.py:63
msgid "Password has been changed!"
msgstr "Password has been changed!"
#: libs/localization.py:64
msgid "Please, type your username for account deletion."
msgstr "Please, type your username for account deletion."
#: libs/localization.py:65
msgid "Account successfully deleted!"
msgstr "Account successfully deleted!"
#: libs/localization.py:66
msgid "Username or password is incorrect!"
msgstr "Username or password is incorrect!"
#: libs/localization.py:67
msgid "Unable to connect to the remote server."
msgstr "Unable to connect to the remote server."
#: libs/localization.py:68
msgid ""
"Encountered an unexpected error while communicating with the remote server."
msgstr ""
"Encountered an unexpected error while communicating with the remote server."
#: libs/localization.py:64
#: libs/localization.py:69
msgid "User already exists."
msgstr ""
msgstr "User already exists."
#: libs/localization.py:65
#: libs/localization.py:70
msgid "Email already exists."
msgstr ""
msgstr "Email already exists."
#: libs/localization.py:66
#: libs/localization.py:71
msgid "Forgot your password? Please try again."
msgstr ""
msgstr "Forgot your password? Please try again."
#: libs/localization.py:67
#: libs/localization.py:72
msgid "The session has expired."
msgstr ""
msgstr "The session has expired."
#: libs/localization.py:68
#: libs/localization.py:73
msgid "Registration is currently closed. We apologize for the inconvenience."
msgstr ""
msgstr "Registration is currently closed. We apologize for the inconvenience."
Binary file not shown.
+69 -53
View File
@@ -8,140 +8,156 @@ msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-04-07 17:20+0200\n"
"PO-Revision-Date: 2022-04-25 17:15+0200\n"
"PO-Revision-Date: 2023-04-07 13:28+0200\n"
"Last-Translator: Aitzol Berasategi <aitzol@lainoa.eus>\n"
"Language-Team: LANGUAGE <EN@en.org>\n"
"Language: eu\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.3\n"
#: libs/localization.py:12
#: libs/localization.py:15
msgid "User"
msgstr "User"
#: libs/localization.py:13
#: libs/localization.py:16
msgid "Username"
msgstr "Username"
#: libs/localization.py:14
#: libs/localization.py:17
msgid "Firstname"
msgstr "Firstname"
#: libs/localization.py:15
#: libs/localization.py:18
msgid "Surname"
msgstr "Surname"
#: libs/localization.py:16
#: libs/localization.py:19
msgid "Password"
msgstr "Password"
#: libs/localization.py:17
#: libs/localization.py:20
msgid "Old password"
msgstr "Old password"
#: libs/localization.py:18
#: libs/localization.py:21
msgid "New password"
msgstr "New password"
#: libs/localization.py:19
#: libs/localization.py:22
msgid "Confirm password"
msgstr "Confirm password"
#: libs/localization.py:20
#: libs/localization.py:23
msgid "Email"
msgstr "Email"
#: libs/localization.py:21
#: libs/localization.py:24
msgid "edit"
msgstr "edit"
#: libs/localization.py:22
#: libs/localization.py:25
msgid "Login"
msgstr "Login"
#: libs/localization.py:23
#: libs/localization.py:26
msgid "Logout"
msgstr "Logout"
#: libs/localization.py:24
#: libs/localization.py:27
msgid "Delete"
msgstr "Delete"
#: libs/localization.py:25
#: libs/localization.py:28
msgid "Sign Up"
msgstr "Sign Up"
#: libs/localization.py:26
#: libs/localization.py:29
msgid "Back"
msgstr "Back"
#: libs/localization.py:27
#: libs/localization.py:30
msgid "Update"
msgstr "Update"
#: libs/localization.py:28
#: libs/localization.py:31
msgid "Or Sign In"
msgstr "Or Sign In"
#: libs/localization.py:29
#: libs/localization.py:32
msgid "Or Sign Up"
msgstr "Or Sign Up"
#: libs/localization.py:30
#: libs/localization.py:33
msgid "Invite code"
msgstr "Invite code"
#: libs/localization.py:31
#: libs/localization.py:34
msgid "Edit your fullname"
msgstr "Edit your fullname"
#: libs/localization.py:32
#: libs/localization.py:35
msgid "Edit your email"
msgstr "Edit your email"
#: libs/localization.py:33
#: libs/localization.py:36
msgid "Change your password"
msgstr "Change your password"
#: libs/localization.py:34
#: libs/localization.py:37
msgid "Delete your account"
msgstr "Delete your account"
#: libs/localization.py:35 libs/localization.py:39
#: libs/localization.py:38 libs/localization.py:46
msgid "Welcome"
msgstr "Welcome"
#: libs/localization.py:39
msgid "Logs"
msgstr "Logs"
#: libs/localization.py:40
msgid "Last login"
msgstr "Last login"
#: libs/localization.py:41
msgid "Devices"
msgstr "Devices"
#: libs/localization.py:42
msgid "show"
msgstr "show"
#: libs/localization.py:45
msgid "The session was closed."
msgstr "The session was closed."
#: libs/localization.py:42
#: libs/localization.py:47
msgid "Username must be at least 3 characters long!"
msgstr "Username must be at least 3 characters long!"
#: libs/localization.py:43
#: libs/localization.py:48
msgid "Not allowed characters for the username field."
msgstr "Not allowed characters for the username field."
#: libs/localization.py:44
#: libs/localization.py:49
msgid "Not allowed characters for the firstname field."
msgstr "Not allowed characters for the firstname field."
#: libs/localization.py:45
#: libs/localization.py:50
msgid "Not allowed characters for the surname field."
msgstr "Not allowed characters for the surname field."
#: libs/localization.py:46
#: libs/localization.py:51
msgid "The code is invalid or has expired."
msgstr "The code is invalid or has expired."
#: libs/localization.py:47
#: libs/localization.py:52
msgid "Passwords do not match!"
msgstr "Passwords do not match!"
#: libs/localization.py:48
#: libs/localization.py:53
msgid ""
"The password must contain at least 8 characters, at least one number, "
"a capital letter and a special character."
@@ -149,84 +165,84 @@ msgstr ""
"The password must contain at least 8 characters, at least one number, "
"a capital letter and a special character."
#: libs/localization.py:49
#: libs/localization.py:54
msgid "Congratulations, your account has been created!"
msgstr "Congratulations, your account has been created!"
#: libs/localization.py:50
#: libs/localization.py:55
msgid "Your first and last name have not been changed."
msgstr "Your first and last name have not been changed."
#: libs/localization.py:51
#: libs/localization.py:56
msgid "Your firstname is a bit short, don't you think?"
msgstr "Your firstname is a bit short, don't you think?"
#: libs/localization.py:52
#: libs/localization.py:57
msgid "Your surname is a bit short, don't you think?"
msgstr "Your surname is a bit short, don't you think?"
#: libs/localization.py:53
#: libs/localization.py:58
msgid "Your first and last name have been successfully updated."
msgstr "Your first and last name have been successfully updated."
#: libs/localization.py:54
#: libs/localization.py:59
msgid "Invalid email address. Please try again."
msgstr "Invalid email address. Please try again."
#: libs/localization.py:55
#: libs/localization.py:60
msgid "Email address has not been changed."
msgstr "Email address has not been changed."
#: libs/localization.py:56
#: libs/localization.py:61
msgid "Your email has been successfully updated."
msgstr "Your email has been successfully updated."
#: libs/localization.py:57
#: libs/localization.py:62
msgid "The password entered is the same as the current password."
msgstr "The password entered is the same as the current password."
#: libs/localization.py:58
#: libs/localization.py:63
msgid "Password has been changed!"
msgstr "Password has been changed!"
#: libs/localization.py:59
#: libs/localization.py:64
msgid "Please, type your username for account deletion."
msgstr "Please, type your username for account deletion."
#: libs/localization.py:60
#: libs/localization.py:65
msgid "Account successfully deleted!"
msgstr "Account successfully deleted!"
#: libs/localization.py:61
#: libs/localization.py:66
msgid "Username or password is incorrect!"
msgstr "Username or password is incorrect!"
#: libs/localization.py:62
#: libs/localization.py:67
msgid "Unable to connect to the remote server."
msgstr "Unable to connect to the remote server."
#: libs/localization.py:63
#: libs/localization.py:68
msgid ""
"Encountered an unexpected error while communicating with the remote server."
msgstr ""
"Encountered an unexpected error while communicating with the remote server."
#: libs/localization.py:64
#: libs/localization.py:69
msgid "User already exists."
msgstr "User already exists."
#: libs/localization.py:65
#: libs/localization.py:70
msgid "Email already exists."
msgstr "Email already exists."
#: libs/localization.py:66
#: libs/localization.py:71
msgid "Forgot your password? Please try again."
msgstr "Forgot your password? Please try again."
#: libs/localization.py:67
#: libs/localization.py:72
msgid "The session has expired."
msgstr "The session has expired."
#: libs/localization.py:68
#: libs/localization.py:73
msgid "Registration is currently closed. We apologize for the inconvenience."
msgstr "Registration is currently closed. We apologize for the inconvenience."
Binary file not shown.
+68 -52
View File
@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-04-07 17:23+0200\n"
"PO-Revision-Date: 2022-04-25 17:10+0200\n"
"PO-Revision-Date: 2023-04-07 13:27+0200\n"
"Last-Translator: Aitzol Berasategi <aitzol@lainoa.eus>\n"
"Language-Team: LANGUAGE <EU@eu.org>\n"
"Language: eu\n"
@@ -17,131 +17,147 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.3\n"
#: libs/localization.py:12
#: libs/localization.py:15
msgid "User"
msgstr "Erabiltzailea"
#: libs/localization.py:13
#: libs/localization.py:16
msgid "Username"
msgstr "Erabiltzailea"
#: libs/localization.py:14
#: libs/localization.py:17
msgid "Firstname"
msgstr "Izena"
#: libs/localization.py:15
#: libs/localization.py:18
msgid "Surname"
msgstr "Abizena"
#: libs/localization.py:16
#: libs/localization.py:19
msgid "Password"
msgstr "Pasahitza"
#: libs/localization.py:17
#: libs/localization.py:20
msgid "Old password"
msgstr "Pasahitz zaharra"
#: libs/localization.py:18
#: libs/localization.py:21
msgid "New password"
msgstr "Pasahitz berria"
#: libs/localization.py:19
#: libs/localization.py:22
msgid "Confirm password"
msgstr "Pasahitza berretsi"
#: libs/localization.py:20
#: libs/localization.py:23
msgid "Email"
msgstr "Emaila"
#: libs/localization.py:21
#: libs/localization.py:24
msgid "edit"
msgstr "editatu"
#: libs/localization.py:22
#: libs/localization.py:25
msgid "Login"
msgstr "Saioa hasi"
#: libs/localization.py:23
#: libs/localization.py:26
msgid "Logout"
msgstr "Saioa itxi"
#: libs/localization.py:24
#: libs/localization.py:27
msgid "Delete"
msgstr "Ezabatu"
#: libs/localization.py:25
#: libs/localization.py:28
msgid "Sign Up"
msgstr "Kontua sortu"
#: libs/localization.py:26
#: libs/localization.py:29
msgid "Back"
msgstr "Itzuli"
#: libs/localization.py:27
#: libs/localization.py:30
msgid "Update"
msgstr "Eguneratu"
#: libs/localization.py:28
#: libs/localization.py:31
msgid "Or Sign In"
msgstr "Edo Saioa hasi"
#: libs/localization.py:29
#: libs/localization.py:32
msgid "Or Sign Up"
msgstr "Edo Kontua sortu"
#: libs/localization.py:30
#: libs/localization.py:33
msgid "Invite code"
msgstr "Gonbidapen kodea"
#: libs/localization.py:31
#: libs/localization.py:34
msgid "Edit your fullname"
msgstr "Izen-abizenak editatu"
#: libs/localization.py:32
#: libs/localization.py:35
msgid "Edit your email"
msgstr "Email helbidea editatu"
#: libs/localization.py:33
#: libs/localization.py:36
msgid "Change your password"
msgstr "Pasahitza eguneratu"
#: libs/localization.py:34
#: libs/localization.py:37
msgid "Delete your account"
msgstr "Kontua ezabatu"
#: libs/localization.py:35 libs/localization.py:41
#: libs/localization.py:38 libs/localization.py:46
msgid "Welcome"
msgstr "Ongi etorri"
#: libs/localization.py:39
msgid "Logs"
msgstr "Erregistroak"
#: libs/localization.py:40
msgid "Last login"
msgstr "Azken saio hasiera"
#: libs/localization.py:41
msgid "Devices"
msgstr "Gailuak"
#: libs/localization.py:42
msgid "show"
msgstr "ikusi"
#: libs/localization.py:45
msgid "The session was closed."
msgstr "Saioa itxi da."
#: libs/localization.py:42
#: libs/localization.py:47
msgid "Username must be at least 3 characters long!"
msgstr "Erabiltzaile izenak gutxienez 3 karaktere izan behar ditu!"
#: libs/localization.py:43
#: libs/localization.py:48
msgid "Not allowed characters for the username field."
msgstr "Erabiltzaile-izenaren eremurako onartzen ez diren karaktereak."
#: libs/localization.py:44
#: libs/localization.py:49
msgid "Not allowed characters for the firstname field."
msgstr "Izenaren eremurako onartzen ez diren karaktereak."
#: libs/localization.py:45
#: libs/localization.py:50
msgid "Not allowed characters for the surname field."
msgstr "Abizenaren eremurako onartzen ez diren karaktereak."
#: libs/localization.py:46
#: libs/localization.py:51
msgid "The code is invalid or has expired."
msgstr "Kodea baliogabea da edo iraungi egin da."
#: libs/localization.py:47
#: libs/localization.py:52
msgid "Passwords do not match!"
msgstr "Pasahitzak ez datoz bat!"
#: libs/localization.py:48
#: libs/localization.py:53
msgid ""
"The password must contain at least 8 characters, at least one number, "
"a capital letter and a special character."
@@ -149,83 +165,83 @@ msgstr ""
"Pasahitzak gutxienez 8 karaktere izan behar ditu, zenbaki bat, hizki larri bat "
"eta karaktere berezi bat."
#: libs/localization.py:49
#: libs/localization.py:54
msgid "Congratulations, your account has been created!"
msgstr "Zorionak, zure kontua sortu da!"
#: libs/localization.py:50
#: libs/localization.py:55
msgid "Your first and last name have not been changed."
msgstr "Zure izen-abizenak ez dira aldatu."
#: libs/localization.py:51
#: libs/localization.py:56
msgid "Your firstname is a bit short, don't you think?"
msgstr "Zure izena labur-xamarra da, ez duzu uste?"
#: libs/localization.py:52
#: libs/localization.py:57
msgid "Your surname is a bit short, don't you think?"
msgstr "Zure abizena labur-xamarra da, ez duzu uste?"
#: libs/localization.py:53
#: libs/localization.py:58
msgid "Your first and last name have been successfully updated."
msgstr "Zure izen-abizenak ongi eguneratu dira."
#: libs/localization.py:54
#: libs/localization.py:59
msgid "Invalid email address. Please try again."
msgstr "Baliogabeko email helbidea. Saia zaitez berriz, mesedez."
#: libs/localization.py:55
#: libs/localization.py:60
msgid "Email address has not been changed."
msgstr "Email helbidea ez da aldatu."
#: libs/localization.py:56
#: libs/localization.py:61
msgid "Your email has been successfully updated."
msgstr "Zure emaila ongi eguneratu da."
#: libs/localization.py:57
#: libs/localization.py:62
msgid "The password entered is the same as the current password."
msgstr "Sartutako pasahitza egungo pasahitzaren berdina da."
#: libs/localization.py:58
#: libs/localization.py:63
msgid "Password has been changed!"
msgstr "Pasahitza eguneratua izan da!"
#: libs/localization.py:59
#: libs/localization.py:64
msgid "Please, type your username for account deletion."
msgstr "Kontua ezabatzeko idatzi zure erabiltzaile izena, mesedez."
#: libs/localization.py:60
#: libs/localization.py:65
msgid "Account successfully deleted!"
msgstr "Kontua ongi ezabatu da!"
#: libs/localization.py:61
#: libs/localization.py:66
msgid "Username or password is incorrect!"
msgstr "Erabiltzaile izena edo pasahitza okerrak dira!"
#: libs/localization.py:62
#: libs/localization.py:67
msgid "Unable to connect to the remote server."
msgstr "Ezinezkoa urruneko zerbitzara konektatzea."
#: libs/localization.py:63
#: libs/localization.py:68
msgid ""
"Encountered an unexpected error while communicating with the remote server."
msgstr "Ezusteko errore bat gertatu da urruneko zerbitzariarekin komunikatzean."
#: libs/localization.py:64
#: libs/localization.py:69
msgid "User already exists."
msgstr "Erabiltzaile hori existitzen da."
#: libs/localization.py:65
#: libs/localization.py:70
msgid "Email already exists."
msgstr "Email hori existitzen da."
#: libs/localization.py:66
#: libs/localization.py:71
msgid "Forgot your password? Please try again."
msgstr "Zure pasahitza ahaztu duzu? Saia zeitez berriz, mesedez."
#: libs/localization.py:67
#: libs/localization.py:72
msgid "The session has expired."
msgstr "Saioa iraungi egin da."
#: libs/localization.py:68
#: libs/localization.py:73
msgid "Registration is currently closed. We apologize for the inconvenience."
msgstr "Izen-ematea itxita dago une honetan. Barkatu eragozpenak."
+46
View File
@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex, nofollow">
<title>{{ str['logs'] }}</title>
<link rel="stylesheet" href="{{ url('static', filename='style.css') }}">
</head>
<body>
<main>
<h1>{{ str['logs'] }}</h1>
<div class="logs">
<div class="last-login">
<h5>{{ str['last-login'] }}</h5>
<div class="last-login-info">
<p>{{ data['ip'] }}</p>
<p class="date">{{ data['lastLogin'] }}</p>
</div>
</div>
<div class="device-list">
<h5>{{ str['devices'] }}</h5>
%for device in data['devices']:
<li>{{ device }}</li>
%end
</div>
<div class="form-buttons">
<a href="/user"><button class="green" type="button">{{ str['back'] }}</button></a>
</div>
</div>
%for type, text, animation in get('alerts', []):
<div class="alerts {{ animation }}">
<div class="alert {{ type }}">{{ text }}</div>
</div>
%end
</main>
</body>
</html>
Executable
+11
View File
@@ -0,0 +1,11 @@
#!/bin/bash
if [ ! -f settings.ini ]; then
cp settings.ini.example settings.ini
fi
if [[ $# -gt 0 ]]; then
UID_=$1
echo $UID_
fi
uwsgi --http :9090 --enable-threads --uid $UID_ --wsgi-file app.py
+23 -1
View File
@@ -35,7 +35,7 @@ form[name="fullNameForm"] input{
}
form {
form, .logs {
/* border-radius: 0.2rem;
border: 1px solid #CCC;*/
margin: 0 auto;
@@ -127,6 +127,28 @@ button.red:hover{
border-color: #C92F1E;
}
.last-login-info {
background-color: #efefef;
/*background-image: linear-gradient(#fcfcfc, #f5f5f5);*/
background-image: linear-gradient(#f9e028, #ffd966);
padding-top: 1px;
padding-bottom: 1px;
border-radius: 0.2rem;
text-align: center;
}
.date {
font-weight: 100;
font-size: 0.8em;
}
.device-list li{
background-color: #efefef;
background-image: linear-gradient(#fcfcfc, #f6f6f6);
list-style: none;
font-size: 0.7em;
margin-bottom: 2px;
padding: 2px;
border-radius: 0.2rem;
}
/*alerts*/
.alerts {
+2 -2
View File
@@ -53,12 +53,12 @@
<div class="grid-item">
<div class="account">
<h5>Erregistroak</h5>
<h5>{{ str['logs'] }}</h5>
</div>
</div>
<div class="grid-item">
<a href="/change_pwd">ikusi</a>
<a href="/logs">{{ str['show'] }}</a>
</div>