Files
iRedAdmin-Pro-SQL/libs/sqllib/auth.py
2023-04-10 07:18:32 +02:00

139 lines
5.1 KiB
Python

import web
import settings
from libs import iredutils, iredpwd
from libs.l10n import TIMEZONES
from libs.sqllib import sqlutils
session = web.config.get('_session', {})
def auth(conn,
username,
password,
account_type='admin',
verify_password=False):
if not iredutils.is_email(username):
return False, 'INVALID_USERNAME'
if not password:
return False, 'EMPTY_PASSWORD'
username = str(username).lower()
password = str(password)
domain = username.split('@', 1)[-1]
# Query account from SQL database.
if account_type == 'admin':
# separate admin accounts
result = conn.select('admin',
vars={'username': username},
where="username=$username AND active=1",
what='password, language, settings',
limit=1)
# mail user marked as domain admin
if not result:
result = conn.select(
["mailbox", "domain"],
vars={'username': username},
where="mailbox.username=$username AND mailbox.active=1 AND (mailbox.isadmin=1 OR mailbox.isglobaladmin=1) AND mailbox.domain=domain.domain and domain.active=1",
what='mailbox.password, mailbox.language, mailbox.isadmin, mailbox.isglobaladmin, mailbox.settings',
limit=1,
)
if result:
session['admin_is_mail_user'] = True
elif account_type == 'user':
result = conn.select('mailbox',
vars={'username': username},
what='password, language, isadmin, isglobaladmin, settings',
where="username=$username AND active=1",
limit=1)
else:
return False, 'INVALID_ACCOUNT_TYPE'
if not result:
# Account not found.
# Do NOT return msg like 'Account does not ***EXIST***', crackers
# can use it to verify valid accounts.
return False, 'INVALID_CREDENTIALS'
record = result[0]
password_sql = str(record.password)
account_settings = sqlutils.account_settings_string_to_dict(str(record.settings))
# Verify password
if not iredpwd.verify_password_hash(password_sql, password):
return False, 'INVALID_CREDENTIALS'
if not verify_password:
session['username'] = username
if account_type == 'user':
session['account_is_mail_user'] = True
# Set preferred language.
session['lang'] = web.safestr(record.get('language', settings.default_language))
# Set timezone (GMT-XX:XX).
# Priority: per-user timezone > per-domain > global setting
timezone = settings.LOCAL_TIMEZONE
if 'timezone' in account_settings:
tz_name = account_settings['timezone']
if tz_name in TIMEZONES:
timezone = TIMEZONES[tz_name]
else:
# Get per-domain timezone
qr_domain = conn.select('domain',
vars={'domain': domain},
what='settings',
where='domain=$domain',
limit=1)
if qr_domain:
domain_settings = sqlutils.account_settings_string_to_dict(str(qr_domain[0]['settings']))
if 'timezone' in domain_settings:
tz_name = domain_settings['timezone']
if tz_name in TIMEZONES:
timezone = TIMEZONES[tz_name]
session['timezone'] = timezone
# Set session['is_global_admin']
if session.get('admin_is_mail_user'):
if record.get('isglobaladmin', 0) == 1:
session['is_global_admin'] = True
else:
session['is_normal_admin'] = True
# Set session['allowed_to_grant_admin']
if 'grant_admin' in account_settings:
session['allowed_to_grant_admin'] = True
else:
try:
result = conn.select('domain_admins',
vars={'username': username, 'domain': 'ALL'},
what='domain',
where='username=$username AND domain=$domain',
limit=1)
if result:
session['is_global_admin'] = True
else:
if account_type == 'admin':
session['is_normal_admin'] = True
except:
pass
if session['is_global_admin']:
if not iredutils.is_allowed_global_admin_login_ip(client_ip=web.ctx.ip):
session.kill()
raise web.seeother('/login?msg=NOT_ALLOWED_IP')
session['logged'] = True
web.config.session_parameters['cookie_name'] = 'iRedAdmin-Pro'
web.config.session_parameters['ignore_change_ip'] = settings.SESSION_IGNORE_CHANGE_IP
web.config.session_parameters['ignore_expiry'] = False
return True, {'account_settings': account_settings}