Skip to content

Commit

Permalink
Jkmarx/add primary group api (#2820)
Browse files Browse the repository at this point in the history
* Add userprofile api.

* Add primary-group field.)

* Add primary group field and remove affilation.

* Move validation to serializer.

* Add dependencies to migration.

* Fix migration reference.

* Use settings name instead of static str.
  • Loading branch information
jkmarx committed Jun 18, 2018
1 parent 8e649ed commit ef22e8e
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 9 deletions.
15 changes: 9 additions & 6 deletions refinery/core/migrations/0020_create_initial_site_statistics.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations
from django.db import migrations
from django.utils import timezone


from core.models import DataSet, UserProfile
from guardian.shortcuts import get_groups_with_perms


def create_initial_site_statistics(apps, schema_editor):
Expand All @@ -14,15 +12,20 @@ def create_initial_site_statistics(apps, schema_editor):
ExtendedGroup = apps.get_model("core", "ExtendedGroup")
WorkflowTool = apps.get_model("tool_manager", "WorkflowTool")
VisualizationTool = apps.get_model("tool_manager", "VisualizationTool")
UserProfile = apps.get_model("core", "UserProfile")
DataSet = apps.get_model("core", "DataSet")

SiteStatistics.objects.create(
run_date=timezone.now(),
datasets_uploaded=DataSet.objects.count(),
datasets_shared=len(
[dataset for dataset in DataSet.objects.all() if dataset.shared]
[dataset for dataset in DataSet.objects.all() if
get_groups_with_perms(dataset)]
),
users_created=User.objects.count(),
groups_created=ExtendedGroup.objects.exclude(manager_group=None).count(),
groups_created=ExtendedGroup.objects.exclude(
manager_group=None
).count(),
unique_user_logins=User.objects.filter(
last_login__lte=timezone.now()
).count(),
Expand Down
20 changes: 20 additions & 0 deletions refinery/core/migrations/0027_userprofile_primary_group.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('auth', '0006_require_contenttypes_0002'),
('core', '0026_auto_20180608_1123'),
]

operations = [
migrations.AddField(
model_name='userprofile',
name='primary_group',
field=models.ForeignKey(blank=True, to='auth.Group', null=True),
),
]
1 change: 1 addition & 0 deletions refinery/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ class UserProfile(models.Model):
uuid = UUIDField(unique=True, auto=True)
user = models.OneToOneField(User, related_name='profile')
affiliation = models.CharField(max_length=100, blank=True)
primary_group = models.ForeignKey(Group, blank=True, null=True)
catch_all_project = models.ForeignKey('Project', blank=True, null=True)
login_count = models.IntegerField(default=0)

Expand Down
35 changes: 34 additions & 1 deletion refinery/core/serializers.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import logging

import celery
from django.conf import settings
from rest_framework import serializers
from rest_framework.validators import UniqueValidator

from data_set_manager.models import Node
from file_store.models import FileStoreItem

from .models import DataSet, Workflow
from .models import DataSet, UserProfile, Workflow

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -62,6 +63,38 @@ def partial_update(self, instance, validated_data):
return instance


class UserProfileSerializer(serializers.ModelSerializer):

class Meta:
model = UserProfile
fields = ['primary_group']

def validate_primary_group(self, group):
user = self.context.get('request').user
if user.id in group.user_set.values_list('id', flat=True):
pass
else:
raise serializers.ValidationError(
'User is not a member of group, %s', group
)

if group.name != settings.REFINERY_PUBLIC_GROUP_NAME:
return group
else:
raise serializers.ValidationError('Primary group can not be '
'the Public group')

def partial_update(self, instance, validated_data):
"""
Update and return an existing `UserProfile` instance, given the
validated data.
"""
instance.primary_group = validated_data.get('primary_group',
instance.primary_group)
instance.save()
return instance


class WorkflowSerializer(serializers.HyperlinkedModelSerializer):
instance = serializers.HyperlinkedIdentityField(
view_name='workflow-detail')
Expand Down
4 changes: 3 additions & 1 deletion refinery/core/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from rest_framework.routers import DefaultRouter

from .views import (AnalysesViewSet, DataSetsViewSet, NodeViewSet,
OpenIDToken, WorkflowViewSet)
OpenIDToken, UserProfileViewSet, WorkflowViewSet)

urlpatterns = patterns(
'core.views',
Expand Down Expand Up @@ -77,6 +77,8 @@
core_router.register(r'workflows', WorkflowViewSet)
core_router.urls.extend([
url(r'^data_sets/$', DataSetsViewSet.as_view()),
url(r'^user_profile/(?P<uuid>' + UUID_RE + r')/$',
UserProfileViewSet.as_view()),
url(r'^data_sets/(?P<uuid>' + UUID_RE + r')/$',
DataSetsViewSet.as_view()),
url(r'^analyses/(?P<uuid>' + UUID_RE + r')/$',
Expand Down
49 changes: 48 additions & 1 deletion refinery/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
from .models import (Analysis, CustomRegistrationProfile, DataSet,
ExtendedGroup, Invitation, Ontology, Project,
UserProfile, Workflow, WorkflowEngine)
from .serializers import DataSetSerializer, NodeSerializer, WorkflowSerializer
from .serializers import (DataSetSerializer, NodeSerializer,
UserProfileSerializer, WorkflowSerializer)
from .utils import (api_error_response, get_data_sets_annotations,
get_resources_for_user)

Expand Down Expand Up @@ -1079,3 +1080,49 @@ def post(self, request):
token["Region"] = region

return Response(token)


class UserProfileViewSet(APIView):
"""API endpoint that allows for UserProfiles to be edited.
---
#YAML
PATCH:
parameters_strategy:
form: replace
query: merge
parameters:
- name: uuid
description: User profile uuid used as an identifier
type: string
paramType: path
required: true
- name: primary_group
description: group id
type: int
paramType: form
required: false
...
"""
http_method_names = ["patch"]

def patch(self, request, uuid):
if request.user.is_anonymous():
return Response(
self.user, status=status.HTTP_401_UNAUTHORIZED
)

serializer = UserProfileSerializer(request.user.profile,
data=request.data,
partial=True,
context={'request': request})

if serializer.is_valid():
serializer.save()
return Response(
serializer.data, status=status.HTTP_202_ACCEPTED
)
return Response(
serializer.errors, status=status.HTTP_400_BAD_REQUEST
)

0 comments on commit ef22e8e

Please sign in to comment.