Skip to content

Commit 13a0612

Browse files
Merge pull request #61 from CentreForDigitalHumanities/feature/user-models
Feature/user models
2 parents cf0fa5b + 3f69dfb commit 13a0612

26 files changed

Lines changed: 1672 additions & 1058 deletions

README.md

Lines changed: 69 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,69 @@
1-
# LangPro Annotator
2-
3-
[![Actions Status](https://github.com/CentreForDigitalHumanities/langpro-annotator/workflows/Unit%20tests/badge.svg)](https://github.com/CentreForDigitalHumanities/langpro-annotator/actions)
4-
5-
An annotation tool for LangPro, a tableau-based theorem prover for natural logic and language.
6-
7-
*This repository is a work in progress, and the README is not yet complete!*
8-
9-
## Introduction
10-
11-
*In this section, provide an overview of your code and describe the project in which the code was developed. Highlight the purpose, scope, and potential uses of your code. Also, consider including links to relevant publications or resources that provide additional context.*
12-
13-
## Getting started
14-
15-
LangPro Annotator is a web application: it can be accessed using a web browser.
16-
17-
*If you are hosting LangPro Annotator anywhere, provide a URL and any additional info.*
18-
19-
You can also run LangPro Annotator locally or host it yourself. Be aware that this is a more advanced option. See [CONTRIBUTING.md](./CONTRIBUTING.md) for information about setting up a local server or configuring deployment.
20-
21-
## Usage
22-
23-
*Provide information about what LangPro Annotator can be used for. If you have written a user manual, this is the place to link it!*
24-
25-
## Development
26-
27-
To get started with developing LangPro Annotator, see [CONTRIBUTING.md](./CONTRIBUTING.md).
28-
29-
## Licence
30-
31-
This work is shared under a BSD 3-Clause licence. See [LICENSE](./LICENSE) for more information.
32-
33-
## Citation
34-
35-
To cite this repository, please use the metadata provided in [CITATION.cff](./CITATION.cff).
36-
37-
## Contact
38-
39-
LangPro Annotator is developed by [Research Software Lab, Centre for Digital Humanities, Utrecht University](https://cdh.uu.nl/about/research-software-lab/).
40-
41-
*Include contact information. You can also provide clear instructions for how users can provide feedback, contribute, or suggest improvements to your work.*
1+
# LangPro Annotator
2+
3+
[![Actions Status](https://github.com/CentreForDigitalHumanities/langpro-annotator/workflows/Unit%20tests/badge.svg)](https://github.com/CentreForDigitalHumanities/langpro-annotator/actions)
4+
5+
An annotation tool for LangPro, a tableau-based theorem prover for natural logic and language.
6+
7+
*This repository is a work in progress, and the README is not yet complete!*
8+
9+
## Introduction
10+
11+
*In this section, provide an overview of your code and describe the project in which the code was developed. Highlight the purpose, scope, and potential uses of your code. Also, consider including links to relevant publications or resources that provide additional context.*
12+
13+
## Getting started
14+
15+
LangPro Annotator is a web application: it can be accessed using a web browser.
16+
17+
*If you are hosting LangPro Annotator anywhere, provide a URL and any additional info.*
18+
19+
You can also run LangPro Annotator locally or host it yourself. Be aware that this is a more advanced option. See [CONTRIBUTING.md](./CONTRIBUTING.md) for information about setting up a local server or configuring deployment.
20+
21+
## Usage
22+
23+
*Provide information about what LangPro Annotator can be used for. If you have written a user manual, this is the place to link it!*
24+
25+
## Development
26+
27+
To get started with developing LangPro Annotator, see [CONTRIBUTING.md](./CONTRIBUTING.md).
28+
29+
## Permission overview
30+
31+
Apart from superusers/admins, the application has three user roles with different permissions. Users with the "Master Annotator" role have full permissions, including managing users and problem visibility/status. Users with the "Annotator" role can browse and annotate both gold and silver problems. Users without any assigned role are considered "Visitors" and can only browse gold problems.
32+
33+
Users can become Annotators or Master Annotators by adding them to the respective user groups in the Django admin interface.
34+
35+
The matrix below shows the permissions for each role. Not all permissions are currently implemented.
36+
37+
(Last updated: November 14th, 2025)
38+
39+
| | Visitor | Annotator | Master Annotator |
40+
| -------------------------- | ------- | --------- | ---------------- |
41+
| Browse gold problems | Yes | Yes | Yes |
42+
| Browse silver problems | No | Yes | Yes |
43+
| Edit KB items | No | Yes | Yes |
44+
| Add labels | No | Yes | Yes |
45+
| Remove own labels | No | Yes | Yes |
46+
| Remove other users' labels | No | No | Yes |
47+
| Add problems | No | No | Yes |
48+
| Copy problems | No | No | Yes |
49+
| Update user problems | No | No | Yes |
50+
| Delete problems | No | No | Yes |
51+
| Edit existing problems | No | No | Yes |
52+
| See hidden problems | No | No | Yes |
53+
| Silver/gold problems | No | No | Yes |
54+
| Hide/unhide problems | No | No | Yes |
55+
| Manage users | No | No | Yes |
56+
57+
## Licence
58+
59+
This work is shared under a BSD 3-Clause licence. See [LICENSE](./LICENSE) for more information.
60+
61+
## Citation
62+
63+
To cite this repository, please use the metadata provided in [CITATION.cff](./CITATION.cff).
64+
65+
## Contact
66+
67+
LangPro Annotator is developed by [Research Software Lab, Centre for Digital Humanities, Utrecht University](https://cdh.uu.nl/about/research-software-lab/).
68+
69+
*Include contact information. You can also provide clear instructions for how users can provide feedback, contribute, or suggest improvements to your work.*
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Generated by Django 4.2.27 on 2025-12-08 13:23
2+
3+
from django.db import migrations
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
("problem", "0005_problem_base"),
10+
]
11+
12+
operations = [
13+
migrations.AlterModelOptions(
14+
name="problem",
15+
options={
16+
"permissions": [
17+
("view_gold_problems", "Can view problems marked as gold"),
18+
("view_silver_problems", "Can view problems marked as silver"),
19+
("view_hidden_problems", "Can view hidden problems that are marked as hidden"),
20+
("copy_problems", "Can copy problems"),
21+
("change_problem_status", "Can change status of a problem (gold/silver)"),
22+
("change_problem_visibility", "Can change problem visibility (hidden/visible)"),
23+
]
24+
},
25+
),
26+
]

backend/problem/models.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,16 @@ class EntailmentLabel(models.TextChoices):
5656

5757
extra_data = models.JSONField()
5858

59+
class Meta:
60+
permissions = [
61+
("view_gold_problems", "Can view gold problems"),
62+
("view_silver_problems", "Can view silver problems"),
63+
("view_hidden_problems", "Can view hidden problems"),
64+
("copy_problems", "Can copy problems"),
65+
("change_problem_status", "Can change problem status"),
66+
("change_problem_visibility", "Can change problem visibility"),
67+
]
68+
5969
def get_index(self, qs: QuerySet) -> int | None:
6070
"""
6171
Get the index of this Problem in a given queryset of problems, ordered by pk.
@@ -65,6 +75,8 @@ def get_index(self, qs: QuerySet) -> int | None:
6575
except Exception as e:
6676
logger.exception(f"Error getting index for problem {self.pk}: {e}")
6777
return None
78+
79+
6880
class KnowledgeBase(models.Model):
6981
class Relationship(models.TextChoices):
7082
EQUAL = "equal", "Equal"

backend/problem/views/problem.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,30 @@
1212
)
1313
from problem.models import Problem
1414
from problem.serializers import ProblemInputSerializer, ProblemSerializer
15+
from rest_framework.permissions import IsAuthenticated, IsAuthenticatedOrReadOnly
16+
17+
18+
class CreateProblemPermission(IsAuthenticated):
19+
def has_permission(self, request, view):
20+
return super().has_permission(request, view) and request.user.can_create_problem
21+
22+
23+
class EditProblemPermission(IsAuthenticated):
24+
def has_permission(self, request, view):
25+
return super().has_permission(request, view) and request.user.can_edit_problem
1526

1627

1728
class ProblemView(ModelViewSet):
1829
queryset = Problem.objects.all()
1930
serializer_class = ProblemSerializer
2031

32+
def get_permissions(self):
33+
if self.action == "create":
34+
return [CreateProblemPermission()]
35+
if self.action == "partial_update":
36+
return [EditProblemPermission()]
37+
return [IsAuthenticatedOrReadOnly()]
38+
2139
def list(self, request: Request) -> Response:
2240
"""
2341
Lists all Problems in the database, with optional filtering.
@@ -111,7 +129,7 @@ def _handle_update_create_problem(
111129
problem_serializer = ProblemSerializer()
112130

113131
if problem_id is None:
114-
problem = problem_serializer.create(validated_input) # type: ignore
132+
problem = problem_serializer.create(validated_input) # type: ignore
115133
status = HTTP_201_CREATED
116134
else:
117135
problem_instance = get_object_or_404(
@@ -123,4 +141,3 @@ def _handle_update_create_problem(
123141
status = HTTP_200_OK
124142

125143
return Response({"id": problem.pk}, status=status)
126-

0 commit comments

Comments
 (0)