Everything should be working fine :>

Signed-off-by: Tiago Garcia <tiago.rgarcia@ua.pt>
This commit is contained in:
Tiago Garcia 2024-12-18 18:09:15 +00:00
parent cd23f0af9e
commit b0e3a21be5
Signed by: TiagoRG
GPG Key ID: DFCD48E3F420DB42
46 changed files with 391 additions and 374 deletions

View File

@ -6,9 +6,8 @@ import requests
import json import json
import argparse import argparse
from subject import main
from lib import digest from lib import digest
from subject import main
logging.basicConfig(format='%(levelname)s\t- %(message)s') logging.basicConfig(format='%(levelname)s\t- %(message)s')
logger = logging.getLogger() logger = logging.getLogger()
@ -48,22 +47,8 @@ def aclDoc(args):
with open(BASE_DIR + args.session, 'r') as f: with open(BASE_DIR + args.session, 'r') as f:
args.session = json.load(f) args.session = json.load(f)
# Get roles in session
try:
req = requests.get(f'http://{state['REP_ADDRESS']}/role/session/list', headers={'Authorization': args.session['token']})
req.raise_for_status()
except requests.exceptions.RequestException as errex:
logger.error("Failed to obtain response from server.")
sys.exit(-1)
# Validate role name
roles = req.json()
if args.role not in roles.items():
logger.error("Role does not exist.")
sys.exit(1)
# Check permission # Check permission
if args.permission not in ['ROLE_ACL', 'SUBJECT_NEW', 'SUBJECT_DOWN', 'SUBJECT_UP', 'DOC_NEW']: if args.permission not in ['DOC_ACL', 'DOC_READ', 'DOC_DELETE']:
logger.error("Permission is not valid.") logger.error("Permission is not valid.")
sys.exit(1) sys.exit(1)
@ -91,6 +76,7 @@ def aclDoc(args):
# Operation success # Operation success
logger.info("ACL changed succesfully.") logger.info("ACL changed succesfully.")
sys.exit(0)
if __name__ == '__main__': if __name__ == '__main__':
aclDoc(sys.argv[1:]) aclDoc(sys.argv[1:])

View File

@ -48,6 +48,7 @@ def activateSubject(args):
logger.error("Failed to obtain response from server.") logger.error("Failed to obtain response from server.")
sys.exit(-1) sys.exit(-1)
logger.info("Subject %s has been activated." % args.username)
sys.exit(0) sys.exit(0)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -82,6 +82,7 @@ def addDoc(args):
#Delete temporary file #Delete temporary file
os.remove(BASE_DIR + 'encryptedText') os.remove(BASE_DIR + 'encryptedText')
logger.info("Document uploaded successfully.")
sys.exit(0) sys.exit(0)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -35,9 +35,6 @@ def addPermission(args):
logger.error("Need session file and role.") logger.error("Need session file and role.")
sys.exit(1) sys.exit(1)
#Validate role name
#TODO
# Check for session file # Check for session file
if not os.path.isfile(BASE_DIR + args.session): if not os.path.isfile(BASE_DIR + args.session):
logger.error("File '" + args.session + "' not found.") logger.error("File '" + args.session + "' not found.")
@ -51,19 +48,18 @@ def addPermission(args):
isPerm = False; isUsername = False isPerm = False; isUsername = False
# query for permission # query for permission
if args.value in ['ROLE_ACL', 'SUBJECT_NEW', 'SUBJECT_DOWN', 'SUBJECT_UP', 'DOC_NEW']: if args.value in [
'ROLE_ACL',
'SUBJECT_NEW',
'SUBJECT_DOWN',
'SUBJECT_UP',
'DOC_NEW',
'ROLE_NEW',
'ROLE_DOWN',
'ROLE_UP',
'ROLE_MOD'
]:
isPerm = True isPerm = True
else:
try:
subjects = requests.get(f'http://{state['REP_ADDRESS']}/user/list',
json=json.dumps({'username' : args.value}),
headers={'Authorization': args.session['token']})
subjects.raise_for_status()
isUsername = True
except requests.exceptions.RequestException as errex:
logger.error("Username doesn't exist.")
sys.exit(1)
if isPerm: if isPerm:
try: try:
@ -73,7 +69,10 @@ def addPermission(args):
except requests.exceptions.RequestException as errex: except requests.exceptions.RequestException as errex:
logger.error("Failed to obtain response from server.") logger.error("Failed to obtain response from server.")
sys.exit(-1) sys.exit(-1)
elif isUsername:
logger.info("Permission added successfully to role.")
sys.exit(0)
else:
try: try:
req = requests.post(f'http://{state['REP_ADDRESS']}/role/' + args.role + '/user/add/' + args.value, req = requests.post(f'http://{state['REP_ADDRESS']}/role/' + args.role + '/user/add/' + args.value,
headers={'Authorization': args.session['token']}) headers={'Authorization': args.session['token']})
@ -81,14 +80,9 @@ def addPermission(args):
except requests.exceptions.RequestException as errex: except requests.exceptions.RequestException as errex:
logger.error("Failed to obtain response from server.") logger.error("Failed to obtain response from server.")
sys.exit(-1) sys.exit(-1)
else:
logger.error("Invalid permission or username.")
sys.exit(1)
req = req.json()
# TODO: print response
logger.info("User added successfully to role.")
sys.exit(0)
if __name__ == '__main__': if __name__ == '__main__':
addPermission(sys.argv[1:]) addPermission(sys.argv[1:])

View File

