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

Interview visibility #1121

Draft
wants to merge 5 commits into
base: interview
Choose a base branch
from
Draft
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
3 changes: 3 additions & 0 deletions rdmo/core/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@
'MULTISITE',
'GROUPS',
'EXPORT_FORMATS',
'PROJECT_VISIBILITY',
'PROJECT_ISSUES',
'PROJECT_VIEWS',
'PROJECT_EXPORTS',
Expand Down Expand Up @@ -292,6 +293,8 @@

PROJECT_TABLE_PAGE_SIZE = 20

PROJECT_VISIBILITY = True

PROJECT_ISSUES = True

PROJECT_ISSUE_PROVIDERS = []
Expand Down
7 changes: 7 additions & 0 deletions rdmo/projects/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,10 @@
(ROLE_AUTHOR, _('Author')),
(ROLE_GUEST, _('Guest')),
)

VISIBILITY_PRIVATE = 'private'
MyPyDavid marked this conversation as resolved.
Show resolved Hide resolved
VISIBILITY_INTERNAL = 'internal'
VISIBILITY_CHOICES = (
(VISIBILITY_PRIVATE, _('Private')),
(VISIBILITY_INTERNAL, _('Internal'))
)
11 changes: 11 additions & 0 deletions rdmo/projects/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ class Meta:
fields = ['title', 'description', 'catalog']
if settings.NESTED_PROJECTS:
fields += ['parent']
if settings.PROJECT_VISIBILITY:
fields += ['visibility']

field_classes = {
'catalog': CatalogChoiceField
Expand All @@ -90,6 +92,15 @@ class Meta:
fields = ('title', 'description')


class ProjectUpdateVisibilityForm(forms.ModelForm):

use_required_attribute = False

class Meta:
model = Project
fields = ('visibility', )


class ProjectUpdateCatalogForm(forms.ModelForm):

use_required_attribute = False
Expand Down
4 changes: 3 additions & 1 deletion rdmo/projects/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from rdmo.accounts.utils import is_site_manager
from rdmo.core.managers import CurrentSiteManagerMixin

from .constants import VISIBILITY_INTERNAL


class ProjectQuerySet(TreeQuerySet):

Expand All @@ -21,7 +23,7 @@ def filter_user(self, user):
elif is_site_manager(user):
return self.filter_current_site()
else:
queryset = self.filter(user=user)
queryset = self.filter(Q(user=user) | models.Q(visibility=VISIBILITY_INTERNAL))
for instance in queryset:
queryset |= instance.get_descendants()
return queryset.distinct()
Expand Down
18 changes: 18 additions & 0 deletions rdmo/projects/migrations/0062_project_visibility.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 4.2.8 on 2024-08-15 15:39

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('projects', '0061_alter_value_value_type'),
]

operations = [
migrations.AddField(
model_name='project',
name='visibility',
field=models.CharField(choices=[('private', 'Private'), ('internal', 'Internal')], default='private', help_text='The visibility for this project.', max_length=8, verbose_name='visibility'),
),
]
21 changes: 21 additions & 0 deletions rdmo/projects/models/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from rdmo.tasks.models import Task
from rdmo.views.models import View

from ..constants import VISIBILITY_CHOICES, VISIBILITY_INTERNAL, VISIBILITY_PRIVATE
from ..managers import ProjectManager


Expand Down Expand Up @@ -73,6 +74,11 @@ class Project(MPTTModel, Model):
verbose_name=_('Progress count'),
help_text=_('The number of values for the progress bar.')
)
visibility = models.CharField(
max_length=8, choices=VISIBILITY_CHOICES, default=VISIBILITY_PRIVATE,
verbose_name=_('visibility'),
help_text=_('The visibility for this project.')
)

class Meta:
ordering = ('tree_id', 'level', 'title')
Expand Down Expand Up @@ -128,6 +134,21 @@ def file_size(self):
queryset = self.values.filter(snapshot=None).exclude(models.Q(file='') | models.Q(file=None))
return sum([value.file.size for value in queryset])

@property
def is_private(self):
return self.visibility == VISIBILITY_PRIVATE

@property
def is_internal(self):
return self.visibility == VISIBILITY_INTERNAL

@property
def get_visibility_help(self):
if self.is_private:
return _('Project access must be granted explicitly to each user.')
elif self.is_internal:
return _('The project can be accessed by any logged in user.')

def get_members(self, role):
try:
# membership_list is created by the Prefetch call in the viewset
Expand Down
19 changes: 12 additions & 7 deletions rdmo/projects/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ def is_project_guest(user, project):
return user in project.guests or (project.parent and is_project_guest(user, project.parent))


@rules.predicate
def is_internal_project(user, project):
return user.is_authenticated and project.is_internal


@rules.predicate
def is_site_manager(user, project):
if user.is_authenticated:
Expand All @@ -67,15 +72,15 @@ def is_site_manager_for_current_site(user, request):
rules.add_rule('projects.can_view_all_projects', is_site_manager_for_current_site | is_superuser)

rules.add_perm('projects.add_project', can_add_project)
rules.add_perm('projects.view_project_object', is_project_member | is_site_manager)
rules.add_perm('projects.view_project_object', is_project_member | is_internal_project | is_site_manager)
rules.add_perm('projects.change_project_object', is_project_manager | is_project_owner | is_site_manager)
rules.add_perm('projects.change_project_progress_object', is_project_author | is_project_manager | is_project_owner | is_site_manager) # noqa: E501
rules.add_perm('projects.delete_project_object', is_project_owner | is_site_manager)
rules.add_perm('projects.leave_project_object', is_current_project_member)
rules.add_perm('projects.export_project_object', is_project_owner | is_project_manager | is_site_manager)
rules.add_perm('projects.import_project_object', is_project_owner | is_project_manager | is_site_manager)

