Compare commits
No commits in common. "3d93e489c4957e32d6af1ce66a495c5b6cd5d1e5" and "88bd79c2284e9830fb08ff4d64072adc2b0f61bd" have entirely different histories.
3d93e489c4
...
88bd79c228
@ -23,8 +23,6 @@ Currently, server settings are represented by the following object:
|
|||||||
"default_permissions": ["PERMISSION1", "PERMISSION2"]
|
"default_permissions": ["PERMISSION1", "PERMISSION2"]
|
||||||
}
|
}
|
||||||
|
|
||||||
.. _admin_anon_perms:
|
|
||||||
|
|
||||||
Anonymous permissions
|
Anonymous permissions
|
||||||
^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
@ -64,11 +64,6 @@ In JSON, a file share has the following properties::
|
|||||||
- Read-only
|
- Read-only
|
||||||
- UUID that uniquely identifies this share.
|
- UUID that uniquely identifies this share.
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
Share ownership can be changed by changing ``owner_name``.
|
|
||||||
Do note that setting it to ``null`` is equivalent to :ref:`unauthenticated users<admin_anon_perms>` owning the share.
|
|
||||||
|
|
||||||
.. _files_metadata_api:
|
.. _files_metadata_api:
|
||||||
|
|
||||||
Metadata API
|
Metadata API
|
||||||
|
@ -2,7 +2,7 @@ import uuid
|
|||||||
import io
|
import io
|
||||||
from flask import Blueprint, request, jsonify, send_file, make_response
|
from flask import Blueprint, request, jsonify, send_file, make_response
|
||||||
from flask.views import MethodView
|
from flask.views import MethodView
|
||||||
from sachet.server.models import Share, Permissions, Upload, Chunk, User
|
from sachet.server.models import Share, Permissions, Upload, Chunk
|
||||||
from sachet.server.views_common import ModelAPI, ModelListAPI, auth_required
|
from sachet.server.views_common import ModelAPI, ModelListAPI, auth_required
|
||||||
from sachet.server import storage, db
|
from sachet.server import storage, db
|
||||||
|
|
||||||
@ -18,28 +18,6 @@ class FilesMetadataAPI(ModelAPI):
|
|||||||
@auth_required(required_permissions=(Permissions.MODIFY,), allow_anonymous=True)
|
@auth_required(required_permissions=(Permissions.MODIFY,), allow_anonymous=True)
|
||||||
def patch(self, share_id, auth_user=None):
|
def patch(self, share_id, auth_user=None):
|
||||||
share = Share.query.filter_by(share_id=share_id).first()
|
share = Share.query.filter_by(share_id=share_id).first()
|
||||||
if auth_user != share.owner:
|
|
||||||
return (
|
|
||||||
jsonify(
|
|
||||||
{
|
|
||||||
"status": "fail",
|
|
||||||
"message": "Share must be modified by its owner.",
|
|
||||||
}
|
|
||||||
),
|
|
||||||
403,
|
|
||||||
)
|
|
||||||
owner_name = request.get_json().get("owner_name")
|
|
||||||
if owner_name is not None:
|
|
||||||
if User.query.filter_by(username=owner_name).first() is None:
|
|
||||||
return (
|
|
||||||
jsonify(
|
|
||||||
{
|
|
||||||
"status": "fail",
|
|
||||||
"message": f"Invalid value for `owner_name`: {owner_name}",
|
|
||||||
}
|
|
||||||
),
|
|
||||||
400,
|
|
||||||
)
|
|
||||||
if share.locked:
|
if share.locked:
|
||||||
return jsonify({"status": "fail", "message": "This share is locked."}), 423
|
return jsonify({"status": "fail", "message": "This share is locked."}), 423
|
||||||
return super().patch(share)
|
return super().patch(share)
|
||||||
@ -47,28 +25,6 @@ class FilesMetadataAPI(ModelAPI):
|
|||||||
@auth_required(required_permissions=(Permissions.MODIFY,), allow_anonymous=True)
|
@auth_required(required_permissions=(Permissions.MODIFY,), allow_anonymous=True)
|
||||||
def put(self, share_id, auth_user=None):
|
def put(self, share_id, auth_user=None):
|
||||||
share = Share.query.filter_by(share_id=share_id).first()
|
share = Share.query.filter_by(share_id=share_id).first()
|
||||||
if auth_user != share.owner:
|
|
||||||
return (
|
|
||||||
jsonify(
|
|
||||||
{
|
|
||||||
"status": "fail",
|
|
||||||
"message": "Share must be modified by its owner.",
|
|
||||||
}
|
|
||||||
),
|
|
||||||
403,
|
|
||||||
)
|
|
||||||
owner_name = request.get_json().get("owner_name")
|
|
||||||
if owner_name is not None:
|
|
||||||
if User.query.filter_by(username=owner_name).first() is None:
|
|
||||||
return (
|
|
||||||
jsonify(
|
|
||||||
{
|
|
||||||
"status": "fail",
|
|
||||||
"message": f"Invalid value for `owner_name`: {owner_name}",
|
|
||||||
}
|
|
||||||
),
|
|
||||||
400,
|
|
||||||
)
|
|
||||||
if share.locked:
|
if share.locked:
|
||||||
return jsonify({"status": "fail", "message": "This share is locked."}), 423
|
return jsonify({"status": "fail", "message": "This share is locked."}), 423
|
||||||
return super().put(share)
|
return super().put(share)
|
||||||
|
@ -105,42 +105,6 @@ class TestSuite:
|
|||||||
assert resp.data == new_data
|
assert resp.data == new_data
|
||||||
assert "filename=new_bin.bin" in resp.headers["Content-Disposition"].split("; ")
|
assert "filename=new_bin.bin" in resp.headers["Content-Disposition"].split("; ")
|
||||||
|
|
||||||
def test_transfer(self, client, users, auth):
|
|
||||||
# create share
|
|
||||||
resp = client.post(
|
|
||||||
"/files", headers=auth("jeff"), json={"file_name": "content.bin"}
|
|
||||||
)
|
|
||||||
data = resp.get_json()
|
|
||||||
url = data.get("url")
|
|
||||||
|
|
||||||
# transfer ownership over to dave
|
|
||||||
resp = client.patch(url, headers=auth("jeff"), json={"owner_name": "dave"})
|
|
||||||
assert resp.status_code == 200
|
|
||||||
|
|
||||||
# ensure the transfer worked
|
|
||||||
resp = client.patch(
|
|
||||||
url, headers=auth("jeff"), json={"file_name": "jeff's file"}
|
|
||||||
)
|
|
||||||
assert resp.status_code == 403
|
|
||||||
resp = client.patch(
|
|
||||||
url, headers=auth("dave"), json={"file_name": "dave's file"}
|
|
||||||
)
|
|
||||||
assert resp.status_code == 200
|
|
||||||
|
|
||||||
# transfer ownership back to jeff
|
|
||||||
resp = client.patch(url, headers=auth("dave"), json={"owner_name": "jeff"})
|
|
||||||
assert resp.status_code == 200
|
|
||||||
|
|
||||||
# ensure the transfer worked
|
|
||||||
resp = client.patch(
|
|
||||||
url, headers=auth("dave"), json={"file_name": "dave's epic file"}
|
|
||||||
)
|
|
||||||
assert resp.status_code == 403
|
|
||||||
resp = client.patch(
|
|
||||||
url, headers=auth("jeff"), json={"file_name": "jeff's file"}
|
|
||||||
)
|
|
||||||
assert resp.status_code == 200
|
|
||||||
|
|
||||||
def test_invalid(self, client, users, auth, rand, upload):
|
def test_invalid(self, client, users, auth, rand, upload):
|
||||||
"""Test invalid requests."""
|
"""Test invalid requests."""
|
||||||
|
|
||||||
@ -218,22 +182,6 @@ class TestSuite:
|
|||||||
method=client.put,
|
method=client.put,
|
||||||
)
|
)
|
||||||
assert resp.status_code == 403
|
assert resp.status_code == 403
|
||||||
resp = client.patch(
|
|
||||||
url, headers=auth("dave"), json=dict(file_name="epic_new_filename.bin")
|
|
||||||
)
|
|
||||||
assert resp.status_code == 403
|
|
||||||
resp = client.put(
|
|
||||||
url,
|
|
||||||
headers=auth("dave"),
|
|
||||||
json=dict(file_name="epic_new_filename.bin", owner_name="dave"),
|
|
||||||
)
|
|
||||||
assert resp.status_code == 403
|
|
||||||
|
|
||||||
# test assigning a file to a non-existent user
|
|
||||||
resp = client.patch(
|
|
||||||
url, headers=auth("jeff"), json=dict(owner_name="non_existent_user")
|
|
||||||
)
|
|
||||||
assert resp.status_code == 400
|
|
||||||
|
|
||||||
# test not allowing re-upload
|
# test not allowing re-upload
|
||||||
resp = upload(
|
resp = upload(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user