@ -45,7 +45,7 @@ def addRole(args):
args.session = json.load(f) args.session = json.load(f)
try: try:
req = requests.post(f'http://{state['REP_ADDRESS']}/role/create/', req = requests.post(f'http://{state['REP_ADDRESS']}/role/create',
json=json.dumps({'role' : args.role}), json=json.dumps({'role' : args.role}),
headers={'Authorization': args.session['token']}) headers={'Authorization': args.session['token']})
req.raise_for_status() req.raise_for_status()

View File

@ -63,8 +63,11 @@ def addSubject(args):
logger.error("Failed to obtain response from server.") logger.error("Failed to obtain response from server.")
sys.exit(-1) sys.exit(-1)
if req.status_code == 201:
logger.info('Subject added.') logger.info('Subject added.')
sys.exit(0) sys.exit(0)
logger.error('Failed to add subject.')
sys.exit(-1)
if __name__ == '__main__': if __name__ == '__main__':
addSubject(sys.argv[1:]) addSubject(sys.argv[1:])

View File

@ -43,22 +43,6 @@ def assumeRole(args):
with open(BASE_DIR + args.session, 'r') as f: with open(BASE_DIR + args.session, 'r') as f:
args.session = json.load(f) args.session = json.load(f)
# # Get roles in session
# try:
# req = requests.get(f'http://{state['REP_ADDRESS']}/role/session/list', headers={'Authorization': args.session['token']})
# req.raise_for_status()
# except requests.exceptions.RequestException as errex:
# logger.error("Failed to obtain response from server.")
# sys.exit(-1)
#
# # Validate role name
# roles = req.json()
# if args.role not in roles.items():
# logger.error("Role does not exist.")
# sys.exit(1)
# TODO:
try: try:
req = requests.post(f'http://{state['REP_ADDRESS']}/role/session/assume/' + args.role, headers={'Authorization': args.session['token']}) req = requests.post(f'http://{state['REP_ADDRESS']}/role/session/assume/' + args.role, headers={'Authorization': args.session['token']})
req.raise_for_status() req.raise_for_status()

View File

@ -65,7 +65,11 @@ def createOrganization(args):
logger.error("Failed to obtain response from server.") logger.error("Failed to obtain response from server.")
sys.exit(-1) sys.exit(-1)
if req.status_code == 201:
logger.info("Organization created successfully.")
sys.exit(0) sys.exit(0)
logger.error("Failed to create organization.")
sys.exit(-1)
if __name__ == '__main__': if __name__ == '__main__':
createOrganization(sys.argv[1:]) createOrganization(sys.argv[1:])

View File

@ -85,7 +85,11 @@ def createSession(args):
with open(BASE_DIR + args.session, 'w') as f: with open(BASE_DIR + args.session, 'w') as f:
json.dump(req.json(), f) json.dump(req.json(), f)
if req.status_code == 201:
logger.info("Session created successfully")
sys.exit(0) sys.exit(0)
logger.error("Failed to create session")
sys.exit(-1)
if __name__ == '__main__': if __name__ == '__main__':
createSession(sys.argv[1:]) createSession(sys.argv[1:])

View File

@ -43,7 +43,6 @@ def decryptFile(args):
# Send decrypted content to stdout # Send decrypted content to stdout
sys.stdout.write(content) sys.stdout.write(content)
sys.exit(0) sys.exit(0)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -54,6 +54,7 @@ def delDoc(args):
logger.error("Failed to obtain response from server.") logger.error("Failed to obtain response from server.")
sys.exit(-1) sys.exit(-1)
logger.info("You deleted the document %s", args.name)
sys.exit(0) sys.exit(0)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -43,22 +43,8 @@ def dropRole(args):
with open(BASE_DIR + args.session, 'r') as f: with open(BASE_DIR + args.session, 'r') as f:
args.session = json.load(f) args.session = json.load(f)
# Get roles in session
try: try:
req = requests.get(f'http://{state['REP_ADDRESS']}/role/session/list', headers={'Authorization': args.session['token']}) req = requests.post(f'http://{state['REP_ADDRESS']}/role/session/drop/' + args.role, headers={'Authorization': args.session['token']})
req.raise_for_status()
except requests.exceptions.RequestException as errex:
logger.error("Failed to obtain response from server.")
sys.exit(-1)
# Validate role name
roles = req.json()
if args.role not in roles.items():
logger.error("Role does not exist.")
sys.exit(1)
try:
req = requests.post(f'http://{state['REP_ADDRESS']}/role/session/drop/' + args.username + '/activate', headers={'Authorization': args.session['token']})
req.raise_for_status() req.raise_for_status()
except requests.exceptions.RequestException as errex: except requests.exceptions.RequestException as errex:
logger.error("Failed to obtain response from server.") logger.error("Failed to obtain response from server.")

View File

