mirror of
https://github.com/Yubico/yubiadmin.git
synced 2025-02-27 08:54:15 +01:00
Delay import of YubiAuth until needed (fixes #3).
This commit is contained in:
parent
8e0169263f
commit
4ac015e0e6
@ -3,5 +3,6 @@ include COPYING
|
|||||||
include NEWS
|
include NEWS
|
||||||
include ChangeLog
|
include ChangeLog
|
||||||
include bin/*.1
|
include bin/*.1
|
||||||
|
include conf/*
|
||||||
recursive-include yubiadmin/static *
|
recursive-include yubiadmin/static *
|
||||||
recursive-include yubiadmin/templates *
|
recursive-include yubiadmin/templates *
|
||||||
|
4
NEWS
4
NEWS
@ -1,3 +1,7 @@
|
|||||||
|
* Version 0.1.6 (unreleased)
|
||||||
|
|
||||||
|
* Added LDAP settings to YubiAuth.
|
||||||
|
|
||||||
* Version 0.1.5 (released 2013-06-07)
|
* Version 0.1.5 (released 2013-06-07)
|
||||||
|
|
||||||
* Fixed YubiAuth user management which sometimes failed due to database
|
* Fixed YubiAuth user management which sometimes failed due to database
|
||||||
|
21
conf/logging.conf
Normal file
21
conf/logging.conf
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
[loggers]
|
||||||
|
keys=root
|
||||||
|
|
||||||
|
[logger_root]
|
||||||
|
level=INFO
|
||||||
|
handlers=fileHandler
|
||||||
|
|
||||||
|
[formatters]
|
||||||
|
keys=formatter
|
||||||
|
|
||||||
|
[handlers]
|
||||||
|
keys=fileHandler
|
||||||
|
|
||||||
|
[formatter_formatter]
|
||||||
|
format=[%(levelname)s] %(asctime)s %(name)s: %(message)s
|
||||||
|
datefmt=%Y-%m-%d %I:%M:%S
|
||||||
|
|
||||||
|
[handler_fileHandler]
|
||||||
|
class=handlers.WatchedFileHandler
|
||||||
|
formatter=formatter
|
||||||
|
args=("/var/log/yubiadmin.log",)
|
2
setup.py
2
setup.py
@ -32,7 +32,7 @@ from release import release
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='yubiadmin',
|
name='yubiadmin',
|
||||||
version='0.1.5',
|
version='0.1.6',
|
||||||
author='Dain Nilsson',
|
author='Dain Nilsson',
|
||||||
author_email='dain@yubico.com',
|
author_email='dain@yubico.com',
|
||||||
maintainer='Yubico Open Source Maintainers',
|
maintainer='Yubico Open Source Maintainers',
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import requests
|
import requests
|
||||||
|
import imp
|
||||||
from wtforms import Form
|
from wtforms import Form
|
||||||
from wtforms.fields import (SelectField, TextField, BooleanField, IntegerField,
|
from wtforms.fields import (SelectField, TextField, BooleanField, IntegerField,
|
||||||
PasswordField)
|
PasswordField)
|
||||||
@ -39,17 +40,16 @@ from yubiadmin.util.config import (python_handler, python_list_handler,
|
|||||||
FileConfig)
|
FileConfig)
|
||||||
from yubiadmin.util.form import ConfigForm, FileForm, ListField
|
from yubiadmin.util.form import ConfigForm, FileForm, ListField
|
||||||
from yubiadmin.apps.dashboard import panel
|
from yubiadmin.apps.dashboard import panel
|
||||||
import logging as log
|
import logging
|
||||||
try:
|
|
||||||
from yubiauth import YubiAuth
|
|
||||||
except:
|
|
||||||
YubiAuth = None
|
|
||||||
User = None
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'app'
|
'app'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
YUBIAUTH_INSTALLED = imp.find_module('yubiauth')
|
||||||
|
YubiAuth = None
|
||||||
|
|
||||||
AUTH_CONFIG_FILE = '/etc/yubico/auth/yubiauth.conf'
|
AUTH_CONFIG_FILE = '/etc/yubico/auth/yubiauth.conf'
|
||||||
YKVAL_SERVERS = [
|
YKVAL_SERVERS = [
|
||||||
@ -150,24 +150,39 @@ class SecurityForm(ConfigForm):
|
|||||||
|
|
||||||
class HSMForm(ConfigForm):
|
class HSMForm(ConfigForm):
|
||||||
legend = 'YubiHSM'
|
legend = 'YubiHSM'
|
||||||
description = 'Settings for the YubiHSM hardware device'
|
description = 'Settings for the YubiHSM hardware device.'
|
||||||
config = auth_config
|
config = auth_config
|
||||||
|
|
||||||
use_hsm = BooleanField(
|
use_hsm = BooleanField(
|
||||||
'Use a YubiHSM',
|
'Use a YubiHSM',
|
||||||
description='Check this if you have a YubiHSM to be used by YubiAuth.'
|
description="""
|
||||||
|
Check this if you have a YubiHSM to be used by YubiAuth for more
|
||||||
|
secure local password validation.
|
||||||
|
"""
|
||||||
)
|
)
|
||||||
hsm_device = TextField('YubiHSM device')
|
hsm_device = TextField('YubiHSM device')
|
||||||
|
|
||||||
|
|
||||||
class LDAPForm(ConfigForm):
|
class LDAPForm(ConfigForm):
|
||||||
legend = 'LDAP authentication'
|
legend = 'LDAP authentication'
|
||||||
descripting = 'Settings for authenticating users against an LDAP server.'
|
description = """
|
||||||
|
Settings for authenticating users against an LDAP server. When LDAP
|
||||||
|
authentication is used only users that exist on the LDAP server will be
|
||||||
|
permitted to log in, and password validatoin will be delegated to the LDAP
|
||||||
|
server.
|
||||||
|
"""
|
||||||
config = auth_config
|
config = auth_config
|
||||||
|
attrs = {
|
||||||
|
'ldap_server': {'class': 'input-xxlarge'},
|
||||||
|
'ldap_bind_dn': {'class': 'input-xxlarge'}
|
||||||
|
}
|
||||||
|
|
||||||
use_ldap = BooleanField(
|
use_ldap = BooleanField(
|
||||||
'Authenticate users against LDAP',
|
'Authenticate users against LDAP',
|
||||||
description='Check this to authenticate users passwords against LDAP.'
|
description="""
|
||||||
|
Check this to authenticate users passwords externally against an LDAP
|
||||||
|
server.
|
||||||
|
"""
|
||||||
)
|
)
|
||||||
ldap_server = TextField('LDAP server URL')
|
ldap_server = TextField('LDAP server URL')
|
||||||
ldap_bind_dn = TextField('Bind DN for user authentication')
|
ldap_bind_dn = TextField('Bind DN for user authentication')
|
||||||
@ -262,6 +277,11 @@ def using_default_client():
|
|||||||
auth_config['client_secret'] == YKVAL_DEFAULT_SECRET
|
auth_config['client_secret'] == YKVAL_DEFAULT_SECRET
|
||||||
|
|
||||||
|
|
||||||
|
def using_ldap():
|
||||||
|
auth_config.read()
|
||||||
|
return auth_config['use_ldap']
|
||||||
|
|
||||||
|
|
||||||
class YubiAuthApp(App):
|
class YubiAuthApp(App):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -271,7 +291,6 @@ class YubiAuthApp(App):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
name = 'auth'
|
name = 'auth'
|
||||||
sections = ['general', 'database', 'validation', 'advanced']
|
|
||||||
priority = 40
|
priority = 40
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -280,19 +299,19 @@ class YubiAuthApp(App):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def sections(self):
|
def sections(self):
|
||||||
if not YubiAuth:
|
base = ['general', 'database', 'password', 'otp']
|
||||||
return ['general', 'database', 'validation', 'advanced']
|
if YUBIAUTH_INSTALLED:
|
||||||
return ['general', 'database', 'validation', 'users', 'advanced']
|
return base + ['users', 'advanced']
|
||||||
|
return base + ['advanced']
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def dash_panels(self):
|
def dash_panels(self):
|
||||||
if using_default_client():
|
if using_default_client():
|
||||||
yield panel('YubiAuth', 'Using default YubiCloud client!',
|
yield panel('YubiAuth', 'Using default YubiCloud client!',
|
||||||
'/%s/validation' % self.name, 'danger')
|
'/%s/otp' % self.name, 'danger')
|
||||||
|
|
||||||
def general(self, request):
|
def general(self, request):
|
||||||
return self.render_forms(request,
|
return self.render_forms(request, [SecurityForm()],
|
||||||
[SecurityForm(), LDAPForm(), HSMForm()],
|
|
||||||
template='auth/general')
|
template='auth/general')
|
||||||
|
|
||||||
def reload(self, request):
|
def reload(self, request):
|
||||||
@ -302,9 +321,9 @@ class YubiAuthApp(App):
|
|||||||
def database(self, request):
|
def database(self, request):
|
||||||
return self.render_forms(request, [DatabaseForm()])
|
return self.render_forms(request, [DatabaseForm()])
|
||||||
|
|
||||||
def validation(self, request):
|
def otp(self, request):
|
||||||
"""
|
"""
|
||||||
Validation Server(s)
|
OTP Validation
|
||||||
"""
|
"""
|
||||||
form = ValidationServerForm()
|
form = ValidationServerForm()
|
||||||
resp = self.render_forms(request, [form])
|
resp = self.render_forms(request, [form])
|
||||||
@ -320,6 +339,12 @@ class YubiAuthApp(App):
|
|||||||
})
|
})
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
|
def password(self, request):
|
||||||
|
"""
|
||||||
|
Password Validation
|
||||||
|
"""
|
||||||
|
return self.render_forms(request, [LDAPForm(), HSMForm()])
|
||||||
|
|
||||||
def getapikey(self, request):
|
def getapikey(self, request):
|
||||||
return self.render_forms(request, [GetApiKeyForm()], success_msg=
|
return self.render_forms(request, [GetApiKeyForm()], success_msg=
|
||||||
"API Key registered!")
|
"API Key registered!")
|
||||||
@ -333,9 +358,11 @@ class YubiAuthApp(App):
|
|||||||
"""
|
"""
|
||||||
Manage Users
|
Manage Users
|
||||||
"""
|
"""
|
||||||
global User
|
global YubiAuth, User
|
||||||
if User is None:
|
if YubiAuth is None:
|
||||||
|
from yubiauth import YubiAuth as _yubiauth
|
||||||
from yubiauth.core.model import User as _user
|
from yubiauth.core.model import User as _user
|
||||||
|
YubiAuth = _yubiauth
|
||||||
User = _user
|
User = _user
|
||||||
|
|
||||||
with YubiAuth() as auth:
|
with YubiAuth() as auth:
|
||||||
@ -388,6 +415,11 @@ class SetPasswordForm(Form):
|
|||||||
self.verify.data = None
|
self.verify.data = None
|
||||||
|
|
||||||
|
|
||||||
|
class SetPasswordDisabledForm(Form):
|
||||||
|
legend = 'Change Password'
|
||||||
|
description = 'Cannot change password when using LDAP for authentication.'
|
||||||
|
|
||||||
|
|
||||||
class AssignYubiKeyForm(Form):
|
class AssignYubiKeyForm(Form):
|
||||||
legend = 'Assign YubiKey'
|
legend = 'Assign YubiKey'
|
||||||
assign = TextField('Assign YubiKey',
|
assign = TextField('Assign YubiKey',
|
||||||
@ -459,10 +491,10 @@ class YubiAuthUsers(CollectionApp):
|
|||||||
msg = 'YubiKey assigned!'
|
msg = 'YubiKey assigned!'
|
||||||
elif request.params.get('unassign', None):
|
elif request.params.get('unassign', None):
|
||||||
msg = 'YubiKey unassigned!'
|
msg = 'YubiKey unassigned!'
|
||||||
return self.render_forms(request,
|
pwd_form = SetPasswordDisabledForm() if using_ldap() else \
|
||||||
[SetPasswordForm(user.id),
|
SetPasswordForm(user.id)
|
||||||
AssignYubiKeyForm(user.id)],
|
forms = [pwd_form, AssignYubiKeyForm(user.id)]
|
||||||
'auth/user', user=user.data,
|
return self.render_forms(request, forms, 'auth/user', user=user.data,
|
||||||
success_msg=msg)
|
success_msg=msg)
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,6 +29,8 @@ import sys
|
|||||||
import os
|
import os
|
||||||
import imp
|
import imp
|
||||||
import errno
|
import errno
|
||||||
|
import logging
|
||||||
|
import logging.config
|
||||||
from yubiadmin import default_settings
|
from yubiadmin import default_settings
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
@ -37,6 +39,8 @@ __all__ = [
|
|||||||
|
|
||||||
SETTINGS_FILE = os.getenv('YUBIADMIN_SETTINGS',
|
SETTINGS_FILE = os.getenv('YUBIADMIN_SETTINGS',
|
||||||
'/etc/yubico/admin/yubiadmin.conf')
|
'/etc/yubico/admin/yubiadmin.conf')
|
||||||
|
LOG_CONFIG_FILE = os.path.join(os.path.dirname(os.path.abspath(SETTINGS_FILE)),
|
||||||
|
'logging.conf')
|
||||||
|
|
||||||
VALUES = {
|
VALUES = {
|
||||||
# Web interface
|
# Web interface
|
||||||
@ -61,8 +65,16 @@ try:
|
|||||||
sys.dont_write_bytecode = True
|
sys.dont_write_bytecode = True
|
||||||
user_settings = imp.load_source('user_settings', SETTINGS_FILE)
|
user_settings = imp.load_source('user_settings', SETTINGS_FILE)
|
||||||
settings = parse(user_settings, settings)
|
settings = parse(user_settings, settings)
|
||||||
except IOError, e:
|
except IOError as e:
|
||||||
if not e.errno in [errno.ENOENT, errno.EACCES]:
|
if not e.errno in [errno.ENOENT, errno.EACCES]:
|
||||||
raise e
|
raise e
|
||||||
finally:
|
finally:
|
||||||
sys.dont_write_bytecode = dont_write_bytecode
|
sys.dont_write_bytecode = dont_write_bytecode
|
||||||
|
|
||||||
|
# Set up logging
|
||||||
|
try:
|
||||||
|
logging.config.fileConfig(LOG_CONFIG_FILE)
|
||||||
|
except:
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
log.exception("Unable to configure logging. Logging to console.")
|
||||||
|
@ -29,7 +29,7 @@ import os
|
|||||||
import re
|
import re
|
||||||
import errno
|
import errno
|
||||||
import csv
|
import csv
|
||||||
import logging as log
|
import logging
|
||||||
from collections import MutableMapping, OrderedDict
|
from collections import MutableMapping, OrderedDict
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
@ -43,6 +43,8 @@ __all__ = [
|
|||||||
'parse_value'
|
'parse_value'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
PHP_BLOCKS = re.compile('(?ms)<\?php(.*?)\s*\?>')
|
PHP_BLOCKS = re.compile('(?ms)<\?php(.*?)\s*\?>')
|
||||||
QUOTED_STR = re.compile(r'\s*[\'"](.*)[\'"]\s*')
|
QUOTED_STR = re.compile(r'\s*[\'"](.*)[\'"]\s*')
|
||||||
COMMENTS = re.compile(
|
COMMENTS = re.compile(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user