diff --git a/galaxy_ng/app/access_control/access_policy.py b/galaxy_ng/app/access_control/access_policy.py index f25318fc38..6e8c854657 100644 --- a/galaxy_ng/app/access_control/access_policy.py +++ b/galaxy_ng/app/access_control/access_policy.py @@ -831,38 +831,36 @@ class SurveyAccessPolicy(AccessPolicyBase): @classmethod def get_access_policy(cls, view): - # statements = GALAXY_STATEMENTS - - ''' - # If this is a galaxy access policy, load from the statement file - if cls.NAME: - return statements.get_pulp_access_policy(cls.NAME, default=[]) - ''' - - # Check if the view has a url pattern. If it does, check for customized - # policies from statements/pulp.py - try: - viewname = get_view_urlpattern(view) - - override_ap = PULP_VIEWSETS.get(viewname, None) - if override_ap: - return MockPulpAccessPolicy(override_ap) - - except AttributeError: - pass - - # If no customized policies exist, try to load the one defined on the view itself - try: - return MockPulpAccessPolicy(view.DEFAULT_ACCESS_POLICY) - except AttributeError: - pass + print(f'GET ACCESS POLICY {cls} {cls.NAME} {view}') + statements = [ + { + "action": [ + "get", + "list", + "retrieve", + ], + "principal": "*", + "effect": "allow", + }, + { + "action": [ + "create", + "update", + ], + "principal": "authenticated", + "effect": "allow", + "condition": "is_survey_user", + }, + ] # As a last resort, require admin rights + print('USE DEFAULT ... FUCK.') return MockPulpAccessPolicy( { - "statements": [{"action": "*", "principal": "admin", "effect": "allow"}], + "statements": statements, } ) def is_survey_user(self, request, viewset, action): + print(f'IS_SURVEY_USER ... {viewset} {action}') return True diff --git a/galaxy_ng/app/api/v3/urls.py b/galaxy_ng/app/api/v3/urls.py index c32db6e1b4..d680382991 100644 --- a/galaxy_ng/app/api/v3/urls.py +++ b/galaxy_ng/app/api/v3/urls.py @@ -189,10 +189,19 @@ viewsets.CollectionSurveyList.as_view({'get': 'list'}), name='collection-survey-list' ), + path( + "surveys/collections//", + viewsets.LegacyRoleSurveyList.as_view({'post': 'create'}), + name='collection-survey-create' + ), path( "surveys/roles/", viewsets.LegacyRoleSurveyList.as_view({'get': 'list'}), name='legacyrole-survey-list' + ), + path( + "surveys/roles//", + viewsets.LegacyRoleSurveyList.as_view({'post': 'create'}), + name='legacyrole-survey-create' ) - ] diff --git a/galaxy_ng/app/api/v3/viewsets/survey.py b/galaxy_ng/app/api/v3/viewsets/survey.py index 9b12474b9e..3acded675f 100644 --- a/galaxy_ng/app/api/v3/viewsets/survey.py +++ b/galaxy_ng/app/api/v3/viewsets/survey.py @@ -1,11 +1,16 @@ from django.conf import settings from django_filters import rest_framework as filters +from django.shortcuts import get_object_or_404 + from rest_framework import viewsets +from rest_framework.settings import perform_import +from rest_framework.permissions import IsAuthenticatedOrReadOnly +from rest_framework.response import Response +from rest_framework import status +from galaxy_ng.app.api.base import LocalSettingsMixin from galaxy_ng.app.access_control.access_policy import SurveyAccessPolicy -from rest_framework.settings import perform_import -from rest_framework.permissions import IsAuthenticatedOrReadOnly from galaxy_ng.app.models import ( CollectionSurvey, @@ -26,6 +31,10 @@ LegacyRoleSurveyFilter, ) +from galaxy_ng.app.api.v1.models import ( + LegacyRole +) + GALAXY_AUTHENTICATION_CLASSES = perform_import( settings.GALAXY_AUTHENTICATION_CLASSES, @@ -64,7 +73,7 @@ def get_queryset(self): ) -class LegacyRoleSurveyList(viewsets.ModelViewSet): +class LegacyRoleSurveyList(LocalSettingsMixin, viewsets.ModelViewSet): queryset = LegacyRoleSurvey.objects.all() serializer_class = LegacyRoleSurveySerializer @@ -77,3 +86,26 @@ def get_queryset(self): return LegacyRoleSurvey.objects.filter( user=self.request.user ) + + def create(self, *args, **kwargs): + print(f'ARGS:{args} KWARGS:{kwargs}') + role_id = kwargs.get('id') + + if not role_id: + return Response( + {"message": "role id not found"}, + status=status.HTTP_404_NOT_FOUND + ) + + role = get_object_or_404(LegacyRole, id=role_id) + + defaults = self.request.data + print(f'DATA: {defaults}') + + survey, _ = LegacyRoleSurvey.objects.get_or_create( + user=self.request.user, + role=role, + defaults=defaults + ) + + return Response({'id': survey.id}, status=status.HTTP_201_CREATED) \ No newline at end of file diff --git a/galaxy_ng/tests/integration/community/test_community_surveys.py b/galaxy_ng/tests/integration/community/test_community_surveys.py new file mode 100644 index 0000000000..f4f19b19c6 --- /dev/null +++ b/galaxy_ng/tests/integration/community/test_community_surveys.py @@ -0,0 +1,136 @@ +import copy +import json +import pytest +import random +import string + +from ..utils import ( + get_client, + SocialGithubClient, + GithubAdminClient, + cleanup_namespace, +) +from ..utils.legacy import ( + cleanup_social_user, + wait_for_v1_task, +) + + +pytestmark = pytest.mark.qa # noqa: F821 + + +SURVEY_FIELDS = [ + 'docs', + 'ease_of_use', + 'does_what_it_says', + 'works_as_is', + 'used_in_production' +] + + +def extract_default_config(ansible_config): + base_cfg = ansible_config('github_user_1') + cfg = {} + cfg['token'] = None + cfg['url'] = base_cfg.get('url') + cfg['auth_url'] = base_cfg.get('auth_url') + cfg['github_url'] = base_cfg.get('github_url') + cfg['github_api_url'] = base_cfg.get('github_api_url') + return cfg + + +@pytest.fixture() +def default_config(ansible_config): + yield extract_default_config(ansible_config) + + +@pytest.fixture +def imported_role(ansible_config): + github_user = 'jctannerTEST' + github_repo = 'role1' + cleanup_social_user(github_user, ansible_config) + cleanup_social_user(github_user.lower(), ansible_config) + + admin_config = ansible_config("admin") + admin_client = get_client( + config=admin_config, + request_token=False, + require_auth=True + ) + + # make the legacy namespace + ns_payload = { + 'name': github_user + } + resp = admin_client('/api/v1/namespaces/', method='POST', args=ns_payload) + assert resp['name'] == github_user, resp + assert not resp['summary_fields']['owners'], resp + assert not resp['summary_fields']['provider_namespaces'], resp + v1_id = resp['id'] + + # make the v3 namespace + v3_payload = { + 'name': github_user.lower(), + 'groups': [], + } + resp = admin_client('/api/_ui/v1/namespaces/', method='POST', args=v3_payload) + assert resp['name'] == github_user.lower(), resp + v3_id = resp['id'] + + # bind the v3 namespace to the v1 namespace + v3_bind = { + 'id': v3_id + } + admin_client(f'/api/v1/namespaces/{v1_id}/providers/', method='POST', args=v3_bind) + + # do an import with the admin ... + payload = { + 'github_repo': github_repo, + 'github_user': github_user, + } + resp = admin_client('/api/v1/imports/', method='POST', args=payload) + task_id = resp['results'][0]['id'] + res = wait_for_v1_task(task_id=task_id, api_client=admin_client, check=False) + + # get the role ... + role_qs = admin_client(f'/api/v1/roles/?owner__username={github_user}&name={github_repo}') + role_ds = role_qs['results'][0] + + yield role_ds + + +@pytest.mark.deployment_community +def test_community_role_survey(ansible_config, default_config, imported_role): + roleid = imported_role['id'] + + ga = GithubAdminClient() + + possible_values = [None] + list(range(0,6)) + user_survey_map = { + 'bob1': dict((x, random.choice(possible_values)) for x in SURVEY_FIELDS), + 'bob2': dict((x, random.choice(possible_values)) for x in SURVEY_FIELDS), + 'bob3': dict((x, random.choice(possible_values)) for x in SURVEY_FIELDS), + } + + for username, payload in user_survey_map.items(): + print(username) + cleanup_social_user(username, ansible_config) + ga.delete_user(login=username) + gcfg = ga.create_user( + login=username, + password='foobar1234', + email=username + '@noreply.github.com' + ) + gcfg['username'] = username + gcfg.update(default_config) + + with SocialGithubClient(config=gcfg) as sclient: + rkwargs = { + 'absolute_url': f'/api/v3/surveys/roles/{roleid}/', + 'data': payload, + } + resp = sclient.post(**rkwargs) + import epdb; epdb.st() + print(resp) + + import epdb; epdb.st() \ No newline at end of file