@ -88,8 +88,6 @@ def getDoc(args):
else: else:
sys.stdout.write(content) sys.stdout.write(content)
sys.exit(0) sys.exit(0)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -57,7 +57,6 @@ def getDocMetadata(args):
metadata = metadata.json() metadata = metadata.json()
sys.stdout.write(json.dumps(metadata)) sys.stdout.write(json.dumps(metadata))
sys.exit(0) sys.exit(0)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -51,6 +51,7 @@ def getFile(args):
with open(BASE_DIR + args.file, "wb") as f: with open(BASE_DIR + args.file, "wb") as f:
f.write(file.content) f.write(file.content)
logger.info("File obtained.")
sys.exit(0) sys.exit(0)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -119,9 +119,7 @@ def list_docs(args):
subjects = subjects.json() subjects = subjects.json()
for s in subjects: logger.info(json.dumps(subjects, indent=4))
sys.stdout.write(s['id'] + " - " + s['username'])
sys.exit(0) sys.exit(0)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -25,9 +25,7 @@ def listOrganizations():
logger.error("Failed to obtain response from server.") logger.error("Failed to obtain response from server.")
sys.exit(-1) sys.exit(-1)
for org in orgs.json(): logger.info(json.dumps(orgs.json(), indent=4))
sys.stdout.write(str(org['id']) + " - " + org['name'])
sys.exit(0) sys.exit(0)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -44,11 +44,6 @@ def listPermissionRoles(args):
with open(BASE_DIR + args.session, 'r') as f: with open(BASE_DIR + args.session, 'r') as f:
args.session = json.load(f) args.session = json.load(f)
#Validate permission name
if args.permission in ['ROLE_ACL', 'SUBJECT_NEW', 'SUBJECT_DOWN', 'SUBJECT_UP', 'DOC_NEW']:
logger.error("Permission does not exist.")
sys.exit(1)
try: try:
req = requests.get(f'http://{state['REP_ADDRESS']}/role/perm/' + args.permission + '/roles', headers={'Authorization': args.session['token']}) req = requests.get(f'http://{state['REP_ADDRESS']}/role/perm/' + args.permission + '/roles', headers={'Authorization': args.session['token']})
req.raise_for_status() req.raise_for_status()
@ -57,8 +52,7 @@ def listPermissionRoles(args):
sys.exit(-1) sys.exit(-1)
roles = req.json() roles = req.json()
for r in roles.items(): logger.info(json.dumps(roles, indent=4))
sys.stdout.write(r)
sys.exit(0) sys.exit(0)

View File

@ -44,20 +44,6 @@ def listRolePermissions(args):
with open(BASE_DIR + args.session, 'r') as f: with open(BASE_DIR + args.session, 'r') as f:
args.session = json.load(f) args.session = json.load(f)
# Get roles in session
try:
req = requests.get(f'http://{state['REP_ADDRESS']}/role/session/list', headers={'Authorization': args.session['token']})
req.raise_for_status()
except requests.exceptions.RequestException as errex:
logger.error("Failed to obtain response from server.")
sys.exit(-1)
# Validate role name
roles = req.json()
if args.role not in roles.items():
logger.error("Role does not exist.")
sys.exit(1)
try: try:
req = requests.get(f'http://{state['REP_ADDRESS']}/role/' + args.role + '/list/perms', headers={'Authorization': args.session['token']}) req = requests.get(f'http://{state['REP_ADDRESS']}/role/' + args.role + '/list/perms', headers={'Authorization': args.session['token']})
req.raise_for_status() req.raise_for_status()
@ -66,8 +52,7 @@ def listRolePermissions(args):
sys.exit(-1) sys.exit(-1)
perms = req.json() perms = req.json()
for p in perms.items(): logger.info(json.dumps(perms, indent=4))
sys.stdout.write(p)
sys.exit(0) sys.exit(0)

View File

@ -44,20 +44,6 @@ def listRoleSubjects(args):
with open(BASE_DIR + args.session, 'r') as f: with open(BASE_DIR + args.session, 'r') as f:
args.session = json.load(f) args.session = json.load(f)
# Get roles in session
try:
req = requests.get(f'http://{state['REP_ADDRESS']}/role/session/list', headers={'Authorization': args.session['token']})
req.raise_for_status()
except requests.exceptions.RequestException as errex:
logger.error("Failed to obtain response from server.")
sys.exit(-1)
# Validate role name
roles = req.json()
if args.role not in roles.items():
logger.error("Role does not exist.")
sys.exit(1)
try: try:
req = requests.get(f'http://{state['REP_ADDRESS']}/role/' + args.role + '/list/users', headers={'Authorization': args.session['token']}) req = requests.get(f'http://{state['REP_ADDRESS']}/role/' + args.role + '/list/users', headers={'Authorization': args.session['token']})
req.raise_for_status() req.raise_for_status()
@ -66,8 +52,7 @@ def listRoleSubjects(args):
sys.exit(-1) sys.exit(-1)
subjects = req.json() subjects = req.json()
for s in subjects.items(): logger.info(json.dumps(subjects, indent=4))
sys.stdout.write(s)
sys.exit(0) sys.exit(0)

View File

@ -52,17 +52,7 @@ def listRoles(args):
sys.exit(-1) sys.exit(-1)
roles = req.json() roles = req.json()
logger.info(json.dumps(roles, indent=4))
if not args.role:
for r in roles.items():
sys.stdout.write(r)
sys.exit(0)
elif args.role not in roles.items():
logger.error("Role %s does not exist.", args.role)
sys.exit(1)
else:
logger.info("Role %s exists.", args.role)
sys.exit(0)
if __name__ == '__main__': if __name__ == '__main__':
listRoles(sys.argv[1:]) listRoles(sys.argv[1:])

View File

@ -44,24 +44,6 @@ def listSubjectRoles(args):
with open(BASE_DIR + args.session, 'r') as f: with open(BASE_DIR + args.session, 'r') as f:
args.session = json.load(f) args.session = json.load(f)
# Get list of subjects
try:
subjects = requests.get(f'http://{state['REP_ADDRESS']}/user/list',
json=json.dumps({}),
headers={'Authorization': args.session['token']})
subjects.raise_for_status()
except requests.exceptions.RequestException as errex:
logger.error("Failed to obtain response from server.")
sys.exit(-1)
subjects = subjects.json()
# Check if subject exists
if args.username not in subjects.items():
logger.error("Subject not found.")
sys.exit(1)
try: try:
req = requests.get(f'http://{state['REP_ADDRESS']}/user/' + args.username + '/roles', headers={'Authorization': args.session['token']}) req = requests.get(f'http://{state['REP_ADDRESS']}/user/' + args.username + '/roles', headers={'Authorization': args.session['token']})
req.raise_for_status() req.raise_for_status()
@ -70,8 +52,7 @@ def listSubjectRoles(args):
sys.exit(-1) sys.exit(-1)
roles = req.json() roles = req.json()
for r in roles.items(): logger.info(json.dumps(roles, indent=4))
sys.stdout.write(r)
sys.exit(0) sys.exit(0)

