forked from indymedia/epicyon
Authentication debug
parent
6602d0b78e
commit
c4797d3de2
33
auth.py
33
auth.py
|
@ -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
|
||||
|
|
|
@ -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']):
|
||||
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
|
||||
|
|
|
@ -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'
|
||||
},
|
||||
|
|
2
posts.py
2
posts.py
|
@ -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
|
||||
"""
|
||||
|
|
8
tests.py
8
tests.py
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue