diff options
author | Victor Shyba <victor1984@riseup.net> | 2017-08-22 05:23:24 -0300 |
---|---|---|
committer | drebs <drebs@riseup.net> | 2017-09-05 11:08:46 -0300 |
commit | c8c742cb981cbe4087a7863ebc3d2a8e3dd93f25 (patch) | |
tree | dfc0fbec7de3c97368e81299bf5216c62cef42a3 /src | |
parent | 9f4739c4ce468110fe070c766260770bb4d669a2 (diff) |
[feature] add a local realm with file auth checker
-- Related: #8867
Diffstat (limited to 'src')
-rw-r--r-- | src/leap/soledad/server/_resource.py | 9 | ||||
-rw-r--r-- | src/leap/soledad/server/auth.py | 73 | ||||
-rw-r--r-- | src/leap/soledad/server/entrypoint.py | 2 |
3 files changed, 78 insertions, 6 deletions
diff --git a/src/leap/soledad/server/_resource.py b/src/leap/soledad/server/_resource.py index 28344b38..e4c51ded 100644 --- a/src/leap/soledad/server/_resource.py +++ b/src/leap/soledad/server/_resource.py @@ -50,6 +50,15 @@ class SoledadAnonResource(Resource): self.putChild('robots.txt', _Robots()) +class LocalResource(Resource): + """ + Used for localhost endpoints, like IncomingBox delivery. + """ + + def __init__(conf): + pass + + class SoledadResource(Resource): """ This is a dummy twisted resource, used only to allow different entry points diff --git a/src/leap/soledad/server/auth.py b/src/leap/soledad/server/auth.py index 1357b289..934517b5 100644 --- a/src/leap/soledad/server/auth.py +++ b/src/leap/soledad/server/auth.py @@ -39,6 +39,7 @@ from twisted.web.resource import IResource from leap.soledad.common.couch import couch_server from ._resource import SoledadResource, SoledadAnonResource +from ._resource import LocalResource from ._blobs import BlobsResource from ._config import get_config @@ -77,8 +78,63 @@ class SoledadRealm(object): raise NotImplementedError() +@implementer(IRealm) +class LocalServicesRealm(object): + + def __init__(self, conf=None): + if conf is None: + conf = get_config() + self.anon_resource = SoledadAnonResource( + enable_blobs=conf['blobs']) + self.auth_resource = LocalResource(conf) + + def requestAvatar(self, avatarId, mind, *interfaces): + + # Anonymous access + if IAnonymous.providedBy(avatarId): + return (IResource, self.anon_resource, + lambda: None) + + # Authenticated access + else: + if IResource in interfaces: + return (IResource, self.auth_resource, + lambda: None) + raise NotImplementedError() + + +@implementer(ICredentialsChecker) +class FileTokenChecker(object): + + def __init__(self, conf=None): + conf = conf or get_config() + self._trusted_services_tokens = {} + self._tokens_file_path = conf['services_tokens_file'] + self._reload_tokens() + + def _reload_tokens(self): + with open(self._tokens_file_path) as tokens_file: + for line in tokens_file.readlines(): + line = line.strip() + if not line.startswith('#'): + service, token = line.split(':') + self._trusted_services_tokens[service] = token + + def requestAvatarId(self, credentials): + if IAnonymous.providedBy(credentials): + return defer.succeed(Anonymous()) + + service = credentials.username + token = credentials.password + + if self._trusted_services_tokens[service] != token: + return defer.fail(error.UnauthorizedLogin()) + + return defer.succeed(service) + + @implementer(ICredentialsChecker) -class TokenChecker(object): +class CouchDBTokenChecker(object): credentialInterfaces = [IUsernamePassword, IAnonymous] @@ -164,10 +220,17 @@ class TokenCredentialFactory(object): raise error.LoginFailed('Invalid credentials') -def portalFactory(sync_pool): - realm = SoledadRealm(sync_pool=sync_pool) - checker = TokenChecker() - return Portal(realm, [checker]) +def portalFactory(public=True, sync_pool=None): + database_checker = CouchDBTokenChecker() + file_checker = FileTokenChecker() + if public: + assert sync_pool + realm = SoledadRealm(sync_pool=sync_pool) + auth_checkers = [database_checker] + else: + realm = LocalServicesRealm() + auth_checkers = [file_checker, database_checker] + return Portal(realm, auth_checkers) credentialFactory = TokenCredentialFactory() diff --git a/src/leap/soledad/server/entrypoint.py b/src/leap/soledad/server/entrypoint.py index c06b740e..9b9a5e66 100644 --- a/src/leap/soledad/server/entrypoint.py +++ b/src/leap/soledad/server/entrypoint.py @@ -40,7 +40,7 @@ class SoledadEntrypoint(SoledadSession): pool = threadpool.ThreadPool(name='wsgi') reactor.callWhenRunning(pool.start) reactor.addSystemEventTrigger('after', 'shutdown', pool.stop) - portal = portalFactory(pool) + portal = portalFactory(public=True, sync_pool=pool) SoledadSession.__init__(self, portal) |