View File

@ -65,9 +65,7 @@ def list_subjects(args):
logger.error("Failed to obtain response from server.") logger.error("Failed to obtain response from server.")
sys.exit(-1) sys.exit(-1)
for s,d in subjects.json().items(): logger.info(json.dumps(subjects.json(), indent=4))
sys.stdout.write(s + " - " + d['username'] + "\n")
sys.exit(0) sys.exit(0)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -36,13 +36,6 @@ def reactivateRole(args):
logger.error("Need session file and role.") logger.error("Need session file and role.")
sys.exit(1) sys.exit(1)
#Validate role name
process = subprocess.Popen(f"./rep_list_roles {args.role}", shell=True)
process.wait()
if process.returncode != 0:
logger.error("Role does not exist.")
sys.exit(1)
# Check for session file # Check for session file
if not os.path.isfile(BASE_DIR + args.session): if not os.path.isfile(BASE_DIR + args.session):
logger.error("File '" + args.session + "' not found.") logger.error("File '" + args.session + "' not found.")

View File

@ -35,9 +35,6 @@ def removePermission(args):
logger.error("Need session file and role.") logger.error("Need session file and role.")
sys.exit(1) sys.exit(1)
#Validate role name
#TODO
# Check for session file # Check for session file
if not os.path.isfile(BASE_DIR + args.session): if not os.path.isfile(BASE_DIR + args.session):
logger.error("File '" + args.session + "' not found.") logger.error("File '" + args.session + "' not found.")
@ -47,23 +44,21 @@ def removePermission(args):
with open(BASE_DIR + args.session, 'r') as f: with open(BASE_DIR + args.session, 'r') as f:
args.session = json.load(f) args.session = json.load(f)
isPerm = False; isUsername = False isPerm = False; isUsername = False
# query for permission # query for permission
if args.value in ['ROLE_ACL', 'SUBJECT_NEW', 'SUBJECT_DOWN', 'SUBJECT_UP', 'DOC_NEW']: if args.value in [
'ROLE_ACL',
'SUBJECT_NEW',
'SUBJECT_DOWN',
'SUBJECT_UP',
'DOC_NEW',
'ROLE_NEW',
'ROLE_DOWN',
'ROLE_UP',
'ROLE_MOD'
]:
isPerm = True isPerm = True
else:
try:
subjects = requests.get(f'http://{state['REP_ADDRESS']}/user/list',
json=json.dumps({'username' : args.value}),
headers={'Authorization': args.session['token']})
subjects.raise_for_status()
isUsername = True
except requests.exceptions.RequestException as errex:
logger.error("Username doesn't exist.")
sys.exit(1)
if isPerm: if isPerm:
try: try:
@ -73,6 +68,9 @@ def removePermission(args):
except requests.exceptions.RequestException as errex: except requests.exceptions.RequestException as errex:
logger.error("Failed to obtain response from server.") logger.error("Failed to obtain response from server.")
sys.exit(-1) sys.exit(-1)
logger.info("Permission removed from role successfully.")
sys.exit(0)
elif isUsername: elif isUsername:
try: try:
req = requests.post(f'http://{state['REP_ADDRESS']}/role/' + args.role + '/user/remove/' + args.value, req = requests.post(f'http://{state['REP_ADDRESS']}/role/' + args.role + '/user/remove/' + args.value,
@ -81,14 +79,13 @@ def removePermission(args):
except requests.exceptions.RequestException as errex: except requests.exceptions.RequestException as errex:
logger.error("Failed to obtain response from server.") logger.error("Failed to obtain response from server.")
sys.exit(-1) sys.exit(-1)
logger.info("Subject removed from role successfully.")
sys.exit(0)
else: else:
logger.error("Invalid permission or username.") logger.error("Invalid permission or username.")
sys.exit(1) sys.exit(1)
# TODO: print response
req = req.json()
if __name__ == '__main__': if __name__ == '__main__':
removePermission(sys.argv[1:]) removePermission(sys.argv[1:])

View File

@ -45,13 +45,6 @@ def suspendRole(args):
with open(BASE_DIR + args.session, 'r') as f: with open(BASE_DIR + args.session, 'r') as f:
args.session = json.load(f) args.session = json.load(f)
#Validate role name
process = subprocess.Popen(f"./rep_list_roles {args.role}", shell=True)
process.wait()
if process.returncode != 0:
logger.error("Role does not exist.")
sys.exit(1)
try: try:
req = requests.post(f'http://{state['REP_ADDRESS']}/role/' + args.role + '/suspend', headers={'Authorization': args.session['token']}) req = requests.post(f'http://{state['REP_ADDRESS']}/role/' + args.role + '/suspend', headers={'Authorization': args.session['token']})
req.raise_for_status() req.raise_for_status()

View File

@ -49,6 +49,7 @@ def suspendSubject(args):
logger.error("Failed to obtain response from server.") logger.error("Failed to obtain response from server.")
sys.exit(-1) sys.exit(-1)
logger.info("Subject %s has been suspended.", args.username)
sys.exit(0) sys.exit(0)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -45,6 +45,13 @@ def test_rep_create_session():
assert process.returncode == 0 assert process.returncode == 0
def test_rep_list_subjects():
#Test the rep_list_subjects command
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_list_subjects session.json", shell=True)
process.wait()
assert process.returncode == 0
def test_rep_assume_role(): def test_rep_assume_role():
# Test the rep_assume_role command # Test the rep_assume_role command
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_assume_role session.json manager", shell=True) process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_assume_role session.json manager", shell=True)
@ -52,12 +59,126 @@ def test_rep_assume_role():
assert process.returncode == 0 assert process.returncode == 0
def test_rep_list_subjects(): def test_rep_add_role():
#Test the rep_list_subjects command # Test the rep_add_role command
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_list_subjects session.json", shell=True) process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_add_role session.json newrole", shell=True)
process.wait() process.wait()
assert process.returncode == 0 assert process.returncode == 0
def test_rep_add_permission():
# Test the rep_add_permission command
# Add permissions: SUBJECT_NEW, SUBJECT_DOWN, SUBJECT_UP, DOC_NEW, ROLE_NEW, ROLE_DOWN, ROLE_UP, ROLE_MOD
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_add_permission session.json newrole SUBJECT_NEW", shell=True)
process.wait()
assert process.returncode == 0
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_add_permission session.json newrole SUBJECT_DOWN", shell=True)
process.wait()
assert process.returncode == 0
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_add_permission session.json newrole SUBJECT_UP", shell=True)
process.wait()
assert process.returncode == 0
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_add_permission session.json newrole DOC_NEW", shell=True)
process.wait()
assert process.returncode == 0
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_add_permission session.json newrole ROLE_NEW", shell=True)
process.wait()
assert process.returncode == 0
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_add_permission session.json newrole ROLE_DOWN", shell=True)
process.wait()
assert process.returncode == 0
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_add_permission session.json newrole ROLE_UP", shell=True)
process.wait()
assert process.returncode == 0
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_add_permission session.json newrole ROLE_MOD", shell=True)
process.wait()
assert process.returncode == 0
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_add_permission session.json newrole ROLE_ACL", shell=True)
process.wait()
assert process.returncode == 0
def test_rep_remove_permission():
# Test the rep_remove_permission command
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_remove_permission session.json newrole ROLE_ACL", shell=True)
process.wait()
assert process.returncode == 0
def test_rep_suspend_role():
# Test the rep_suspend_role command
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_suspend_role session.json newrole", shell=True)
process.wait()
assert process.returncode == 0
def test_rep_reactivate_role():
# Test the rep_activate_role command
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_reactivate_role session.json newrole", shell=True)
process.wait()
assert process.returncode == 0
def test_rep_add_permission_user():
# Test the rep_add_permission command with username
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_add_permission session.json newrole username", shell=True)
process.wait()
assert process.returncode == 0
def test_rep_drop_role():
# Test the rep_drop_role command
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_drop_role session.json manager", shell=True)
process.wait()
assert process.returncode == 0
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_assume_role session.json newrole", shell=True)
process.wait()
assert process.returncode == 0
def test_rep_list_roles():
# Test the rep_list_roles command
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_list_roles session.json", shell=True)
process.wait()
assert process.returncode == 0
def test_rep_list_role_subjects():
# Test the rep_list_role_subjects command
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_list_role_subjects session.json newrole", shell=True)
process.wait()
assert process.returncode == 0
def test_rep_list_subject_roles():
# Test the rep_list_subject_roles command
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_list_subject_roles session.json username", shell=True)
process.wait()
assert process.returncode == 0
def test_rep_list_role_permissions():
# Test the rep_list_role_permissions command
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_list_role_permissions session.json newrole", shell=True)
process.wait()
assert process.returncode == 0
def test_rep_list_permission_roles():
# Test the rep_list_permission_roles command
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_list_permission_roles session.json SUBJECT_NEW", shell=True)
process.wait()
assert process.returncode == 0
def test_rep_add_subject(): def test_rep_add_subject():
# Test the rep_subject_create command # Test the rep_subject_create command
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_subject_credentials password pub_extra.pem priv_extra.pem ", shell=True) process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_subject_credentials password pub_extra.pem priv_extra.pem ", shell=True)
@ -93,8 +214,43 @@ def test_rep_add_doc():
process.wait() process.wait()
assert process.returncode == 0 assert process.returncode == 0
def test_rep_acl_doc():
# Test the rep_acl_doc command
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_acl_doc session.json doc - newrole DOC_READ", shell=True)
process.wait()
assert process.returncode == 0
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_acl_doc session.json doc - newrole DOC_DELETE", shell=True)
process.wait()
assert process.returncode == 0
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_acl_doc session.json doc + newrole DOC_READ", shell=True)
process.wait()
assert process.returncode == 0
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_acl_doc session.json doc + newrole DOC_DELETE", shell=True)
process.wait()
assert process.returncode == 0
def test_rep_list_docs():
# Test the rep_list_docs command
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_list_docs session.json", shell=True)
process.wait()
assert process.returncode == 0
def test_rep_list_permission_roles_with_file():
# Test the rep_list_permission_roles command
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_list_permission_roles session.json DOC_READ", shell=True)
process.wait()
assert process.returncode == 0
metadata = {} metadata = {}
def test_rep_get_doc_metadata(): def test_rep_get_doc_metadata():
# Test the rep_get_doc_metadata command # Test the rep_get_doc_metadata command
global metadata global metadata
@ -133,7 +289,9 @@ def test_rep_delete_doc():
assert process.returncode == 0 assert process.returncode == 0
def test_rep_list_docs_after_deletion():
# Test the rep_list_docs command
process = subprocess.Popen(f"{DELIVERY_PATH}/client/bin/rep_list_docs session.json", shell=True)
process.wait()
assert process.returncode == 0

