Skip to content

Commit

Permalink
Add ability to make states public
Browse files Browse the repository at this point in the history
  • Loading branch information
JackWilb committed Aug 12, 2021
1 parent 716cbdc commit 50fa9d6
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 13 deletions.
8 changes: 5 additions & 3 deletions backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ There are several routes set up for accessing the patient and surgery data. Here
- Allowed Methods: `GET, POST, PUT, DELETE`
- Parameters:
`name`: The name of the state object.
`definition`: The state definition, usually the string from our provenance library.
`definition`: The state definition, usually the string from our provenance library.
`public`: true/false indicating whether the state should be public
- Description: Handles state saving into a database on the backend. A GET will retrieve the state object by name. A POST creates a state object. A PUT updates a state object. Finally, a DELETE will delete a state object. The required parameters for each type of request are documented in the examples.
- Example:
```
Expand All @@ -176,12 +177,13 @@ There are several routes set up for accessing the patient and surgery data. Here
# POST
curl -X POST '127.0.0.1:8000/api/state' \
-F "name=example_state" \
-F "definition=foo"
-F "definition=foo" \
-F "public=true"
# PUT
curl -X PUT '127.0.0.1:8000/api/state' \
-H "Content-Type: application/json" \
-d '{"old_name": "example_state", "new_name": "a_new_state", "definition": "foo"}'
-d '{"old_name": "example_state", "new_name": "a_new_state", "new_definition": "foo", "new_public": "false"}'
# DELETE
curl -X DELETE '127.0.0.1:8000/api/state' \
Expand Down
23 changes: 23 additions & 0 deletions backend/api/api/migrations/0004_auto_20210716_1709.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 2.2.24 on 2021-07-16 17:09

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('api', '0003_auto_20200826_1855'),
]

operations = [
migrations.AddField(
model_name='state',
name='public',
field=models.BooleanField(default=False),
),
migrations.AlterField(
model_name='state',
name='owner',
field=models.CharField(default='u0999308', max_length=128),
),
]
1 change: 1 addition & 0 deletions backend/api/api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class State(models.Model):
name = models.CharField(max_length=128, unique=True, default="New State")
definition = models.TextField()
owner = models.CharField(max_length=128, default="NA")
public = models.BooleanField(default=False)


class StateAccess(models.Model):
Expand Down
28 changes: 18 additions & 10 deletions backend/api/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,7 @@ def state(request):
state_access = StateAccess.objects.filter(state=state).filter(user=user)

# Make sure that user is owner or at least reader
if not(str(state.owner) == str(user) or state_access):
if not(str(state.owner) == str(user) or state_access or public):
return HttpResponseBadRequest("Not authorized", 401)

# Return the json for the state
Expand All @@ -876,15 +876,19 @@ def state(request):
name = request.POST.get('name')
definition = request.POST.get('definition')
owner = request.user.id
public = request.POST.get("public")

logging.info(f"{request.META.get('HTTP_X_FORWARDED_FOR')} POST: state Params: name = {name} User: {request.user}")
if not public != "true":
public = False

logging.info(f"{request.META.get('HTTP_X_FORWARDED_FOR')} POST: state Params: name = {name}, public = {public} User: {request.user}")

if State.objects.filter(name=name).exists():
return HttpResponseBadRequest("a state with that name already exists, try another", 400)

if name and definition: # owner is guaranteed by login
# Create and save the new State object
new_state = State(name=name, definition=definition, owner=owner)
new_state = State(name=name, definition=definition, owner=owner, public=public)
new_state.save()

return HttpResponse("state object created", 200)
Expand All @@ -897,23 +901,27 @@ def state(request):
old_name = put.get('old_name')
new_name = put.get('new_name')
new_definition = put.get('new_definition')
new_public = put.get('new_public')

logging.info(f"{request.META.get('HTTP_X_FORWARDED_FOR')} PUT: state Params: old_name = {old_name}, new_name = {new_name} User: {request.user}")

states = [o.name for o in State.objects.all().filter(owner=request.user.id)]
state_access = [o.state.name for o in StateAccess.objects.filter(user=request.user.id).filter(role="WR")]
state_read_access = [o.state.name for o in StateAccess.objects.filter(user=request.user.id).filter(role="RE")]
allowed_states = response = set(states + state_access)
owned_states = [o.name for o in State.objects.all().filter(owner=request.user.id)]
public_states = [o.name for o in State.objects.all().filter(public=True)]
writable_states = [o.state.name for o in StateAccess.objects.filter(user=request.user.id).filter(role="WR")]
readable_states = [o.state.name for o in StateAccess.objects.filter(user=request.user.id).filter(role="RE")]
all_accessible_states = set(owned_states + public_states + writable_states + readable_states)
all_modifiable_states = set(owned_states + writable_states)

if old_name in state_read_access:
return HttpResponseBadRequest("Not authorized", 401)
elif old_name not in allowed_states:
if old_name not in all_accessible_states:
return HttpResponseBadRequest("State not found", 404)
if old_name not in all_modifiable_states:
return HttpResponseBadRequest("Not authorized", 401)

# Update the State object and save
result = State.objects.get(name=old_name)
result.name = new_name
result.definition = new_definition
result.public = new_public
result.save()

return HttpResponse("state object updated", 200)
Expand Down

0 comments on commit 50fa9d6

Please sign in to comment.