Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop #126

Merged
merged 4 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion server/mergin/sync/public_api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -977,7 +977,7 @@ components:
UnsupportedMediaType:
description: Payload format is in an unsupported format.
ConflictResp:
description: Request could not be processed becuase of conflict in resources
description: Request could not be processed because of conflict in resources
UnprocessableEntity:
description: Request was correct and yet server could not process it
ProjectsLimitHitResp:
Expand Down
65 changes: 61 additions & 4 deletions server/mergin/sync/public_api_v2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,73 @@ tags:
description: Mergin project
paths:
/projects/{id}:
parameters:
- $ref: "#/components/parameters/ProjectId"
delete:
tags:
- project
summary: Delete project immediately
operationId: delete_project_now
parameters:
- $ref: "#/components/parameters/ProjectId"
responses:
"204":
$ref: "#/components/responses/NoContent"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
x-openapi-router-controller: mergin.sync.public_api_v2_controller
patch:
tags:
- project
summary: Update project
operationId: update_project
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- name
properties:
name:
type: string
example: survey
responses:
"204":
$ref: "#/components/responses/NoContent"
"400":
description: Invalid project name
content:
application/json:
schema:
type: object
required:
- code
- detail
properties:
code:
type: string
enum:
- InvalidProjectName
example: InvalidProjectName
detail:
type: string
enum:
- "Entered project name is invalid"
example: "Entered project name is invalid"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
"409":
$ref: "#/components/responses/Conflict"
x-openapi-router-controller: mergin.sync.public_api_v2_controller
/projects/{id}/scheduleDelete:
post:
Expand All @@ -40,8 +91,10 @@ paths:
$ref: "#/components/responses/NoContent"
"400":
$ref: "#/components/responses/BadRequest"
"403":
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
x-openapi-router-controller: mergin.sync.public_api_v2_controller
Expand All @@ -50,11 +103,15 @@ components:
NoContent:
description: No content
BadRequest:
description: Invalid request.
description: Invalid request
Unauthorized:
description: Authentication information is missing or invalid
Forbidden:
description: Invalid token
NotFound:
description: Not found
Conflict:
description: Conflict
parameters:
ProjectId:
name: id
Expand Down
34 changes: 32 additions & 2 deletions server/mergin/sync/public_api_v2_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@

from datetime import datetime

from connexion import NoContent
from flask import abort
from connexion import NoContent, request
from flask import abort, jsonify
from flask_login import current_user

from mergin import db
from mergin.auth import auth_required
from mergin.sync.models import Project
from mergin.sync.permissions import ProjectPermissions, require_project_by_uuid
from mergin.sync.utils import is_name_allowed


@auth_required
Expand Down Expand Up @@ -43,3 +44,32 @@ def delete_project_now(id_):
db.session.commit()

return NoContent, 204


@auth_required
def update_project(id_):
"""Rename project

:param id_: Project_id
:type id_: str
"""
project = require_project_by_uuid(id_, ProjectPermissions.Update)
new_name = request.json["name"]

if not is_name_allowed(new_name):
return (
jsonify(
code="InvalidProjectName", detail="Entered project name is invalid"
),
400,
)
new_name_exists = Project.query.filter_by(
workspace_id=project.workspace_id, name=new_name
).first()
if new_name_exists:
abort(409, "Name already exist within workspace")

project.name = new_name.strip()
db.session.commit()

return NoContent, 204
24 changes: 23 additions & 1 deletion server/mergin/tests/test_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@
from ..auth.tasks import prune_removed_users
from .. import db
from ..sync.models import Project
from . import test_workspace_id, json_headers, DEFAULT_USER, test_workspace_name
from . import (
test_workspace_id,
json_headers,
DEFAULT_USER,
test_workspace_name,
test_project,
)
from .utils import add_user, login_as_admin, login


Expand Down Expand Up @@ -718,3 +724,19 @@ def test_admin_login(client, data, expected):
add_user("user", "user")
resp = client.post("/app/admin/login", data=json.dumps(data), headers=json_headers)
assert resp.status_code == expected


def test_update_project_v2(client):
project = Project.query.filter_by(
workspace_id=test_workspace_id, name=test_project
).first()
data = {"name": "new_project_name"}
resp = client.patch(f"v2/projects/{project.id}", json=data)
assert resp.status_code == 401
user = add_user("test", "test")
login(client, "test", "test")
resp = client.patch(f"v2/projects/{project.id}", json=data)
assert resp.status_code == 403
login_as_admin(client)
resp = client.patch(f"v2/projects/{project.id}", json=data)
assert resp.status_code == 204
22 changes: 22 additions & 0 deletions server/mergin/tests/test_public_api_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,25 @@ def test_delete_after_schedule(client):
assert response.status_code == 204
response = client.delete(f"v2/projects/{project.id}")
assert response.status_code == 204


def test_rename_project(client):
project = Project.query.filter_by(
workspace_id=test_workspace_id, name=test_project
).first()
data = {"name": "new_project_name"}
response = client.patch(f"v2/projects/{project.id}", json=data)
assert response.status_code == 204
assert project.name == "new_project_name"
# name already exists
response = client.patch(f"v2/projects/{project.id}", json=data)
assert response.status_code == 409
# invalid project name
response = client.patch(f"v2/projects/{project.id}", json={"name": ".new_name"})
assert response.status_code == 400
assert response.json["code"] == "InvalidProjectName"
response = client.patch(
f"v2/projects/{project.id}", json={"name": " new_project_name"}
)
assert response.status_code == 400
assert response.json["code"] == "InvalidProjectName"
Loading