View File

@ -1,4 +1,5 @@
import os import os
import sys
import sqlalchemy.exc import sqlalchemy.exc
from flask import Flask, request, jsonify from flask import Flask, request, jsonify
from routes import org_bp, user_bp, file_bp, role_bp from routes import org_bp, user_bp, file_bp, role_bp
@ -25,6 +26,18 @@ app.register_blueprint(file_bp, url_prefix="/file")
app.register_blueprint(role_bp, url_prefix="/role") app.register_blueprint(role_bp, url_prefix="/role")
def reset_all():
with app.app_context():
db_connection.drop_all()
db_connection.create_all()
repos = os.path.join(os.path.dirname(os.path.abspath(__file__)), "repository")
for repo in os.listdir(repos):
if os.path.isdir(os.path.join(repos, repo)):
for file in os.listdir(os.path.join(repos, repo)):
os.remove(os.path.join(repos, repo, file))
os.rmdir(os.path.join(repos, repo))
@app.route("/", methods=["GET"]) @app.route("/", methods=["GET"])
def index(): def index():
return jsonify({"message": "Welcome to the API"}), 200 return jsonify({"message": "Welcome to the API"}), 200
@ -36,18 +49,19 @@ def reset():
if password != "123": if password != "123":
return jsonify({"error": "Invalid password"}), 403 return jsonify({"error": "Invalid password"}), 403
try: try:
with app.app_context(): reset_all()
db_connection.drop_all()
db_connection.create_all()
repos = os.path.join(os.path.dirname(os.path.abspath(__file__)), "repository")
for repo in os.listdir(repos):
if os.path.isdir(os.path.join(repos, repo)):
for file in os.listdir(os.path.join(repos, repo)):
os.remove(os.path.join(repos, repo, file))
os.rmdir(os.path.join(repos, repo))
except sqlalchemy.exc.OperationalError: except sqlalchemy.exc.OperationalError:
return jsonify({"error": "Database error"}), 500 return jsonify({"error": "Database error"}), 500
return jsonify({"message": "Database reset"}), 200 return jsonify({"message": "Database reset"}), 200
if __name__ == "__main__": if __name__ == "__main__":
args = sys.argv[1:]
for arg in args:
if arg == "--reset":
try:
reset_all()
except sqlalchemy.exc.OperationalError:
print("Database error")
sys.exit(1)
break
app.run(debug=True) app.run(debug=True)

