Authenticator: automatically choose authentication backend

and test other backends, if one fails.

Written-by: Rudolf Mayerhofer <rm@eightyfive.net>
Signed-off-by: Ralf Ramsauer <ralf@binary-kitchen.de>
[ralf: also remove the authentication method from any other code path]
This commit is contained in:
Ralf Ramsauer 2018-11-27 08:40:23 +01:00
parent 90ea795c1b
commit eaf2537d83
3 changed files with 9 additions and 36 deletions

View File

@ -102,14 +102,10 @@ class Authenticator:
if self._simulate:
log.info('SIMULATION MODE! ACCEPTING ANYTHING!')
return DoorlockResponse.Success
method = credentials[0]
if method not in self._backends:
return DoorlockResponse.InternalError
if method == AuthMethod.LDAP_USER_PW:
return self._try_auth_ldap(credentials[1], credentials[2])
elif method == AuthMethod.LOCAL_USER_DB:
return self._try_auth_local(credentials[1], credentials[2])
return DoorlockResponse.InternalError
if AuthMethod.LDAP_USER_PW in self._backends:
retval = self._try_auth_ldap(credentials[0], credentials[1])
if retval == DoorlockResponse.Success:
return retval
if AuthMethod.LOCAL_USER_DB in self._backends:
return self._try_auth_local(credentials[0], credentials[1])
return DoorlockResponse.Perm

View File

@ -45,7 +45,6 @@ def emit_doorstate(response=None):
class AuthenticationForm(FlaskForm):
username = StringField('Username', [Length(min=3, max=25)])
password = PasswordField('Password', [DataRequired()])
method = StringField('Method', [DataRequired()])
open = SubmitField('Open')
present = SubmitField('Present')
close = SubmitField('Close')
@ -63,11 +62,6 @@ class AuthenticationForm(FlaskForm):
elif self.present.data:
self.desired_state = DoorState.Present
if self.method.data == 'Local':
self.method = AuthMethod.LOCAL_USER_DB
else: # default: use LDAP
self.method = AuthMethod.LDAP_USER_PW
return True
@ -98,16 +92,10 @@ def api():
json['status'] = logic.state.value
return jsonify(json)
method = request.form.get('method')
user = request.form.get('user')
password = request.form.get('pass')
command = request.form.get('command')
if method == 'local':
method = AuthMethod.LOCAL_USER_DB
else: # 'ldap' or default
method = AuthMethod.LDAP_USER_PW
if any(v is None for v in [user, password, command]):
log.warning('Incomplete API request')
abort(400)
@ -117,7 +105,7 @@ def api():
return json_response(DoorlockResponse.Inval,
'Invalid username or password format')
credentials = method, user, password
credentials = user, password
if command == 'status':
return json_response(logic.auth.try_auth(credentials))
@ -143,11 +131,9 @@ def home():
if request.method == 'POST' and authentication_form.validate():
user = authentication_form.username.data
password = authentication_form.password.data
method = authentication_form.method
credentials = method, user, password
credentials = user, password
log.info('Incoming request from %s' % user.encode('utf-8'))
log.info(' authentication method: %s' % method)
desired_state = authentication_form.desired_state
log.info(' desired state: %s' % desired_state)
log.info(' current state: %s' % logic.state)
@ -159,7 +145,6 @@ def home():
return render_template('index.html',
authentication_form=authentication_form,
auth_backends=logic.auth.backends,
response=response,
state_text=str(logic.state),
led=logic.state.to_img(),

View File

@ -23,14 +23,6 @@
<label class="control-label" for="password">Password</label>
<input class="form-control" id="password" name="password" required type="password" value="">
</div>
<div class="form-group">
<label for="method">Authentication method</label>
<select name="method" id="method" class="form-control">
{% for backend in auth_backends %}
<option>{{ backend }}</option>
{% endfor %}
</select>
</div>
<input class="btn btn-success btn-lg btn-block" id="open" name="open" type="submit" value="Open">
<input class="btn btn-warning btn-lg btn-block" id="present" name="present" type="submit" value="Present">
<input class="btn btn-danger btn-lg btn-block" id="close" name="close" type="submit" value="Close">