Authentication debug

master
Bob Mottram 2019-07-04 09:56:15 +01:00
parent 6602d0b78e
commit c4797d3de2
5 changed files with 48 additions and 18 deletions

33
auth.py
View File

@ -49,25 +49,50 @@ def nicknameFromBasicAuth(authHeader: str) -> str:
return None
return plain.split(':')[0]
def authorizeBasic(baseDir: str,authHeader: str) -> bool:
def authorizeBasic(baseDir: str,path: str,authHeader: str,debug: bool) -> bool:
"""HTTP basic auth
"""
if ' ' not in authHeader:
if debug:
print('DEBUG: Authorixation header does not contain a space character')
return False
if '/users/' not in path:
if debug:
print('DEBUG: Path for Authorization does not contain a user')
return False
pathUsersSection=path.split('/users/')[1]
if '/' not in pathUsersSection:
if debug:
print('DEBUG: This is not a users endpoint')
return False
nicknameFromPath=pathUsersSection.split('/')[0]
base64Str = authHeader.split(' ')[1].replace('\n','')
plain = base64.b64decode(base64Str).decode('utf-8')
if ':' not in plain:
if debug:
print('DEBUG: Basic Auth header does not contain a ":" separator for username:password')
return False
nickname = plain.split(':')[0]
if nickname!=nicknameFromPath:
if debug:
print('DEBUG: Nickname given in the path ('+nicknameFromPath+') does not match the one in the Authorization header ('+nickname+')')
return False
passwordFile=baseDir+'/accounts/passwords'
if not os.path.isfile(passwordFile):
if debug:
print('DEBUG: passwords file missing')
return False
providedPassword = plain.split(':')[1]
passfile = open(passwordFile, "r")
for line in passfile:
if line.startswith(nickname+':'):
storedPassword=line.split(':')[1].replace('\n','')
return verifyPassword(storedPassword,providedPassword)
success = verifyPassword(storedPassword,providedPassword)
if not success:
if debug:
print('DEBUG: Password check failed for '+nickname)
return success
print('DEBUG: Did not find credentials for '+nickname+' in '+passwordFile)
return False
def storeBasicCredentials(baseDir: str,nickname: str,password: str) -> bool:
@ -100,7 +125,7 @@ def storeBasicCredentials(baseDir: str,nickname: str,password: str) -> bool:
passfile.write(storeStr+'\n')
return True
def authorize(baseDir: str,authHeader: str) -> bool:
def authorize(baseDir: str,path: str,authHeader: str,debug: bool) -> bool:
if authHeader.lower().startswith('basic '):
return authorizeBasic(baseDir,authHeader)
return authorizeBasic(baseDir,path,authHeader,debug)
return False

View File

@ -172,15 +172,18 @@ class PubServer(BaseHTTPRequestHandler):
if self.path.endswith('/inbox'):
if '/users/' in self.path:
if self.headers.get('Authorization'):
nickname=self.path.split('/users/')[1].replace('/inbox','')
if nickname==nicknameFromBasicAuth(self.headers['Authorization']):
if authorize(self.server.baseDir,self.headers['Authorization']):
# TODO
print('inbox access not supported yet')
self.send_response(405)
self.end_headers()
self.server.POSTbusy=False
return
if authorize(self.server.baseDir,self.path,self.headers['Authorization'],self.server.debug):
# TODO
print('inbox access not supported yet')
self.send_response(405)
self.end_headers()
self.server.POSTbusy=False
return
else:
if self.server.debug:
print('DEBUG: '+nickname+' was not authorized to access '+self.path)
if self.server.debug:
print('DEBUG: GET access to inbox is unauthorized')
self.send_response(405)
self.end_headers()
self.server.POSTbusy=False

View File

@ -52,7 +52,7 @@ def createPerson(baseDir: str,nickname: str,domain: str,port: int, \
'value': 'schema:value'}],
'attachment': [],
'endpoints': {
'id': httpPrefix+'://'+domain+'/users/'+nickname+'/endpoints'
'id': httpPrefix+'://'+domain+'/users/'+nickname+'/endpoints',
'sharedInbox': httpPrefix+'://'+domain+'/inbox',
'uploadMedia': httpPrefix+'://'+domain+'/users/'+nickname+'/endpoints/uploadMedia'
},

View File

@ -360,7 +360,7 @@ def createPostBase(baseDir: str,nickname: str, domain: str, port: int, \
savePostToOutbox(baseDir,httpPrefix,newPostId,nickname,domain,newPost)
return newPost
def outboxMessageCreateWrap(httpPrefix str,nickname: str,domain: str,messageJson: {}) -> {}:
def outboxMessageCreateWrap(httpPrefix: str,nickname: str,domain: str,messageJson: {}) -> {}:
"""Wraps a received message in a Create
https://www.w3.org/TR/activitypub/#object-without-create
"""

View File

@ -318,16 +318,18 @@ def testAuthentication():
authHeader=createBasicAuthHeader(nickname,password)
assert nickname==nicknameFromBasicAuth(authHeader)
assert authorizeBasic(baseDir,authHeader)
assert authorizeBasic(baseDir,'/users/'+nickname+'/inbox',authHeader,False)
assert authorizeBasic(baseDir,'/users/'+nickname,authHeader,False)==False
assert authorizeBasic(baseDir,'/users/othernick/inbox',authHeader,False)==False
authHeader=createBasicAuthHeader(nickname,password+'1')
assert authorizeBasic(baseDir,authHeader)==False
assert authorizeBasic(baseDir,'/users/'+nickname+'/inbox',authHeader,False)==False
password='someOtherPassword'
assert storeBasicCredentials(baseDir,nickname,password)
authHeader=createBasicAuthHeader(nickname,password)
assert authorizeBasic(baseDir,authHeader)
assert authorizeBasic(baseDir,'/users/'+nickname+'/inbox',authHeader,False)
os.chdir(currDir)
shutil.rmtree(baseDir)