View File

@ -27,8 +27,12 @@ class File(db_connection.Model):
"created_at": self.created_at, "created_at": self.created_at,
"acl": self.acl, "acl": self.acl,
"deleter_id": self.deleter_id, "deleter_id": self.deleter_id,
"key": self.key,
"alg": self.alg,
"org": {"id": self.org.id, "name": self.org.name}, "org": {"id": self.org.id, "name": self.org.name},
"creator": {"id": self.creator.id, "username": self.creator.username}, "creator": {"id": self.creator.id, "username": self.creator.username},
} }
def get_encrytion(self):
return {
"key": self.key,
"alg": self.alg
}

View File

@ -34,7 +34,7 @@ def file_get_metadata(document_handle: str):
if not file: if not file:
return jsonify({"error": "File not found"}), 404 return jsonify({"error": "File not found"}), 404
return jsonify(file.to_dict()) return jsonify(file.to_dict() | file.get_encrytion())
@file_bp.route("/upload/metadata", methods=["POST"]) @file_bp.route("/upload/metadata", methods=["POST"])
@ -201,28 +201,3 @@ def file_acl():
return jsonify(file.to_dict()), 200 return jsonify(file.to_dict()), 200
################################################
@file_bp.route("/create_dummy", methods=["POST"])
def file_create_dummy():
session_token = request.headers.get("Authorization")
if not session_token:
return jsonify({"error": "No session token"}), 400
session = SessionService.validate_session(session_token)
if isinstance(session, tuple):
return session
org = OrganizationService.get_organization(session.org_id)
if not org:
return jsonify({"error": "Organization not found"}), 404
user = UserService.get_user(session.user_id)
if not user:
return jsonify({"error": "User not found"}), 404
file = FileService.create_dummy_file(org, user)
return jsonify(file.to_dict()), 201

View File

