Authentication from shared items federation token list

main
Bob Mottram 2021-07-25 22:18:38 +01:00
parent f142d9f001
commit 5ce777eb1b
4 changed files with 94 additions and 10 deletions

57
auth.py
View File

@ -89,7 +89,7 @@ def authorizeBasic(baseDir: str, path: str, authHeader: str,
"""
if ' ' not in authHeader:
if debug:
print('DEBUG: basic auth - Authorixation header does not ' +
print('DEBUG: basic auth - Authorisation header does not ' +
'contain a space character')
return False
if not hasUsersPath(path):
@ -147,6 +147,61 @@ def authorizeBasic(baseDir: str, path: str, authHeader: str,
return False
def authorizeDFC(sharedItemsFederatedDomains: [],
baseDir: str,
callingDomain: str,
authHeader: str,
debug: bool) -> bool:
"""HTTP basic auth for shared item federation
"""
if callingDomain not in sharedItemsFederatedDomains:
if debug:
print(callingDomain +
' is not in the shared items federation list')
return False
if 'Basic ' not in authHeader:
if debug:
print('DEBUG: DFC basic auth - Authorisation header does not ' +
'contain a space character')
return False
base64Str = \
authHeader.split(' ')[1].replace('\n', '').replace('\r', '')
plain = base64.b64decode(base64Str).decode('utf-8')
if ':' not in plain:
if debug:
print('DEBUG: DFC basic auth header does not contain a ":" ' +
'separator for username:password')
return False
basicAuthDomain = plain.split(':')[0]
if basicAuthDomain != callingDomain:
if debug:
print('DEBUG: DFC calling domain does not match ' +
'the one in the Authorization header (' +
basicAuthDomain + ')')
return False
passwordFile = baseDir + '/accounts/sharedItemsFederationTokens'
if not os.path.isfile(passwordFile):
if debug:
print('DEBUG: shared item federation tokens file missing ' +
passwordFile)
return False
providedPassword = plain.split(':')[1]
passfile = open(passwordFile, 'r')
for line in passfile:
if line.startswith(basicAuthDomain + ':'):
storedPassword = \
line.split(':')[1].replace('\n', '').replace('\r', '')
success = _verifyPassword(storedPassword, providedPassword)
if not success:
if debug:
print('DEBUG: DFC password check failed for ' +
basicAuthDomain)
return success
print('DEBUG: DFC did not find credentials for ' + basicAuthDomain +
' in ' + passwordFile)
return False
def storeBasicCredentials(baseDir: str, nickname: str, password: str) -> bool:
"""Stores login credentials to a file
"""

View File

@ -105,6 +105,7 @@ from skills import actorSkillValue
from skills import setActorSkillLevel
from auth import recordLoginFailure
from auth import authorize
from auth import authorizeDFC
from auth import createPassword
from auth import createBasicAuthHeader
from auth import authorizeBasic
@ -10671,11 +10672,13 @@ class PubServer(BaseHTTPRequestHandler):
if authorized:
catalogAuthorized = True
else:
# basic auth access to catalog
# basic auth access to shared items catalog
if self.headers.get('Authorization'):
if authorize(self.server.baseDir, self.path,
self.headers['Authorization'],
self.server.debug):
if authorizeDFC(self.server.sharedItemsFederatedDomains,
self.server.baseDir,
callingDomain,
self.headers['Authorization'],
self.server.debug):
catalogAuthorized = True
# show shared items DFC catalog
if self._hasAccept(callingDomain) and catalogAuthorized:
@ -14808,7 +14811,8 @@ def loadTokens(baseDir: str, tokensDict: {}, tokensLookup: {}) -> None:
break
def runDaemon(userAgentsBlocked: [],
def runDaemon(sharedItemsFederatedDomains: [],
userAgentsBlocked: [],
logLoginFailures: bool,
city: str,
showNodeInfoAccounts: bool,
@ -15067,6 +15071,7 @@ def runDaemon(userAgentsBlocked: [],
httpd.httpPrefix = httpPrefix
httpd.debug = debug
httpd.federationList = fedList.copy()
httpd.sharedItemsFederatedDomains = sharedItemsFederatedDomains.copy()
httpd.baseDir = baseDir
httpd.instanceId = instanceId
httpd.personCache = {}

View File

@ -264,6 +264,10 @@ parser.add_argument('--rss', dest='rss', type=str, default=None,
help='Show an rss feed for a given url')
parser.add_argument('-f', '--federate', nargs='+', dest='federationList',
help='Specify federation list separated by spaces')
parser.add_argument('--federateshares', nargs='+',
dest='sharedItemsFederatedDomains',
help='Specify federation list for shared items, ' +
'separated by spaces')
parser.add_argument("--following", "--followingList",
dest='followingList',
type=str2bool, nargs='?',
@ -1024,6 +1028,16 @@ else:
if configFederationList:
federationList = configFederationList
sharedItemsFederatedDomains = []
if args.sharedItemsFederatedDomains:
setConfigParam(baseDir, 'sharedItemsFederatedDomains',
sharedItemsFederatedDomains)
else:
configSharedItemsFederatedDomains = \
getConfigParam(baseDir, 'sharedItemsFederatedDomains')
if configSharedItemsFederatedDomains:
sharedItemsFederatedDomains = configSharedItemsFederatedDomains
proxyType = None
if args.tor or domain.endswith('.onion'):
proxyType = 'tor'
@ -2142,6 +2156,9 @@ if args.desktop:
if federationList:
print('Federating with: ' + str(federationList))
if sharedItemsFederatedDomains:
print('Federating shared items with: ' +
str(sharedItemsFederatedDomains))
if args.block:
if not nickname:
@ -2657,7 +2674,8 @@ if args.registration:
print('New registrations closed')
if __name__ == "__main__":
runDaemon(userAgentsBlocked,
runDaemon(sharedItemsFederatedDomains,
userAgentsBlocked,
args.logLoginFailures,
args.city,
args.showNodeInfoAccounts,

View File

@ -457,6 +457,7 @@ def createServerAlice(path: str, domain: str, port: int,
shutil.rmtree(path)
os.mkdir(path)
os.chdir(path)
sharedItemsFederatedDomains = []
systemLanguage = 'en'
nickname = 'alice'
httpPrefix = 'http'
@ -554,7 +555,8 @@ def createServerAlice(path: str, domain: str, port: int,
logLoginFailures = False
userAgentsBlocked = []
print('Server running: Alice')
runDaemon(userAgentsBlocked,
runDaemon(sharedItemsFederatedDomains,
userAgentsBlocked,
logLoginFailures, city,
showNodeInfoAccounts,
showNodeInfoVersion,
@ -585,6 +587,7 @@ def createServerBob(path: str, domain: str, port: int,
shutil.rmtree(path)
os.mkdir(path)
os.chdir(path)
sharedItemsFederatedDomains = []
systemLanguage = 'en'
nickname = 'bob'
httpPrefix = 'http'
@ -680,7 +683,8 @@ def createServerBob(path: str, domain: str, port: int,
logLoginFailures = False
userAgentsBlocked = []
print('Server running: Bob')
runDaemon(userAgentsBlocked,
runDaemon(sharedItemsFederatedDomains,
userAgentsBlocked,
logLoginFailures, city,
showNodeInfoAccounts,
showNodeInfoVersion,
@ -710,6 +714,7 @@ def createServerEve(path: str, domain: str, port: int, federationList: [],
shutil.rmtree(path)
os.mkdir(path)
os.chdir(path)
sharedItemsFederatedDomains = []
nickname = 'eve'
httpPrefix = 'http'
proxyType = None
@ -740,7 +745,8 @@ def createServerEve(path: str, domain: str, port: int, federationList: [],
logLoginFailures = False
userAgentsBlocked = []
print('Server running: Eve')
runDaemon(userAgentsBlocked,
runDaemon(sharedItemsFederatedDomains,
userAgentsBlocked,
logLoginFailures, city,
showNodeInfoAccounts,
showNodeInfoVersion,