summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVictor Shyba <victor1984@riseup.net>2017-08-22 05:23:24 -0300
committerdrebs <drebs@riseup.net>2017-09-05 11:08:46 -0300
commitc8c742cb981cbe4087a7863ebc3d2a8e3dd93f25 (patch)
treedfc0fbec7de3c97368e81299bf5216c62cef42a3 /src
parent9f4739c4ce468110fe070c766260770bb4d669a2 (diff)
[feature] add a local realm with file auth checker
-- Related: #8867
Diffstat (limited to 'src')
-rw-r--r--src/leap/soledad/server/_resource.py9
-rw-r--r--src/leap/soledad/server/auth.py73
-rw-r--r--src/leap/soledad/server/entrypoint.py2
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)