@ -12,7 +12,7 @@ def role_create():
if type(data) is str: if type(data) is str:
data = json.loads(data) data = json.loads(data)
if "role" not in data or "perms" not in data: if "role" not in data:
return jsonify({"error": "Missing required fields"}), 400 return jsonify({"error": "Missing required fields"}), 400
session_token = request.headers.get("Authorization") session_token = request.headers.get("Authorization")
@ -28,7 +28,7 @@ def role_create():
return jsonify({"error": "Organization not found"}), 404 return jsonify({"error": "Organization not found"}), 404
try: try:
role = RoleService.create_role(org, data["role"], data["perms"]) role = RoleService.create_role(org, data["role"], [])
except ValueError as e: except ValueError as e:
return jsonify({"error": str(e)}), 400 return jsonify({"error": str(e)}), 400
@ -77,13 +77,6 @@ def role_list_perms(role):
@role_bp.route("/<string:role>/suspend", methods=["POST"]) @role_bp.route("/<string:role>/suspend", methods=["POST"])
def role_suspend(role): def role_suspend(role):
data = request.json
if type(data) is str:
data = json.loads(data)
if "user" not in data:
return jsonify({"error": "Missing required fields"}), 400
session_token = request.headers.get("Authorization") session_token = request.headers.get("Authorization")
if not session_token: if not session_token:
return jsonify({"error": "No session token"}), 400 return jsonify({"error": "No session token"}), 400
@ -105,13 +98,6 @@ def role_suspend(role):
@role_bp.route("/<string:role>/activate", methods=["POST"]) @role_bp.route("/<string:role>/activate", methods=["POST"])
def role_activate(role): def role_activate(role):
data = request.json
if type(data) is str:
data = json.loads(data)
if "user" not in data:
return jsonify({"error": "Missing required fields"}), 400
session_token = request.headers.get("Authorization") session_token = request.headers.get("Authorization")
if not session_token: if not session_token:
return jsonify({"error": "No session token"}), 400 return jsonify({"error": "No session token"}), 400
@ -133,13 +119,6 @@ def role_activate(role):
@role_bp.route("/<string:role>/user/add/<username>", methods=["POST"]) @role_bp.route("/<string:role>/user/add/<username>", methods=["POST"])
def role_user_add(role, username): def role_user_add(role, username):
data = request.json
if type(data) is str:
data = json.loads(data)
if "user" not in data:
return jsonify({"error": "Missing required fields"}), 400
session_token = request.headers.get("Authorization") session_token = request.headers.get("Authorization")
if not session_token: if not session_token:
return jsonify({"error": "No session token"}), 400 return jsonify({"error": "No session token"}), 400
@ -165,13 +144,6 @@ def role_user_add(role, username):
@role_bp.route("/<string:role>/user/remove/<username>", methods=["POST"]) @role_bp.route("/<string:role>/user/remove/<username>", methods=["POST"])
def role_user_remove(role, username): def role_user_remove(role, username):
data = request.json
if type(data) is str:
data = json.loads(data)
if "user" not in data:
return jsonify({"error": "Missing required fields"}), 400
session_token = request.headers.get("Authorization") session_token = request.headers.get("Authorization")
if not session_token: if not session_token:
return jsonify({"error": "No session token"}), 400 return jsonify({"error": "No session token"}), 400
@ -197,13 +169,6 @@ def role_user_remove(role, username):
@role_bp.route("/<string:role>/perm/add/<perm>", methods=["POST"]) @role_bp.route("/<string:role>/perm/add/<perm>", methods=["POST"])
def role_perm_add(role, perm): def role_perm_add(role, perm):
data = request.json
if type(data) is str:
data = json.loads(data)
if "user" not in data:
return jsonify({"error": "Missing required fields"}), 400
session_token = request.headers.get("Authorization") session_token = request.headers.get("Authorization")
if not session_token: if not session_token:
return jsonify({"error": "No session token"}), 400 return jsonify({"error": "No session token"}), 400
@ -225,13 +190,6 @@ def role_perm_add(role, perm):
@role_bp.route("/<string:role>/perm/remove/<perm>", methods=["POST"]) @role_bp.route("/<string:role>/perm/remove/<perm>", methods=["POST"])
def role_perm_remove(role, perm): def role_perm_remove(role, perm):
data = request.json
if type(data) is str:
data = json.loads(data)
if "user" not in data:
return jsonify({"error": "Missing required fields"}), 400
session_token = request.headers.get("Authorization") session_token = request.headers.get("Authorization")
if not session_token: if not session_token:
return jsonify({"error": "No session token"}), 400 return jsonify({"error": "No session token"}), 400
@ -322,7 +280,12 @@ def perm_list_roles(perm):
if not org: if not org:
return jsonify({"error": "Organization not found"}), 404 return jsonify({"error": "Organization not found"}), 404
roles = RoleService.get_roles_for_perm(org, Perm(perm)) try:
roles = RoleService.get_roles_for_perm(org, Perm.from_str(perm))
except ValueError:
return jsonify({"error": "Invalid permission"}), 400
except NameError:
return jsonify({"error": "Invalid permission"}), 400
if isinstance(roles, tuple): if isinstance(roles, tuple):
return roles return roles
return jsonify(roles), 200 return jsonify(roles), 200

View File

@ -43,7 +43,7 @@ def user_login():
session = SessionService.verify_session(session_token, signature) session = SessionService.verify_session(session_token, signature)
if isinstance(session, tuple): if isinstance(session, tuple):
return session return session
return jsonify(session.to_dict()), 200 return jsonify(session.to_dict()), 201
return jsonify({"error": "Missing required fields"}), 400 return jsonify({"error": "Missing required fields"}), 400

View File

@ -14,6 +14,7 @@ class FileService:
self.current_requests = {} self.current_requests = {}
def create_file(self, session_token: str, org: Organization, user: User, file_name: str, key: str, alg: str) -> File: def create_file(self, session_token: str, org: Organization, user: User, file_name: str, key: str, alg: str) -> File:
from services import SessionService
file = File( file = File(
file_handle = None, file_handle = None,
document_handle = get_hash(file_name), document_handle = get_hash(file_name),
@ -25,7 +26,11 @@ class FileService:
Perm.DOC_READ, Perm.DOC_READ,
Perm.DOC_DELETE, Perm.DOC_DELETE,
]) ])
}, } | {role: Perm.get_int([
Perm.DOC_ACL,
Perm.DOC_READ,
Perm.DOC_DELETE
]) for role in SessionService.list_roles(SessionService.get_session(session_token))},
key = key, key = key,
alg = alg, alg = alg,
org_id = org.id, org_id = org.id,

View File