rules.add_perm('projects.view_membership_object', is_project_member | is_site_manager)
rules.add_perm('projects.view_membership_object', is_project_member | is_internal_project | is_site_manager)
rules.add_perm('projects.add_membership_object', is_project_owner | is_site_manager)
rules.add_perm('projects.change_membership_object', is_project_owner | is_site_manager)
rules.add_perm('projects.delete_membership_object', is_project_owner | is_site_manager)
Expand All @@ -85,27 +90,27 @@ def is_site_manager_for_current_site(user, request):
rules.add_perm('projects.change_invite_object', is_project_owner | is_site_manager)
rules.add_perm('projects.delete_invite_object', is_project_owner | is_site_manager)

rules.add_perm('projects.view_integration_object', is_project_member | is_site_manager)
rules.add_perm('projects.view_integration_object', is_project_member | is_internal_project | is_site_manager)
rules.add_perm('projects.add_integration_object', is_project_owner | is_project_manager | is_site_manager)
rules.add_perm('projects.change_integration_object', is_project_owner | is_project_manager | is_site_manager)
rules.add_perm('projects.delete_integration_object', is_project_owner | is_project_manager | is_site_manager)

rules.add_perm('projects.view_issue_object', is_project_member | is_site_manager)
rules.add_perm('projects.view_issue_object', is_project_member | is_internal_project | is_site_manager)
rules.add_perm('projects.add_issue_object', is_project_manager | is_project_owner | is_site_manager)
rules.add_perm('projects.change_issue_object', is_project_author | is_project_manager | is_project_owner | is_site_manager) # noqa: E501
rules.add_perm('projects.delete_issue_object', is_project_manager | is_project_owner | is_site_manager)

rules.add_perm('projects.view_snapshot_object', is_project_member | is_site_manager)
rules.add_perm('projects.view_snapshot_object', is_project_member | is_internal_project | is_site_manager)
rules.add_perm('projects.add_snapshot_object', is_project_manager | is_project_owner | is_site_manager)
rules.add_perm('projects.change_snapshot_object', is_project_manager | is_project_owner | is_site_manager)
rules.add_perm('projects.rollback_snapshot_object', is_project_manager | is_project_owner | is_site_manager)

rules.add_perm('projects.view_value_object', is_project_member | is_site_manager)
rules.add_perm('projects.view_value_object', is_project_member | is_internal_project | is_site_manager)
rules.add_perm('projects.add_value_object', is_project_author | is_project_manager | is_project_owner | is_site_manager)
rules.add_perm('projects.change_value_object', is_project_author | is_project_manager | is_project_owner | is_site_manager) # noqa: E501
rules.add_perm('projects.delete_value_object', is_project_author | is_project_manager | is_project_owner | is_site_manager) # noqa: E501

rules.add_perm('projects.view_page_object', is_project_member | is_site_manager)
rules.add_perm('projects.view_page_object', is_project_member | is_internal_project | is_site_manager)

# TODO: use one of the permissions above
rules.add_perm('projects.is_project_owner', is_project_owner)
10 changes: 10 additions & 0 deletions rdmo/projects/templates/projects/project_detail_header.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ <h1>{{ project.title }}</h1>
{% include 'projects/project_detail_header_catalog.html' %}
</td>
</tr>
{% if settings.PROJECT_VISIBILITY %}
<tr id="project-visibility">
<td>
<strong>{% trans 'Visibility' %}</strong>
</td>
<td>
{% include 'projects/project_detail_header_visibility.html' %}
</td>
</tr>
{% endif %}
{% if project.is_child_node or project.get_descendant_count %}
{% drilldown_tree_for_node project as project_tree all_descendants %}
<tr>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{% load i18n %}
{% load core_tags %}

{% if can_change_project %}
<p class="pull-right">
<a href="{% url 'project_update_visibility' project.pk %}" title="{% trans 'Update project visibility' %}">
<i class="fa fa-pencil"></i>
</a>
</p>
{% endif %}

<strong>{{ project.get_visibility_display }}</strong>
<span class="text-muted ml-10">{{ project.get_visibility_help }}</span>
5 changes: 5 additions & 0 deletions rdmo/projects/templates/projects/project_detail_sidebar.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ <h2>{% trans 'Options' %}</h2>
<li>
<a href="{% url 'project_update_information' project.pk %}">{% trans 'Update project information' %}</a>
</li>
{% if settings.PROJECT_VISIBILITY %}
<li>
<a href="{% url 'project_update_visibility' project.pk %}">{% trans 'Update project visibility' %}</a>
</li>
{% endif %}
<li>
<a href="{% url 'project_update_catalog' project.pk %}">{% trans 'Update project catalog' %}</a>
</li>
Expand Down
9 changes: 0 additions & 9 deletions rdmo/projects/tests/test_view_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,6 @@
('anonymous', None),
)

view_integration_permission_map = {
'owner': [1, 2, 3, 4, 5],
'manager': [1, 3, 5],
'author': [1, 3, 5],
'guest': [1, 3, 5],
'api': [1, 2, 3, 4, 5],
'site': [1, 2, 3, 4, 5]
}

add_integration_permission_map = change_integration_permission_map = delete_integration_permission_map = {
'owner': [1, 2, 3, 4, 5],
'manager': [1, 3, 5],
Expand Down
Loading