summaryrefslogtreecommitdiff
path: root/opendc-web
diff options
context:
space:
mode:
Diffstat (limited to 'opendc-web')
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/scenarios/test_endpoint.py4
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/test_endpoint.py15
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/prefabs/authorizations/endpoint.py7
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/prefabs/endpoint.py5
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/prefabs/prefabId/test_endpoint.py6
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/projects/endpoint.py14
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/__init__.py0
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/endpoint.py17
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/test_endpoint.py43
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/endpoint.py6
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/portfolios/test_endpoint.py4
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/test_endpoint.py15
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/topologies/test_endpoint.py4
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/projects/test_endpoint.py7
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/test_endpoint.py90
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/topologies/topologyId/test_endpoint.py16
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/users/__init__.py0
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/users/endpoint.py30
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/users/test_endpoint.py34
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/users/userId/__init__.py0
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/users/userId/endpoint.py59
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/users/userId/test_endpoint.py56
-rw-r--r--opendc-web/opendc-web-api/opendc/models/portfolio.py17
-rw-r--r--opendc-web/opendc-web-api/opendc/models/prefab.py19
-rw-r--r--opendc-web/opendc-web-api/opendc/models/project.py29
-rw-r--r--opendc-web/opendc-web-api/opendc/models/scenario.py16
-rw-r--r--opendc-web/opendc-web-api/opendc/models/topology.py20
-rw-r--r--opendc-web/opendc-web-api/opendc/models/user.py36
28 files changed, 108 insertions, 461 deletions
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/scenarios/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/scenarios/test_endpoint.py
index e5982b7f..ff1666c0 100644
--- a/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/scenarios/test_endpoint.py
+++ b/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/scenarios/test_endpoint.py
@@ -37,7 +37,7 @@ def test_add_scenario_not_authorized(client, mocker):
'projectId': test_id,
'portfolioId': test_id,
'authorizations': [{
- 'projectId': test_id,
+ 'userId': 'test',
'authorizationLevel': 'VIEW'
}]
})
@@ -71,7 +71,7 @@ def test_add_scenario(client, mocker):
'portfolioIds': [test_id],
'scenarioIds': [test_id],
'authorizations': [{
- 'projectId': test_id,
+ 'userId': 'test',
'authorizationLevel': 'EDIT'
}],
'simulation': {
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/test_endpoint.py
index 52f71aa4..1a44c63d 100644
--- a/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/test_endpoint.py
+++ b/opendc-web/opendc-web-api/opendc/api/v2/portfolios/portfolioId/test_endpoint.py
@@ -21,10 +21,7 @@ def test_get_portfolio_not_authorized(client, mocker):
return_value={
'projectId': test_id,
'_id': test_id,
- 'authorizations': [{
- 'projectId': test_id_2,
- 'authorizationLevel': 'OWN'
- }]
+ 'authorizations': []
})
res = client.get(f'/v2/portfolios/{test_id}')
assert '403' in res.status
@@ -37,7 +34,7 @@ def test_get_portfolio(client, mocker):
'projectId': test_id,
'_id': test_id,
'authorizations': [{
- 'projectId': test_id,
+ 'userId': 'test',
'authorizationLevel': 'EDIT'
}]
})
@@ -69,7 +66,7 @@ def test_update_portfolio_not_authorized(client, mocker):
'_id': test_id,
'projectId': test_id,
'authorizations': [{
- 'projectId': test_id,
+ 'userId': 'test',
'authorizationLevel': 'VIEW'
}]
})
@@ -92,7 +89,7 @@ def test_update_portfolio(client, mocker):
'_id': test_id,
'projectId': test_id,
'authorizations': [{
- 'projectId': test_id,
+ 'userId': 'test',
'authorizationLevel': 'OWN'
}],
'targets': {
@@ -125,7 +122,7 @@ def test_delete_project_different_user(client, mocker):
'projectId': test_id,
'googleId': 'other_test',
'authorizations': [{
- 'projectId': test_id,
+ 'userId': 'test',
'authorizationLevel': 'VIEW'
}]
})
@@ -142,7 +139,7 @@ def test_delete_project(client, mocker):
'googleId': 'test',
'portfolioIds': [test_id],
'authorizations': [{
- 'projectId': test_id,
+ 'userId': 'test',
'authorizationLevel': 'OWN'
}]
})
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/authorizations/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/authorizations/endpoint.py
index 0de50851..5a8d367f 100644
--- a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/authorizations/endpoint.py
+++ b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/authorizations/endpoint.py
@@ -1,17 +1,14 @@
from opendc.models.prefab import Prefab
from opendc.util.database import DB
-from opendc.models.user import User
from opendc.util.rest import Response
def GET(request):
"""Return all prefabs the user is authorized to access"""
- user = User.from_google_id(request.current_user['sub'])
+ user_id = request.current_user['sub']
- user.check_exists()
-
- own_prefabs = DB.fetch_all({'authorId': user.get_id()}, Prefab.collection_name)
+ own_prefabs = DB.fetch_all({'authorId': user_id}, Prefab.collection_name)
public_prefabs = DB.fetch_all({'visibility': 'public'}, Prefab.collection_name)
authorizations = {"authorizations": []}
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/endpoint.py
index e77c7150..4a30f7eb 100644
--- a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/endpoint.py
+++ b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/endpoint.py
@@ -1,7 +1,6 @@
from datetime import datetime
from opendc.models.prefab import Prefab
-from opendc.models.user import User
from opendc.util.database import Database
from opendc.util.rest import Response
@@ -15,8 +14,8 @@ def POST(request):
prefab.set_property('datetimeCreated', Database.datetime_to_string(datetime.now()))
prefab.set_property('datetimeLastEdited', Database.datetime_to_string(datetime.now()))
- user = User.from_google_id(request.current_user['sub'])
- prefab.set_property('authorId', user.get_id())
+ user_id = request.current_user['sub']
+ prefab.set_property('authorId', user_id)
prefab.insert()
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/prefabId/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/prefabId/test_endpoint.py
index 2daeb6bf..bc3b1a32 100644
--- a/opendc-web/opendc-web-api/opendc/api/v2/prefabs/prefabId/test_endpoint.py
+++ b/opendc-web/opendc-web-api/opendc/api/v2/prefabs/prefabId/test_endpoint.py
@@ -32,7 +32,7 @@ def test_get_private_prefab(client, mocker):
DB.fetch_one.side_effect = [{
'_id': test_id,
'name': 'test prefab',
- 'authorId': test_id,
+ 'authorId': 'test',
'visibility': 'private',
'rack': {}
},
@@ -92,7 +92,7 @@ def test_update_prefab(client, mocker):
DB.fetch_one.side_effect = [{
'_id': test_id,
'name': 'test prefab',
- 'authorId': test_id,
+ 'authorId': 'test',
'visibility': 'private',
'rack': {}
},
@@ -132,7 +132,7 @@ def test_delete_prefab(client, mocker):
DB.fetch_one.side_effect = [{
'_id': test_id,
'name': 'test prefab',
- 'authorId': test_id,
+ 'authorId': 'test',
'visibility': 'private',
'rack': {}
},
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/endpoint.py
index dacbe6a4..b381d689 100644
--- a/opendc-web/opendc-web-api/opendc/api/v2/projects/endpoint.py
+++ b/opendc-web/opendc-web-api/opendc/api/v2/projects/endpoint.py
@@ -2,15 +2,22 @@ from datetime import datetime
from opendc.models.project import Project
from opendc.models.topology import Topology
-from opendc.models.user import User
from opendc.util.database import Database
from opendc.util.rest import Response
+def GET(request):
+ """Get the authorized projects of the user"""
+ user_id = request.current_user['sub']
+ projects = Project.get_for_user(user_id)
+ return Response(200, 'Successfully retrieved projects', projects)
+
+
def POST(request):
"""Create a new project, and return that new project."""
request.check_required_parameters(body={'project': {'name': 'string'}})
+ user_id = request.current_user['sub']
topology = Topology({'name': 'Default topology', 'rooms': []})
topology.insert()
@@ -20,13 +27,10 @@ def POST(request):
project.set_property('datetimeLastEdited', Database.datetime_to_string(datetime.now()))
project.set_property('topologyIds', [topology.get_id()])
project.set_property('portfolioIds', [])
+ project.set_property('authorizations', [{'userId': user_id, 'authorizationLevel': 'OWN'}])
project.insert()
topology.set_property('projectId', project.get_id())
topology.update()
- user = User.from_google_id(request.current_user['sub'])
- user.obj['authorizations'].append({'projectId': project.get_id(), 'authorizationLevel': 'OWN'})
- user.update()
-
return Response(200, 'Successfully created project.', project.obj)
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/__init__.py
+++ /dev/null
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/endpoint.py
deleted file mode 100644
index 1b229122..00000000
--- a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/endpoint.py
+++ /dev/null
@@ -1,17 +0,0 @@
-from opendc.models.project import Project
-from opendc.util.rest import Response
-
-
-def GET(request):
- """Find all authorizations for a Project."""
-
- request.check_required_parameters(path={'projectId': 'string'})
-
- project = Project.from_id(request.params_path['projectId'])
-
- project.check_exists()
- project.check_user_access(request.current_user['sub'], False)
-
- authorizations = project.get_all_authorizations()
-
- return Response(200, 'Successfully retrieved project authorizations', authorizations)
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/test_endpoint.py
deleted file mode 100644
index bebd6cff..00000000
--- a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/authorizations/test_endpoint.py
+++ /dev/null
@@ -1,43 +0,0 @@
-from opendc.util.database import DB
-
-test_id = 24 * '1'
-test_id_2 = 24 * '2'
-
-
-def test_get_authorizations_non_existing(client, mocker):
- mocker.patch.object(DB, 'fetch_one', return_value=None)
- mocker.patch.object(DB, 'fetch_all', return_value=None)
- assert '404' in client.get(f'/v2/projects/{test_id}/authorizations').status
-
-
-def test_get_authorizations_not_authorized(client, mocker):
- mocker.patch.object(DB,
- 'fetch_one',
- return_value={
- '_id': test_id,
- 'name': 'test trace',
- 'authorizations': [{
- 'projectId': test_id_2,
- 'authorizationLevel': 'OWN'
- }]
- })
- mocker.patch.object(DB, 'fetch_all', return_value=[])
- res = client.get(f'/v2/projects/{test_id}/authorizations')
- assert '403' in res.status
-
-
-def test_get_authorizations(client, mocker):
- mocker.patch.object(DB,
- 'fetch_one',
- return_value={
- '_id': test_id,
- 'name': 'test trace',
- 'authorizations': [{
- 'projectId': test_id,
- 'authorizationLevel': 'OWN'
- }]
- })
- mocker.patch.object(DB, 'fetch_all', return_value=[])
- res = client.get(f'/v2/projects/{test_id}/authorizations')
- assert len(res.json['content']) == 0
- assert '200' in res.status
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/endpoint.py
index 37cf1860..fa53ce6b 100644
--- a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/endpoint.py
+++ b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/endpoint.py
@@ -3,7 +3,6 @@ from datetime import datetime
from opendc.models.portfolio import Portfolio
from opendc.models.project import Project
from opendc.models.topology import Topology
-from opendc.models.user import User
from opendc.util.database import Database
from opendc.util.rest import Response
@@ -56,11 +55,6 @@ def DELETE(request):
portfolio = Portfolio.from_id(portfolio_id)
portfolio.delete()
- user = User.from_google_id(request.current_user['sub'])
- user.obj['authorizations'] = list(
- filter(lambda x: x['projectId'] != project.get_id(), user.obj['authorizations']))
- user.update()
-
old_object = project.delete()
return Response(200, 'Successfully deleted project.', old_object)
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/portfolios/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/portfolios/test_endpoint.py
index 04c699b5..7ddfe0ce 100644
--- a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/portfolios/test_endpoint.py
+++ b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/portfolios/test_endpoint.py
@@ -28,7 +28,7 @@ def test_add_portfolio_not_authorized(client, mocker):
'_id': test_id,
'projectId': test_id,
'authorizations': [{
- 'projectId': test_id,
+ 'userId': 'test',
'authorizationLevel': 'VIEW'
}]
})
@@ -52,7 +52,7 @@ def test_add_portfolio(client, mocker):
'projectId': test_id,
'portfolioIds': [test_id],
'authorizations': [{
- 'projectId': test_id,
+ 'userId': 'test',
'authorizationLevel': 'EDIT'
}]
})
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/test_endpoint.py
index f9ffaf37..03e6758b 100644
--- a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/test_endpoint.py
+++ b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/test_endpoint.py
@@ -20,10 +20,7 @@ def test_get_project_not_authorized(client, mocker):
'fetch_one',
return_value={
'_id': test_id,
- 'authorizations': [{
- 'projectId': test_id_2,
- 'authorizationLevel': 'OWN'
- }]
+ 'authorizations': []
})
res = client.get(f'/v2/projects/{test_id}')
assert '403' in res.status
@@ -35,7 +32,7 @@ def test_get_project(client, mocker):
return_value={
'_id': test_id,
'authorizations': [{
- 'projectId': test_id,
+ 'userId': 'test',
'authorizationLevel': 'EDIT'
}]
})
@@ -58,7 +55,7 @@ def test_update_project_not_authorized(client, mocker):
return_value={
'_id': test_id,
'authorizations': [{
- 'projectId': test_id,
+ 'userId': 'test',
'authorizationLevel': 'VIEW'
}]
})
@@ -72,7 +69,7 @@ def test_update_project(client, mocker):
return_value={
'_id': test_id,
'authorizations': [{
- 'projectId': test_id,
+ 'userId': 'test',
'authorizationLevel': 'OWN'
}]
})
@@ -94,7 +91,7 @@ def test_delete_project_different_user(client, mocker):
'_id': test_id,
'googleId': 'other_test',
'authorizations': [{
- 'projectId': test_id,
+ 'userId': 'test',
'authorizationLevel': 'VIEW'
}],
'topologyIds': []
@@ -110,7 +107,7 @@ def test_delete_project(client, mocker):
'_id': test_id,
'googleId': 'test',
'authorizations': [{
- 'projectId': test_id,
+ 'userId': 'test',
'authorizationLevel': 'OWN'
}],
'topologyIds': [],
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/topologies/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/topologies/test_endpoint.py
index 71e88f00..2e872415 100644
--- a/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/topologies/test_endpoint.py
+++ b/opendc-web/opendc-web-api/opendc/api/v2/projects/projectId/topologies/test_endpoint.py
@@ -13,7 +13,7 @@ def test_add_topology(client, mocker):
return_value={
'_id': test_id,
'authorizations': [{
- 'projectId': test_id,
+ 'userId': 'test',
'authorizationLevel': 'OWN'
}],
'topologyIds': []
@@ -39,7 +39,7 @@ def test_add_topology_not_authorized(client, mocker):
'_id': test_id,
'projectId': test_id,
'authorizations': [{
- 'projectId': test_id,
+ 'userId': 'test',
'authorizationLevel': 'VIEW'
}]
})
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/projects/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/projects/test_endpoint.py
index 9444b1e4..db768f28 100644
--- a/opendc-web/opendc-web-api/opendc/api/v2/projects/test_endpoint.py
+++ b/opendc-web/opendc-web-api/opendc/api/v2/projects/test_endpoint.py
@@ -3,6 +3,13 @@ from opendc.util.database import DB
test_id = 24 * '1'
+def test_get_user_projects(client, mocker):
+ mocker.patch.object(DB, 'fetch_all', return_value={'_id': test_id, 'authorizations': [{'userId': 'test',
+ 'authorizationLevel': 'OWN'}]})
+ res = client.get('/v2/projects')
+ assert '200' in res.status
+
+
def test_add_project_missing_parameter(client):
assert '400' in client.post('/v2/projects').status
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/test_endpoint.py
index cd4bcdf8..24b38671 100644
--- a/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/test_endpoint.py
+++ b/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/test_endpoint.py
@@ -10,26 +10,9 @@ def test_get_scenario_non_existing(client, mocker):
def test_get_scenario_no_authorizations(client, mocker):
- mocker.patch.object(DB, 'fetch_one', return_value={
- 'portfolioId': '1',
- 'authorizations': []
- })
- res = client.get(f'/v2/scenarios/{test_id}')
- assert '403' in res.status
-
-
-def test_get_scenario_not_authorized(client, mocker):
- mocker.patch.object(DB,
- 'fetch_one',
- return_value={
- 'projectId': test_id,
- 'portfolioId': test_id,
- '_id': test_id,
- 'authorizations': [{
- 'projectId': test_id_2,
- 'authorizationLevel': 'OWN'
- }]
- })
+ m = mocker.MagicMock()
+ m.side_effect = ({'portfolioId': test_id}, {'projectId': test_id}, {'authorizations': []})
+ mocker.patch.object(DB, 'fetch_one', m)
res = client.get(f'/v2/scenarios/{test_id}')
assert '403' in res.status
@@ -37,15 +20,12 @@ def test_get_scenario_not_authorized(client, mocker):
def test_get_scenario(client, mocker):
mocker.patch.object(DB,
'fetch_one',
- return_value={
- 'projectId': test_id,
- 'portfolioId': test_id,
- '_id': test_id,
- 'authorizations': [{
- 'projectId': test_id,
- 'authorizationLevel': 'EDIT'
- }]
- })
+ side_effect=[
+ {'portfolioId': test_id},
+ {'projectId': test_id},
+ {'authorizations':
+ [{'userId': 'test', 'authorizationLevel': 'OWN'}]
+ }])
res = client.get(f'/v2/scenarios/{test_id}')
assert '200' in res.status
@@ -66,15 +46,12 @@ def test_update_scenario_non_existing(client, mocker):
def test_update_scenario_not_authorized(client, mocker):
mocker.patch.object(DB,
'fetch_one',
- return_value={
- '_id': test_id,
- 'projectId': test_id,
- 'portfolioId': test_id,
- 'authorizations': [{
- 'projectId': test_id,
- 'authorizationLevel': 'VIEW'
- }]
- })
+ side_effect=[
+ {'portfolioId': test_id},
+ {'projectId': test_id},
+ {'authorizations':
+ [{'userId': 'test', 'authorizationLevel': 'VIEW'}]
+ }])
mocker.patch.object(DB, 'update', return_value={})
assert '403' in client.put(f'/v2/scenarios/{test_id}', json={
'scenario': {
@@ -86,19 +63,12 @@ def test_update_scenario_not_authorized(client, mocker):
def test_update_scenario(client, mocker):
mocker.patch.object(DB,
'fetch_one',
- return_value={
- '_id': test_id,
- 'projectId': test_id,
- 'portfolioId': test_id,
- 'authorizations': [{
- 'projectId': test_id,
- 'authorizationLevel': 'OWN'
- }],
- 'targets': {
- 'enabledMetrics': [],
- 'repeatsPerScenario': 1
- }
- })
+ side_effect=[
+ {'_id': test_id, 'portfolioId': test_id},
+ {'projectId': test_id},
+ {'authorizations':
+ [{'userId': 'test', 'authorizationLevel': 'OWN'}]
+ }])
mocker.patch.object(DB, 'update', return_value={})
res = client.put(f'/v2/scenarios/{test_id}', json={'scenario': {
@@ -115,16 +85,12 @@ def test_delete_project_non_existing(client, mocker):
def test_delete_project_different_user(client, mocker):
mocker.patch.object(DB,
'fetch_one',
- return_value={
- '_id': test_id,
- 'projectId': test_id,
- 'portfolioId': test_id,
- 'googleId': 'other_test',
- 'authorizations': [{
- 'projectId': test_id,
- 'authorizationLevel': 'VIEW'
- }]
- })
+ side_effect=[
+ {'_id': test_id, 'portfolioId': test_id},
+ {'projectId': test_id},
+ {'authorizations':
+ [{'userId': 'test', 'authorizationLevel': 'VIEW'}]
+ }])
mocker.patch.object(DB, 'delete_one', return_value=None)
assert '403' in client.delete(f'/v2/scenarios/{test_id}').status
@@ -139,7 +105,7 @@ def test_delete_project(client, mocker):
'googleId': 'test',
'scenarioIds': [test_id],
'authorizations': [{
- 'projectId': test_id,
+ 'userId': 'test',
'authorizationLevel': 'OWN'
}]
})
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/topologies/topologyId/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/topologies/topologyId/test_endpoint.py
index 4da0bc64..96d2e08e 100644
--- a/opendc-web/opendc-web-api/opendc/api/v2/topologies/topologyId/test_endpoint.py
+++ b/opendc-web/opendc-web-api/opendc/api/v2/topologies/topologyId/test_endpoint.py
@@ -11,7 +11,7 @@ def test_get_topology(client, mocker):
'_id': test_id,
'projectId': test_id,
'authorizations': [{
- 'projectId': test_id,
+ 'userId': 'test',
'authorizationLevel': 'EDIT'
}]
})
@@ -30,10 +30,7 @@ def test_get_topology_not_authorized(client, mocker):
return_value={
'_id': test_id,
'projectId': test_id,
- 'authorizations': [{
- 'projectId': test_id_2,
- 'authorizationLevel': 'OWN'
- }]
+ 'authorizations': []
})
res = client.get(f'/v2/topologies/{test_id}')
assert '403' in res.status
@@ -60,10 +57,7 @@ def test_update_topology_not_authorized(client, mocker):
return_value={
'_id': test_id,
'projectId': test_id,
- 'authorizations': [{
- 'projectId': test_id,
- 'authorizationLevel': 'VIEW'
- }]
+ 'authorizations': []
})
mocker.patch.object(DB, 'update', return_value={})
assert '403' in client.put(f'/v2/topologies/{test_id}', json={
@@ -81,7 +75,7 @@ def test_update_topology(client, mocker):
'_id': test_id,
'projectId': test_id,
'authorizations': [{
- 'projectId': test_id,
+ 'userId': 'test',
'authorizationLevel': 'OWN'
}]
})
@@ -104,7 +98,7 @@ def test_delete_topology(client, mocker):
'googleId': 'test',
'topologyIds': [test_id],
'authorizations': [{
- 'projectId': test_id,
+ 'userId': 'test',
'authorizationLevel': 'OWN'
}]
})
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/users/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/users/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/opendc-web/opendc-web-api/opendc/api/v2/users/__init__.py
+++ /dev/null
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/users/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/users/endpoint.py
deleted file mode 100644
index fe61ce25..00000000
--- a/opendc-web/opendc-web-api/opendc/api/v2/users/endpoint.py
+++ /dev/null
@@ -1,30 +0,0 @@
-from opendc.models.user import User
-from opendc.util.rest import Response
-
-
-def GET(request):
- """Search for a User using their email address."""
-
- request.check_required_parameters(query={'email': 'string'})
-
- user = User.from_email(request.params_query['email'])
-
- user.check_exists()
-
- return Response(200, 'Successfully retrieved user.', user.obj)
-
-
-def POST(request):
- """Add a new User."""
-
- request.check_required_parameters(body={'user': {'email': 'string'}})
-
- user = User(request.params_body['user'])
- user.set_property('googleId', request.current_user['sub'])
- user.set_property('authorizations', [])
-
- user.check_already_exists()
-
- user.insert()
-
- return Response(200, 'Successfully created user.', user.obj)
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/users/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/users/test_endpoint.py
deleted file mode 100644
index 13b63b20..00000000
--- a/opendc-web/opendc-web-api/opendc/api/v2/users/test_endpoint.py
+++ /dev/null
@@ -1,34 +0,0 @@
-from opendc.util.database import DB
-
-
-def test_get_user_by_email_missing_parameter(client):
- assert '400' in client.get('/v2/users').status
-
-
-def test_get_user_by_email_non_existing(client, mocker):
- mocker.patch.object(DB, 'fetch_one', return_value=None)
- assert '404' in client.get('/v2/users?email=test@test.com').status
-
-
-def test_get_user_by_email(client, mocker):
- mocker.patch.object(DB, 'fetch_one', return_value={'email': 'test@test.com'})
- res = client.get('/v2/users?email=test@test.com')
- assert 'email' in res.json['content']
- assert '200' in res.status
-
-
-def test_add_user_missing_parameter(client):
- assert '400' in client.post('/v2/users').status
-
-
-def test_add_user_existing(client, mocker):
- mocker.patch.object(DB, 'fetch_one', return_value={'email': 'test@test.com'})
- assert '409' in client.post('/v2/users', json={'user': {'email': 'test@test.com'}}).status
-
-
-def test_add_user(client, mocker):
- mocker.patch.object(DB, 'fetch_one', return_value=None)
- mocker.patch.object(DB, 'insert', return_value={'email': 'test@test.com'})
- res = client.post('/v2/users', json={'user': {'email': 'test@test.com'}})
- assert 'email' in res.json['content']
- assert '200' in res.status
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/users/userId/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/users/userId/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/opendc-web/opendc-web-api/opendc/api/v2/users/userId/__init__.py
+++ /dev/null
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/users/userId/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/users/userId/endpoint.py
deleted file mode 100644
index 26ff7717..00000000
--- a/opendc-web/opendc-web-api/opendc/api/v2/users/userId/endpoint.py
+++ /dev/null
@@ -1,59 +0,0 @@
-from opendc.models.project import Project
-from opendc.models.user import User
-from opendc.util.rest import Response
-
-
-def GET(request):
- """Get this User."""
-
- request.check_required_parameters(path={'userId': 'string'})
-
- user = User.from_id(request.params_path['userId'])
-
- user.check_exists()
-
- return Response(200, 'Successfully retrieved user.', user.obj)
-
-
-def PUT(request):
- """Update this User's given name and/or family name."""
-
- request.check_required_parameters(body={'user': {
- 'givenName': 'string',
- 'familyName': 'string'
- }},
- path={'userId': 'string'})
-
- user = User.from_id(request.params_path['userId'])
-
- user.check_exists()
- user.check_correct_user(request.current_user['sub'])
-
- user.set_property('givenName', request.params_body['user']['givenName'])
- user.set_property('familyName', request.params_body['user']['familyName'])
-
- user.update()
-
- return Response(200, 'Successfully updated user.', user.obj)
-
-
-def DELETE(request):
- """Delete this User."""
-
- request.check_required_parameters(path={'userId': 'string'})
-
- user = User.from_id(request.params_path['userId'])
-
- user.check_exists()
- user.check_correct_user(request.current_user['sub'])
-
- for authorization in user.obj['authorizations']:
- if authorization['authorizationLevel'] != 'OWN':
- continue
-
- project = Project.from_id(authorization['projectId'])
- project.delete()
-
- old_object = user.delete()
-
- return Response(200, 'Successfully deleted user.', old_object)
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/users/userId/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/users/userId/test_endpoint.py
deleted file mode 100644
index 4085642f..00000000
--- a/opendc-web/opendc-web-api/opendc/api/v2/users/userId/test_endpoint.py
+++ /dev/null
@@ -1,56 +0,0 @@
-from opendc.util.database import DB
-
-test_id = 24 * '1'
-
-
-def test_get_user_non_existing(client, mocker):
- mocker.patch.object(DB, 'fetch_one', return_value=None)
- assert '404' in client.get(f'/v2/users/{test_id}').status
-
-
-def test_get_user(client, mocker):
- mocker.patch.object(DB, 'fetch_one', return_value={'email': 'test@test.com'})
- res = client.get(f'/v2/users/{test_id}')
- assert 'email' in res.json['content']
- assert '200' in res.status
-
-
-def test_update_user_missing_parameter(client):
- assert '400' in client.put(f'/v2/users/{test_id}').status
-
-
-def test_update_user_non_existing(client, mocker):
- mocker.patch.object(DB, 'fetch_one', return_value=None)
- assert '404' in client.put(f'/v2/users/{test_id}', json={'user': {'givenName': 'A', 'familyName': 'B'}}).status
-
-
-def test_update_user_different_user(client, mocker):
- mocker.patch.object(DB, 'fetch_one', return_value={'_id': test_id, 'googleId': 'other_test'})
- assert '403' in client.put(f'/v2/users/{test_id}', json={'user': {'givenName': 'A', 'familyName': 'B'}}).status
-
-
-def test_update_user(client, mocker):
- mocker.patch.object(DB, 'fetch_one', return_value={'_id': test_id, 'googleId': 'test'})
- mocker.patch.object(DB, 'update', return_value={'givenName': 'A', 'familyName': 'B'})
- res = client.put(f'/v2/users/{test_id}', json={'user': {'givenName': 'A', 'familyName': 'B'}})
- assert 'givenName' in res.json['content']
- assert '200' in res.status
-
-
-def test_delete_user_non_existing(client, mocker):
- mocker.patch.object(DB, 'fetch_one', return_value=None)
- assert '404' in client.delete(f'/v2/users/{test_id}').status
-
-
-def test_delete_user_different_user(client, mocker):
- mocker.patch.object(DB, 'fetch_one', return_value={'_id': test_id, 'googleId': 'other_test'})
- assert '403' in client.delete(f'/v2/users/{test_id}').status
-
-
-def test_delete_user(client, mocker):
- mocker.patch.object(DB, 'fetch_one', return_value={'_id': test_id, 'googleId': 'test', 'authorizations': []})
- mocker.patch.object(DB, 'delete_one', return_value={'googleId': 'test'})
- res = client.delete(f'/v2/users/{test_id}', )
-
- assert 'googleId' in res.json['content']
- assert '200' in res.status
diff --git a/opendc-web/opendc-web-api/opendc/models/portfolio.py b/opendc-web/opendc-web-api/opendc/models/portfolio.py
index 32961b63..8e3f2a52 100644
--- a/opendc-web/opendc-web-api/opendc/models/portfolio.py
+++ b/opendc-web/opendc-web-api/opendc/models/portfolio.py
@@ -1,7 +1,5 @@
+from opendc.models.project import Project
from opendc.models.model import Model
-from opendc.models.user import User
-from opendc.util.exceptions import ClientError
-from opendc.util.rest import Response
class Portfolio(Model):
@@ -9,16 +7,13 @@ class Portfolio(Model):
collection_name = 'portfolios'
- def check_user_access(self, google_id, edit_access):
- """Raises an error if the user with given [google_id] has insufficient access.
+ def check_user_access(self, user_id, edit_access):
+ """Raises an error if the user with given [user_id] has insufficient access.
Checks access on the parent project.
- :param google_id: The Google ID of the user.
+ :param user_id: The User ID of the user.
:param edit_access: True when edit access should be checked, otherwise view access.
"""
- user = User.from_google_id(google_id)
- authorizations = list(
- filter(lambda x: str(x['projectId']) == str(self.obj['projectId']), user.obj['authorizations']))
- if len(authorizations) == 0 or (edit_access and authorizations[0]['authorizationLevel'] == 'VIEW'):
- raise ClientError(Response(403, 'Forbidden from retrieving/editing portfolio.'))
+ project = Project.from_id(self.obj['projectId'])
+ project.check_user_access(user_id, edit_access)
diff --git a/opendc-web/opendc-web-api/opendc/models/prefab.py b/opendc-web/opendc-web-api/opendc/models/prefab.py
index edf1d4c4..05356358 100644
--- a/opendc-web/opendc-web-api/opendc/models/prefab.py
+++ b/opendc-web/opendc-web-api/opendc/models/prefab.py
@@ -1,5 +1,4 @@
from opendc.models.model import Model
-from opendc.models.user import User
from opendc.util.exceptions import ClientError
from opendc.util.rest import Response
@@ -9,20 +8,10 @@ class Prefab(Model):
collection_name = 'prefabs'
- def check_user_access(self, google_id):
- """Raises an error if the user with given [google_id] has insufficient access to view this prefab.
+ def check_user_access(self, user_id):
+ """Raises an error if the user with given [user_id] has insufficient access to view this prefab.
- :param google_id: The Google ID of the user.
+ :param user_id: The Google ID of the user.
"""
- user = User.from_google_id(google_id)
-
- # TODO(Jacob) add special handling for OpenDC-provided prefabs
-
- #try:
-
- print(self.obj)
- if self.obj['authorId'] != user.get_id() and self.obj['visibility'] == "private":
+ if self.obj['authorId'] != user_id and self.obj['visibility'] == "private":
raise ClientError(Response(403, "Forbidden from retrieving prefab."))
- #except KeyError:
- # OpenDC-authored objects don't necessarily have an authorId
- # return
diff --git a/opendc-web/opendc-web-api/opendc/models/project.py b/opendc-web/opendc-web-api/opendc/models/project.py
index b57e9f77..2b3fd5f4 100644
--- a/opendc-web/opendc-web-api/opendc/models/project.py
+++ b/opendc-web/opendc-web-api/opendc/models/project.py
@@ -1,5 +1,4 @@
from opendc.models.model import Model
-from opendc.models.user import User
from opendc.util.database import DB
from opendc.util.exceptions import ClientError
from opendc.util.rest import Response
@@ -10,22 +9,20 @@ class Project(Model):
collection_name = 'projects'
- def check_user_access(self, google_id, edit_access):
- """Raises an error if the user with given [google_id] has insufficient access.
+ def check_user_access(self, user_id, edit_access):
+ """Raises an error if the user with given [user_id] has insufficient access.
- :param google_id: The Google ID of the user.
+ :param user_id: The User ID of the user.
:param edit_access: True when edit access should be checked, otherwise view access.
"""
- user = User.from_google_id(google_id)
- authorizations = list(filter(lambda x: str(x['projectId']) == str(self.get_id()),
- user.obj['authorizations']))
- if len(authorizations) == 0 or (edit_access and authorizations[0]['authorizationLevel'] == 'VIEW'):
- raise ClientError(Response(403, "Forbidden from retrieving project."))
+ for authorization in self.obj['authorizations']:
+ if user_id == authorization['userId'] and authorization['authorizationLevel'] != 'VIEW' or not edit_access:
+ return
+ raise ClientError(Response(403, "Forbidden from retrieving project."))
- def get_all_authorizations(self):
- """Get all user IDs having access to this project."""
- return [
- str(user['_id']) for user in DB.fetch_all({'authorizations': {
- 'projectId': self.obj['_id']
- }}, User.collection_name)
- ]
+ @classmethod
+ def get_for_user(cls, user_id):
+ """Get all projects for the specified user id."""
+ return DB.fetch_all({'authorizations': {
+ 'userId': user_id
+ }}, Project.collection_name)
diff --git a/opendc-web/opendc-web-api/opendc/models/scenario.py b/opendc-web/opendc-web-api/opendc/models/scenario.py
index 8d53e408..3dfde012 100644
--- a/opendc-web/opendc-web-api/opendc/models/scenario.py
+++ b/opendc-web/opendc-web-api/opendc/models/scenario.py
@@ -1,8 +1,5 @@
from opendc.models.model import Model
from opendc.models.portfolio import Portfolio
-from opendc.models.user import User
-from opendc.util.exceptions import ClientError
-from opendc.util.rest import Response
class Scenario(Model):
@@ -10,17 +7,14 @@ class Scenario(Model):
collection_name = 'scenarios'
- def check_user_access(self, google_id, edit_access):
- """Raises an error if the user with given [google_id] has insufficient access.
+ def check_user_access(self, user_id, edit_access):
+ """Raises an error if the user with given [user_id] has insufficient access.
Checks access on the parent project.
- :param google_id: The Google ID of the user.
+ :param user_id: The User ID of the user.
:param edit_access: True when edit access should be checked, otherwise view access.
"""
portfolio = Portfolio.from_id(self.obj['portfolioId'])
- user = User.from_google_id(google_id)
- authorizations = list(
- filter(lambda x: str(x['projectId']) == str(portfolio.obj['projectId']), user.obj['authorizations']))
- if len(authorizations) == 0 or (edit_access and authorizations[0]['authorizationLevel'] == 'VIEW'):
- raise ClientError(Response(403, 'Forbidden from retrieving/editing scenario.'))
+ print(portfolio.obj)
+ portfolio.check_user_access(user_id, edit_access)
diff --git a/opendc-web/opendc-web-api/opendc/models/topology.py b/opendc-web/opendc-web-api/opendc/models/topology.py
index cb4c4bab..3ebec16d 100644
--- a/opendc-web/opendc-web-api/opendc/models/topology.py
+++ b/opendc-web/opendc-web-api/opendc/models/topology.py
@@ -1,7 +1,5 @@
+from opendc.models.project import Project
from opendc.models.model import Model
-from opendc.models.user import User
-from opendc.util.exceptions import ClientError
-from opendc.util.rest import Response
class Topology(Model):
@@ -9,19 +7,13 @@ class Topology(Model):
collection_name = 'topologies'
- def check_user_access(self, google_id, edit_access):
- """Raises an error if the user with given [google_id] has insufficient access.
+ def check_user_access(self, user_id, edit_access):
+ """Raises an error if the user with given [user_id] has insufficient access.
Checks access on the parent project.
- :param google_id: The Google ID of the user.
+ :param user_id: The User ID of the user.
:param edit_access: True when edit access should be checked, otherwise view access.
"""
- user = User.from_google_id(google_id)
- if 'projectId' not in self.obj:
- raise ClientError(Response(400, 'Missing projectId in topology.'))
-
- authorizations = list(
- filter(lambda x: str(x['projectId']) == str(self.obj['projectId']), user.obj['authorizations']))
- if len(authorizations) == 0 or (edit_access and authorizations[0]['authorizationLevel'] == 'VIEW'):
- raise ClientError(Response(403, 'Forbidden from retrieving topology.'))
+ project = Project.from_id(self.obj['projectId'])
+ project.check_user_access(user_id, edit_access)
diff --git a/opendc-web/opendc-web-api/opendc/models/user.py b/opendc-web/opendc-web-api/opendc/models/user.py
deleted file mode 100644
index 8e8ff945..00000000
--- a/opendc-web/opendc-web-api/opendc/models/user.py
+++ /dev/null
@@ -1,36 +0,0 @@
-from opendc.models.model import Model
-from opendc.util.database import DB
-from opendc.util.exceptions import ClientError
-from opendc.util.rest import Response
-
-
-class User(Model):
- """Model representing a User."""
-
- collection_name = 'users'
-
- @classmethod
- def from_email(cls, email):
- """Fetches the user with given email from the collection."""
- return User(DB.fetch_one({'email': email}, User.collection_name))
-
- @classmethod
- def from_google_id(cls, google_id):
- """Fetches the user with given Google ID from the collection."""
- return User(DB.fetch_one({'googleId': google_id}, User.collection_name))
-
- def check_correct_user(self, request_google_id):
- """Raises an error if a user tries to modify another user.
-
- :param request_google_id:
- """
- if request_google_id is not None and self.obj['googleId'] != request_google_id:
- raise ClientError(Response(403, f'Forbidden from editing user with ID {self.obj["_id"]}.'))
-
- def check_already_exists(self):
- """Checks if the user already exists in the database."""
-
- existing_user = DB.fetch_one({'googleId': self.obj['googleId']}, self.collection_name)
-
- if existing_user is not None:
- raise ClientError(Response(409, 'User already exists.'))