pydoorlock: Refactor LogicResponse to DoorlockResponse

Signed-off-by: Ralf Ramsauer <ralf@binary-kitchen.de>
This commit is contained in:
Ralf Ramsauer 2018-10-08 22:59:34 +02:00
parent 8d37886ee1
commit 00f74d69f9
3 changed files with 91 additions and 100 deletions

View File

@ -28,9 +28,10 @@ from subprocess import Popen
from threading import Thread
from time import sleep
from pydoorlock.Authenticator import Authenticator, AuthMethod, AuthenticationResult
from pydoorlock.Authenticator import Authenticator, AuthMethod
from pydoorlock.WebApp import webapp_run, emit_doorstate
from pydoorlock.Door import DoorState
from pydoorlock.Doorlock import DoorlockResponse
SYSCONFDIR = '.'
PREFIX = '.'
@ -106,6 +107,7 @@ def start_hook(script):
def sound_helper(old_state, new_state, button):
if old_state == new_state:
playsound(wave_zonk)
return
if button:
if new_state == DoorState.Open:
@ -123,40 +125,6 @@ def sound_helper(old_state, new_state, button):
playsound(wave_lock)
class LogicResponse(Enum):
Success = 0
Perm = 1
AlreadyActive = 2
# don't break old apps, value 3 is reserved now
RESERVED = 3
Inval = 4
EmergencyUnlock = 10,
ButtonLock = 11,
ButtonUnlock = 12,
ButtonPresent = 13,
def __str__(self):
if self == LogicResponse.Success:
return 'Yo, passt.'
elif self == LogicResponse.Perm:
return choose_insult()
elif self == LogicResponse.AlreadyActive:
return 'Zustand bereits aktiv'
elif self == LogicResponse.Inval:
return 'Das was du willst geht nicht.'
elif self == LogicResponse.EmergencyUnlock:
return '!!! Emergency Unlock !!!'
elif self == LogicResponse.ButtonLock:
return 'Closed by button'
elif self == LogicResponse.ButtonUnlock:
return 'Opened by button'
elif self == LogicResponse.ButtonPresent:
return 'Present by button'
return 'Error'
class DoorHandler:
state = DoorState.Closed
do_close = False
@ -229,37 +197,41 @@ class DoorHandler:
def open(self):
if self.state == DoorState.Open:
return LogicResponse.AlreadyActive
return DoorlockResponse.AlreadyActive
self.state = DoorState.Open
start_hook('post_unlock')
return LogicResponse.Success
return DoorlockResponse.Success
def present(self):
if self.state == DoorState.Present:
return LogicResponse.AlreadyActive
return DoorlockResponse.AlreadyActive
self.state = DoorState.Present
start_hook('post_present')
return LogicResponse.Success
return DoorlockResponse.Success
def close(self):
if self.state == DoorState.Closed:
return LogicResponse.AlreadyActive
return DoorlockResponse.AlreadyActive
self.do_close = True
self.state = DoorState.Closed
start_hook('post_lock')
return LogicResponse.Success
return DoorlockResponse.Success
def request(self, state):
old_state = self.state
if state == DoorState.Closed:
err = self.close()
elif state == DoorState.Present:
err = self.present()
elif state == DoorState.Open:
err = self.open()
sound_helper(old_state, self.state, False)
emit_doorstate()
return err
class Logic:
@ -267,18 +239,12 @@ class Logic:
self.auth = Authenticator(cfg)
self.door_handler = DoorHandler(cfg)
def _request(self, state, credentials):
err = self.auth.try_auth(credentials)
if err != AuthenticationResult.Success:
return err
return self.door_handler.request(state)
def request(self, state, credentials):
old_state = self.door_handler.state
err = self._request(state, credentials)
if err == LogicResponse.Success or err == LogicResponse.AlreadyActive:
sound_helper(old_state, self.door_handler.state, False)
return err
err = self.auth.try_auth(credentials)
if err != DoorlockResponse.Success:
return err
return self.door_handler.request(state)
@property
def state(self):

View File

