1
0
mirror of https://github.com/mail-in-a-box/mailinabox.git synced 2025-04-03 00:07:05 +00:00

Merge remote-tracking branch 'fspoettel/admin-panel-2fa' into totp

# Conflicts:
#	management/daemon.py
#	management/mfa.py
#	setup/mail-users.sh
This commit is contained in:
downtownallday 2020-09-29 22:20:15 -04:00
commit 5deb88ab60
5 changed files with 29 additions and 8 deletions

View File

@ -2637,10 +2637,6 @@ components:
type: string
type:
type: string
secret:
type: string
mru_token:
type: string
label:
type: string
nullable: true
@ -2681,4 +2677,4 @@ components:
type: string
nullable: true
MfaDisableSuccessResponse:
type: string
type: string

View File

@ -9,7 +9,7 @@ import auth, utils, mfa
from mailconfig import get_mail_users, get_mail_users_ex, get_admins, add_mail_user, set_mail_password, set_mail_display_name, remove_mail_user
from mailconfig import get_mail_user_privileges, add_remove_mail_user_privilege
from mailconfig import get_mail_aliases, get_mail_aliases_ex, get_mail_domains, add_mail_alias, remove_mail_alias
from mfa import get_mfa_state, enable_mfa, disable_mfa
from mfa import get_public_mfa_state, enable_mfa, disable_mfa
import mfa_totp
env = utils.load_environment()
@ -413,7 +413,7 @@ def ssl_provision_certs():
@authorized_personnel_only
def mfa_get_status():
return json_response({
"enabled_mfa": get_mfa_state(request.user_email, env),
"enabled_mfa": get_public_mfa_state(request.user_email, env),
"new_mfa": {
"totp": mfa_totp.provision(request.user_email, env)
}

View File

@ -57,6 +57,19 @@ def get_mfa_state(email, env):
state_list += mfa_totp.get_state(user)
return state_list
def get_public_mfa_state(email, env):
'''return details about what MFA schemes are enabled for a user
ordered by the priority that the scheme will be tried, with index
zero being the first. No secrets are returned by this function -
only those details that are needed by the end user to identify a
particular MFA by label and the id of each so it may be disabled.
'''
user = get_mfa_user(email, env)
state_list = []
state_list += mfa_totp.get_public_state(user)
return state_list
def enable_mfa(email, type, secret, token, label, env):
'''enable MFA using the scheme specified in `type`. users may have
multiple mfa schemes enabled of the same type.

View File

@ -45,6 +45,18 @@ def get_state(user):
})
return state_list
def get_public_state(user):
state_list = []
# totp
for idx in range(0, len(user['totpSecret'])):
state_list.append({
'id': totp_id_from_index(user, idx),
'type': 'totp',
'label': user['totpLabel'][idx]
})
return state_list
def enable(user, secret, token, label, env):
validate_secret(secret)
# Sanity check with the provide current token.

View File

@ -185,7 +185,7 @@ def migration_12(env):
def migration_13(env):
# Add the "mfa" table for configuring MFA for login to the control panel.
db = os.path.join(env["STORAGE_ROOT"], 'mail/users.sqlite')
shell("check_call", ["sqlite3", db, "CREATE TABLE mfa (id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER NOT NULL UNIQUE, type TEXT NOT NULL, secret TEXT NOT NULL, mru_token TEXT, label TEXT, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE);"])
shell("check_call", ["sqlite3", db, "CREATE TABLE mfa (id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER NOT NULL, type TEXT NOT NULL, secret TEXT NOT NULL, mru_token TEXT, label TEXT, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE);"])
###########################################################