@ -66,7 +66,7 @@ class RoleService:
if not file: if not file:
return jsonify({"error": "File not found"}), 404 return jsonify({"error": "File not found"}), 404
if not Perm.check_perm(file.acl[role], perm.value): if role not in file.acl or not Perm.check_perm(file.acl[role], perm.value):
return False return False
return True return True
@ -90,9 +90,10 @@ class RoleService:
@staticmethod @staticmethod
def get_users_in_role(org: Organization, role: str) -> list | tuple: def get_users_in_role(org: Organization, role: str) -> list | tuple:
from services import UserService
if role not in org.roles: if role not in org.roles:
return jsonify({"error": f"Role {role} does not exist in organization {org.name}"}), 400 return jsonify({"error": f"Role {role} does not exist in organization {org.name}"}), 400
return org.roles[role]["users"] return [UserService.get_user(user_id).username for user_id in org.roles[role]["users"]]
@staticmethod @staticmethod
def get_roles_for_user(user: User, org: Organization) -> list: def get_roles_for_user(user: User, org: Organization) -> list:
@ -109,10 +110,20 @@ class RoleService:
@staticmethod @staticmethod
def get_roles_for_perm(org: Organization, perm: Perm) -> list: def get_roles_for_perm(org: Organization, perm: Perm) -> list:
from services import FileService
roles = [] roles = []
if Perm.get_int([perm]) > 0b111:
for role in org.roles: for role in org.roles:
if RoleService.check_role_permission(org, role, perm): if RoleService.check_role_permission(org, role, perm):
roles.append(role) roles.append(role)
else:
for file in FileService.list_files_in_org(org):
file_roles = []
for role in file.acl:
if Perm.check_perm(file.acl[role], perm.value):
file_roles.append(role)
if file_roles:
roles.append({file.name: file_roles})
return roles return roles
@staticmethod @staticmethod
@ -127,7 +138,9 @@ class RoleService:
return jsonify({"error": f"Role {role} is not active in organization {org.name}"}), 400 return jsonify({"error": f"Role {role} is not active in organization {org.name}"}), 400
roles = user.roles.copy() roles = user.roles.copy()
roles[org.id] = role if str(org.id) not in roles or not roles[str(org.id)]:
roles[str(org.id)] = []
roles[str(org.id)].append(role)
user.roles = roles user.roles = roles
flag_modified(user, "roles") flag_modified(user, "roles")
db.commit() db.commit()
@ -153,7 +166,7 @@ class RoleService:
return jsonify({"error": f"Role {role} is not active in organization {org.name}"}), 400 return jsonify({"error": f"Role {role} is not active in organization {org.name}"}), 400
roles = user.roles.copy() roles = user.roles.copy()
roles.pop(org.id) roles[str(org.id)].remove(role)
user.roles = roles user.roles = roles
flag_modified(user, "roles") flag_modified(user, "roles")
db.commit() db.commit()
@ -194,8 +207,8 @@ class RoleService:
if role not in file.acl: if role not in file.acl:
file.acl[role] = 0 file.acl[role] = 0
if file.acl[role] & perm.value != 0: if (file.acl[role] & perm.value != 0 and operation == PermOperation.ADD) or (file.acl[role] & perm.value == 0 and operation == PermOperation.REMOVE):
return jsonify({"error": f"Role {role} already has permission {perm} in file {file.document_handle}"}), 400 return jsonify({"error": f"Role {role} already has permission {perm} in file {file.name}"}), 400
file.acl[role] = PermOperation.calc(file.acl[role], perm, operation) file.acl[role] = PermOperation.calc(file.acl[role], perm, operation)
flag_modified(file, "acl") flag_modified(file, "acl")

View File

@ -112,6 +112,7 @@ class SessionService:
session.roles.append(role) session.roles.append(role)
elif operation == "drop": elif operation == "drop":
if role not in user.roles[str(org.id)]: if role not in user.roles[str(org.id)]:
print(user.roles)
return jsonify({"error": f"User {user.username} does not have role {role}"}), 400 return jsonify({"error": f"User {user.username} does not have role {role}"}), 400
if role not in session.roles: if role not in session.roles:

View File

@ -15,21 +15,29 @@ Content-Type: application/json
"username": "username", "username": "username",
"full_name": "Full Name", "full_name": "Full Name",
"email": "user@mail.com", "email": "user@mail.com",
"public_key": "null" "public_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtV6PE1i2vlhCAjlzTFVt\n7v96feZHl4b5ZlHwlKLdac+ULt9b1ACWFFtMwdAoFlY6u+ijt4PaEvsKx0WSNqlI\nz4WwRYjCz8tZr+52yXzD/swZ71CponI/nofMkUUtt17SBYNLNbAWcltk69FULfMF\nSPgO+AWgN4dPnGBTotoKfVhQCWWTan6sUSTYEVgLgdZov68mn5bSHZ3NppZYIsOb\nfVL+lN/kpC0BHTrgQSoKGZcBV3tbLUg724uO7j5DNCNfUcPFbCdUEkQq+zGTaaxG\nsy335YN19x8asSvs/jGv9mhJajgr3PfD+fd5DiLecDOmgcAOBPqdGWDjqP5x6ViG\ntwIDAQAB\n-----END PUBLIC KEY-----"
} }
### Login ### Login (get token)
POST http://localhost:5000/user/login POST http://localhost:5000/user/login
Content-Type: application/json Content-Type: application/json
{ {
"username": "username", "username": "username",
"org": "org", "org": "org"
"public_key": "null"
} }
> {% client.global.set("token", response.body["token"]) %} > {% client.global.set("token", response.body["token"]) %}
### Verify token
POST http://localhost:5000/user/login
Content-Type: application/json
Authorization: {{token}}
{
"signature": "signature"
}
### List organizations ### List organizations
GET http://localhost:5000/org/list GET http://localhost:5000/org/list

View File

@ -25,7 +25,9 @@ class Perm(Enum):
@staticmethod @staticmethod
def from_str(perm_name): def from_str(perm_name):
return Perm[perm_name] for perm in Perm:
if perm.name == perm_name:
return perm
@staticmethod @staticmethod
def get_perms(bit_array: int, return_str=False): def get_perms(bit_array: int, return_str=False):