@ -20,35 +20,11 @@ import ldap
import logging
from enum import Enum
from random import sample
from .Doorlock import DoorlockResponse
log = logging.getLogger()
# copied from sudo
eperm_insults = {
'Wrong! You cheating scum!',
'And you call yourself a Rocket Scientist!',
'No soap, honkie-lips.',
'Where did you learn to type?',
'Are you on drugs?',
'My pet ferret can type better than you!',
'You type like i drive.',
'Do you think like you type?',
'Your mind just hasn\'t been the same since the electro-shock, has it?',
'Maybe if you used more than just two fingers...',
'BOB says: You seem to have forgotten your passwd, enter another!',
'stty: unknown mode: doofus',
'I can\'t hear you -- I\'m using the scrambler.',
'The more you drive -- the dumber you get.',
'Listen, broccoli brains, I don\'t have time to listen to this trash.',
'I\'ve seen penguins that can type better than that.',
'Have you considered trying to match wits with a rutabaga?',
'You speak an infinite deal of nothing',
}
def choose_insult():
return(sample(eperm_insults, 1)[0])
class AuthMethod(Enum):
LDAP_USER_PW = 1
@ -62,19 +38,6 @@ class AuthMethod(Enum):
return 'Error'
class AuthenticationResult(Enum):
Success = 0
Perm = 1
InternalError = 2
def __str__(self):
if self == AuthenticationResult.Success:
return 'Yo, passt!'
elif self == AuthenticationResult.Perm:
return choose_insult()
else:
return 'Internal authentication error'
class Authenticator:
def __init__(self, cfg):
self._simulate = cfg.boolean('SIMULATE_AUTH')
@ -111,14 +74,14 @@ class Authenticator:
def _try_auth_local(self, user, password):
if user not in self._local_db:
return AuthenticationResult.Perm
return DoorlockResponse.Perm
stored_pw = self._local_db[user][0]
stored_salt = self._local_db[user][1]
if stored_pw == hashlib.sha256(stored_salt.encode() + password.encode()).hexdigest():
return AuthenticationResult.Success
return DoorlockResponse.Success
return AuthenticationResult.Perm
return DoorlockResponse.Perm
def _try_auth_ldap(self, user, password):
log.info(' Trying to LDAP auth (user, password) as user %s', user)
@ -129,24 +92,24 @@ class Authenticator:
l.unbind_s()
except ldap.INVALID_CREDENTIALS:
log.info(' Invalid credentials')
return AuthenticationResult.Perm
return DoorlockResponse.Perm
except ldap.LDAPError as e:
log.info(' LDAP Error: %s' % e)
return AuthenticationResult.InternalError
return AuthenticationResult.Success
return DoorlockResponse.InternalError
return DoorlockResponse.Success
def try_auth(self, credentials):
if self._simulate:
log.info('SIMULATION MODE! ACCEPTING ANYTHING!')
return AuthenticationResult.Success
return DoorlockResponse.Success
method = credentials[0]
if method not in self._backends:
return AuthenticationResult.InternalError
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 AuthenticationResult.InternalError
return DoorlockResponse.InternalError

62
pydoorlock/Doorlock.py Normal file
View File

@ -0,0 +1,62 @@
from enum import Enum
from random import sample
# copied from sudo
eperm_insults = {
'Wrong! You cheating scum!',
'And you call yourself a Rocket Scientist!',
'No soap, honkie-lips.',
'Where did you learn to type?',
'Are you on drugs?',
'My pet ferret can type better than you!',
'You type like i drive.',
'Do you think like you type?',
'Your mind just hasn\'t been the same since the electro-shock, has it?',
'Maybe if you used more than just two fingers...',
'BOB says: You seem to have forgotten your passwd, enter another!',
'stty: unknown mode: doofus',
'I can\'t hear you -- I\'m using the scrambler.',
'The more you drive -- the dumber you get.',
'Listen, broccoli brains, I don\'t have time to listen to this trash.',
'I\'ve seen penguins that can type better than that.',
'Have you considered trying to match wits with a rutabaga?',
'You speak an infinite deal of nothing',
}
def choose_insult():
return(sample(eperm_insults, 1)[0])
class DoorlockResponse(Enum):
Success = 0
Perm = 1
AlreadyActive = 2
# don't break old apps, value 3 is reserved now
RESERVED = 3
Inval = 4
EmergencyUnlock = 10,
ButtonLock = 11,
ButtonUnlock = 12,
ButtonPresent = 13,
def __str__(self):
if self == DoorlockResponse.Success:
return 'Yo, passt.'
elif self == DoorlockResponse.Perm:
return choose_insult()
elif self == DoorlockResponse.AlreadyActive:
return 'Zustand bereits aktiv'
elif self == DoorlockResponse.Inval:
return 'Das was du willst geht nicht.'
elif self == DoorlockResponse.EmergencyUnlock:
return '!!! Emergency Unlock !!!'
elif self == DoorlockResponse.ButtonLock:
return 'Closed by button'
elif self == DoorlockResponse.ButtonUnlock:
return 'Opened by button'
elif self == DoorlockResponse.ButtonPresent:
return 'Present by button'
return 'Error'