root / snf-astakos-app / astakos / api / projects.py @ 362dadaa
History | View | Annotate | Download (21.9 kB)
1 | 2556cf45 | Giorgos Korfiatis | # Copyright 2013 GRNET S.A. All rights reserved.
|
---|---|---|---|
2 | 2556cf45 | Giorgos Korfiatis | #
|
3 | 2556cf45 | Giorgos Korfiatis | # Redistribution and use in source and binary forms, with or
|
4 | 2556cf45 | Giorgos Korfiatis | # without modification, are permitted provided that the following
|
5 | 2556cf45 | Giorgos Korfiatis | # conditions are met:
|
6 | 2556cf45 | Giorgos Korfiatis | #
|
7 | 2556cf45 | Giorgos Korfiatis | # 1. Redistributions of source code must retain the above
|
8 | 2556cf45 | Giorgos Korfiatis | # copyright notice, this list of conditions and the following
|
9 | 2556cf45 | Giorgos Korfiatis | # disclaimer.
|
10 | 2556cf45 | Giorgos Korfiatis | #
|
11 | 2556cf45 | Giorgos Korfiatis | # 2. Redistributions in binary form must reproduce the above
|
12 | 2556cf45 | Giorgos Korfiatis | # copyright notice, this list of conditions and the following
|
13 | 2556cf45 | Giorgos Korfiatis | # disclaimer in the documentation and/or other materials
|
14 | 2556cf45 | Giorgos Korfiatis | # provided with the distribution.
|
15 | 2556cf45 | Giorgos Korfiatis | #
|
16 | 2556cf45 | Giorgos Korfiatis | # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
|
17 | 2556cf45 | Giorgos Korfiatis | # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
18 | 2556cf45 | Giorgos Korfiatis | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
19 | 2556cf45 | Giorgos Korfiatis | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
|
20 | 2556cf45 | Giorgos Korfiatis | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21 | 2556cf45 | Giorgos Korfiatis | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22 | 2556cf45 | Giorgos Korfiatis | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
23 | 2556cf45 | Giorgos Korfiatis | # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
24 | 2556cf45 | Giorgos Korfiatis | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25 | 2556cf45 | Giorgos Korfiatis | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
26 | 2556cf45 | Giorgos Korfiatis | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27 | 2556cf45 | Giorgos Korfiatis | # POSSIBILITY OF SUCH DAMAGE.
|
28 | 2556cf45 | Giorgos Korfiatis | #
|
29 | 2556cf45 | Giorgos Korfiatis | # The views and conclusions contained in the software and
|
30 | 2556cf45 | Giorgos Korfiatis | # documentation are those of the authors and should not be
|
31 | 2556cf45 | Giorgos Korfiatis | # interpreted as representing official policies, either expressed
|
32 | 2556cf45 | Giorgos Korfiatis | # or implied, of GRNET S.A.
|
33 | 2556cf45 | Giorgos Korfiatis | |
34 | a23ac2f7 | Giorgos Korfiatis | import re |
35 | 2556cf45 | Giorgos Korfiatis | from django.utils import simplejson as json |
36 | 2556cf45 | Giorgos Korfiatis | from django.views.decorators.csrf import csrf_exempt |
37 | 2556cf45 | Giorgos Korfiatis | from django.http import HttpResponse |
38 | 2556cf45 | Giorgos Korfiatis | from django.db.models import Q |
39 | a3e3917f | Giorgos Korfiatis | from django.db import transaction |
40 | 2556cf45 | Giorgos Korfiatis | |
41 | 2556cf45 | Giorgos Korfiatis | from astakos.api.util import json_response |
42 | 2556cf45 | Giorgos Korfiatis | |
43 | 2556cf45 | Giorgos Korfiatis | from snf_django.lib import api |
44 | 2556cf45 | Giorgos Korfiatis | from snf_django.lib.api import faults |
45 | 2556cf45 | Giorgos Korfiatis | from .util import user_from_token, invert_dict, read_json_body |
46 | 2556cf45 | Giorgos Korfiatis | |
47 | 2556cf45 | Giorgos Korfiatis | from astakos.im import functions |
48 | 2556cf45 | Giorgos Korfiatis | from astakos.im.models import ( |
49 | 2556cf45 | Giorgos Korfiatis | AstakosUser, Project, ProjectApplication, ProjectMembership, |
50 | 362dadaa | Giorgos Korfiatis | ProjectResourceQuota, ProjectResourceGrant, ProjectLog, |
51 | 362dadaa | Giorgos Korfiatis | ProjectMembershipLog) |
52 | 2556cf45 | Giorgos Korfiatis | import synnefo.util.date as date_util |
53 | 362dadaa | Giorgos Korfiatis | from synnefo.util import units |
54 | 2556cf45 | Giorgos Korfiatis | |
55 | 2556cf45 | Giorgos Korfiatis | |
56 | 2556cf45 | Giorgos Korfiatis | MEMBERSHIP_POLICY_SHOW = { |
57 | 2556cf45 | Giorgos Korfiatis | functions.AUTO_ACCEPT_POLICY: "auto",
|
58 | 2556cf45 | Giorgos Korfiatis | functions.MODERATED_POLICY: "moderated",
|
59 | 2556cf45 | Giorgos Korfiatis | functions.CLOSED_POLICY: "closed",
|
60 | 2556cf45 | Giorgos Korfiatis | } |
61 | 2556cf45 | Giorgos Korfiatis | |
62 | 2556cf45 | Giorgos Korfiatis | MEMBERSHIP_POLICY = invert_dict(MEMBERSHIP_POLICY_SHOW) |
63 | 2556cf45 | Giorgos Korfiatis | |
64 | 2556cf45 | Giorgos Korfiatis | APPLICATION_STATE_SHOW = { |
65 | 2556cf45 | Giorgos Korfiatis | ProjectApplication.PENDING: "pending",
|
66 | 2556cf45 | Giorgos Korfiatis | ProjectApplication.APPROVED: "approved",
|
67 | 2556cf45 | Giorgos Korfiatis | ProjectApplication.REPLACED: "replaced",
|
68 | 2556cf45 | Giorgos Korfiatis | ProjectApplication.DENIED: "denied",
|
69 | 2556cf45 | Giorgos Korfiatis | ProjectApplication.DISMISSED: "dismissed",
|
70 | 2556cf45 | Giorgos Korfiatis | ProjectApplication.CANCELLED: "cancelled",
|
71 | 2556cf45 | Giorgos Korfiatis | } |
72 | 2556cf45 | Giorgos Korfiatis | |
73 | 2556cf45 | Giorgos Korfiatis | PROJECT_STATE_SHOW = { |
74 | 362dadaa | Giorgos Korfiatis | Project.UNINITIALIZED: "uninitialized",
|
75 | 362dadaa | Giorgos Korfiatis | Project.NORMAL: "active",
|
76 | 362dadaa | Giorgos Korfiatis | Project.SUSPENDED: "suspended",
|
77 | 362dadaa | Giorgos Korfiatis | Project.TERMINATED: "terminated",
|
78 | 362dadaa | Giorgos Korfiatis | Project.DELETED: "deleted",
|
79 | 2556cf45 | Giorgos Korfiatis | } |
80 | 2556cf45 | Giorgos Korfiatis | |
81 | 2556cf45 | Giorgos Korfiatis | PROJECT_STATE = invert_dict(PROJECT_STATE_SHOW) |
82 | 2556cf45 | Giorgos Korfiatis | |
83 | 2556cf45 | Giorgos Korfiatis | MEMBERSHIP_STATE_SHOW = { |
84 | 2556cf45 | Giorgos Korfiatis | ProjectMembership.REQUESTED: "requested",
|
85 | 2556cf45 | Giorgos Korfiatis | ProjectMembership.ACCEPTED: "accepted",
|
86 | 2556cf45 | Giorgos Korfiatis | ProjectMembership.LEAVE_REQUESTED: "leave_requested",
|
87 | 2556cf45 | Giorgos Korfiatis | ProjectMembership.USER_SUSPENDED: "suspended",
|
88 | 2556cf45 | Giorgos Korfiatis | ProjectMembership.REJECTED: "rejected",
|
89 | 2556cf45 | Giorgos Korfiatis | ProjectMembership.CANCELLED: "cancelled",
|
90 | 2556cf45 | Giorgos Korfiatis | ProjectMembership.REMOVED: "removed",
|
91 | 2556cf45 | Giorgos Korfiatis | } |
92 | 2556cf45 | Giorgos Korfiatis | |
93 | 2556cf45 | Giorgos Korfiatis | |
94 | 362dadaa | Giorgos Korfiatis | def _grant_details(grants): |
95 | 2556cf45 | Giorgos Korfiatis | resources = {} |
96 | 2556cf45 | Giorgos Korfiatis | for grant in grants: |
97 | 85ae5a4c | Giorgos Korfiatis | if not grant.resource.api_visible: |
98 | 85ae5a4c | Giorgos Korfiatis | continue
|
99 | 2556cf45 | Giorgos Korfiatis | resources[grant.resource.name] = { |
100 | 2556cf45 | Giorgos Korfiatis | "member_capacity": grant.member_capacity,
|
101 | 2556cf45 | Giorgos Korfiatis | "project_capacity": grant.project_capacity,
|
102 | 2556cf45 | Giorgos Korfiatis | } |
103 | 362dadaa | Giorgos Korfiatis | return resources
|
104 | 2556cf45 | Giorgos Korfiatis | |
105 | 362dadaa | Giorgos Korfiatis | |
106 | 362dadaa | Giorgos Korfiatis | def _application_details(application, all_grants): |
107 | 362dadaa | Giorgos Korfiatis | grants = all_grants.get(application.id, []) |
108 | 362dadaa | Giorgos Korfiatis | resources = _grant_details(grants) |
109 | 362dadaa | Giorgos Korfiatis | join_policy = MEMBERSHIP_POLICY_SHOW.get(application.member_join_policy) |
110 | 362dadaa | Giorgos Korfiatis | leave_policy = MEMBERSHIP_POLICY_SHOW.get(application.member_leave_policy) |
111 | 2556cf45 | Giorgos Korfiatis | |
112 | 2556cf45 | Giorgos Korfiatis | d = { |
113 | 362dadaa | Giorgos Korfiatis | "id": application.id,
|
114 | 362dadaa | Giorgos Korfiatis | "state": APPLICATION_STATE_SHOW[application.state],
|
115 | 2556cf45 | Giorgos Korfiatis | "name": application.name,
|
116 | 362dadaa | Giorgos Korfiatis | "owner": application.owner.uuid if application.owner else None, |
117 | 2556cf45 | Giorgos Korfiatis | "applicant": application.applicant.uuid,
|
118 | 2556cf45 | Giorgos Korfiatis | "homepage": application.homepage,
|
119 | 2556cf45 | Giorgos Korfiatis | "description": application.description,
|
120 | 2556cf45 | Giorgos Korfiatis | "start_date": application.start_date,
|
121 | 2556cf45 | Giorgos Korfiatis | "end_date": application.end_date,
|
122 | 362dadaa | Giorgos Korfiatis | "comments": application.comments,
|
123 | 2556cf45 | Giorgos Korfiatis | "join_policy": join_policy,
|
124 | 2556cf45 | Giorgos Korfiatis | "leave_policy": leave_policy,
|
125 | 2556cf45 | Giorgos Korfiatis | "max_members": application.limit_on_members_number,
|
126 | 362dadaa | Giorgos Korfiatis | "private": application.private,
|
127 | 2556cf45 | Giorgos Korfiatis | "resources": resources,
|
128 | 2556cf45 | Giorgos Korfiatis | } |
129 | 2556cf45 | Giorgos Korfiatis | return d
|
130 | 2556cf45 | Giorgos Korfiatis | |
131 | 2556cf45 | Giorgos Korfiatis | |
132 | 2556cf45 | Giorgos Korfiatis | def get_projects_details(projects, request_user=None): |
133 | 362dadaa | Giorgos Korfiatis | applications = [p.last_application for p in projects if p.last_application] |
134 | 362dadaa | Giorgos Korfiatis | proj_quotas = ProjectResourceQuota.objects.quotas_per_project(projects) |
135 | 362dadaa | Giorgos Korfiatis | app_grants = ProjectResourceGrant.objects.grants_per_app(applications) |
136 | 2556cf45 | Giorgos Korfiatis | deactivations = ProjectLog.objects.last_deactivations(projects) |
137 | 2556cf45 | Giorgos Korfiatis | |
138 | 2556cf45 | Giorgos Korfiatis | l = [] |
139 | 2556cf45 | Giorgos Korfiatis | for project in projects: |
140 | 362dadaa | Giorgos Korfiatis | join_policy = MEMBERSHIP_POLICY_SHOW[project.member_join_policy] |
141 | 362dadaa | Giorgos Korfiatis | leave_policy = MEMBERSHIP_POLICY_SHOW[project.member_leave_policy] |
142 | 362dadaa | Giorgos Korfiatis | quotas = proj_quotas.get(project.id, []) |
143 | 362dadaa | Giorgos Korfiatis | resources = _grant_details(quotas) |
144 | 362dadaa | Giorgos Korfiatis | |
145 | 2556cf45 | Giorgos Korfiatis | d = { |
146 | 88f5242e | Giorgos Korfiatis | "id": project.uuid,
|
147 | 362dadaa | Giorgos Korfiatis | "state": PROJECT_STATE_SHOW[project.state],
|
148 | 2556cf45 | Giorgos Korfiatis | "creation_date": project.creation_date,
|
149 | 362dadaa | Giorgos Korfiatis | "name": project.realname,
|
150 | 362dadaa | Giorgos Korfiatis | "owner": project.owner.uuid if project.owner else None, |
151 | 362dadaa | Giorgos Korfiatis | "homepage": project.homepage,
|
152 | 362dadaa | Giorgos Korfiatis | "description": project.description,
|
153 | 362dadaa | Giorgos Korfiatis | "end_date": project.end_date,
|
154 | 362dadaa | Giorgos Korfiatis | "join_policy": join_policy,
|
155 | 362dadaa | Giorgos Korfiatis | "leave_policy": leave_policy,
|
156 | 362dadaa | Giorgos Korfiatis | "max_members": project.limit_on_members_number,
|
157 | 362dadaa | Giorgos Korfiatis | "private": project.private,
|
158 | 362dadaa | Giorgos Korfiatis | "base_project": project.is_base,
|
159 | 362dadaa | Giorgos Korfiatis | "resources": resources,
|
160 | 362dadaa | Giorgos Korfiatis | } |
161 | 362dadaa | Giorgos Korfiatis | |
162 | 2556cf45 | Giorgos Korfiatis | check = functions.project_check_allowed |
163 | 2556cf45 | Giorgos Korfiatis | if check(project, request_user,
|
164 | 2556cf45 | Giorgos Korfiatis | level=functions.APPLICANT_LEVEL, silent=True):
|
165 | 362dadaa | Giorgos Korfiatis | application = project.last_application |
166 | 362dadaa | Giorgos Korfiatis | if application:
|
167 | 362dadaa | Giorgos Korfiatis | d["last_application"] = _application_details(
|
168 | 362dadaa | Giorgos Korfiatis | application, app_grants) |
169 | 2556cf45 | Giorgos Korfiatis | deact = deactivations.get(project.id) |
170 | 2556cf45 | Giorgos Korfiatis | if deact is not None: |
171 | 2556cf45 | Giorgos Korfiatis | d["deactivation_date"] = deact.date
|
172 | 2556cf45 | Giorgos Korfiatis | l.append(d) |
173 | 2556cf45 | Giorgos Korfiatis | return l
|
174 | 2556cf45 | Giorgos Korfiatis | |
175 | 2556cf45 | Giorgos Korfiatis | |
176 | 2556cf45 | Giorgos Korfiatis | def get_project_details(project, request_user=None): |
177 | 2556cf45 | Giorgos Korfiatis | return get_projects_details([project], request_user=request_user)[0] |
178 | 2556cf45 | Giorgos Korfiatis | |
179 | 2556cf45 | Giorgos Korfiatis | |
180 | 2556cf45 | Giorgos Korfiatis | def get_memberships_details(memberships, request_user): |
181 | 2556cf45 | Giorgos Korfiatis | all_logs = ProjectMembershipLog.objects.last_logs(memberships) |
182 | 2556cf45 | Giorgos Korfiatis | |
183 | 2556cf45 | Giorgos Korfiatis | l = [] |
184 | 2556cf45 | Giorgos Korfiatis | for membership in memberships: |
185 | 2556cf45 | Giorgos Korfiatis | logs = all_logs.get(membership.id, {}) |
186 | 2556cf45 | Giorgos Korfiatis | dates = {} |
187 | 2556cf45 | Giorgos Korfiatis | for s, log in logs.iteritems(): |
188 | 2556cf45 | Giorgos Korfiatis | dates[MEMBERSHIP_STATE_SHOW[s]] = log.date |
189 | 2556cf45 | Giorgos Korfiatis | |
190 | 2556cf45 | Giorgos Korfiatis | allowed_actions = functions.membership_allowed_actions( |
191 | 2556cf45 | Giorgos Korfiatis | membership, request_user) |
192 | 2556cf45 | Giorgos Korfiatis | d = { |
193 | 2556cf45 | Giorgos Korfiatis | "id": membership.id,
|
194 | 2556cf45 | Giorgos Korfiatis | "user": membership.person.uuid,
|
195 | 88f5242e | Giorgos Korfiatis | "project": membership.project.uuid,
|
196 | 2556cf45 | Giorgos Korfiatis | "state": MEMBERSHIP_STATE_SHOW[membership.state],
|
197 | 2556cf45 | Giorgos Korfiatis | "allowed_actions": allowed_actions,
|
198 | 2556cf45 | Giorgos Korfiatis | } |
199 | 2556cf45 | Giorgos Korfiatis | d.update(dates) |
200 | 2556cf45 | Giorgos Korfiatis | l.append(d) |
201 | 2556cf45 | Giorgos Korfiatis | return l
|
202 | 2556cf45 | Giorgos Korfiatis | |
203 | 2556cf45 | Giorgos Korfiatis | |
204 | 2556cf45 | Giorgos Korfiatis | def get_membership_details(membership, request_user): |
205 | 2556cf45 | Giorgos Korfiatis | return get_memberships_details([membership], request_user)[0] |
206 | 2556cf45 | Giorgos Korfiatis | |
207 | 2556cf45 | Giorgos Korfiatis | |
208 | 2556cf45 | Giorgos Korfiatis | def _query(attr): |
209 | 2556cf45 | Giorgos Korfiatis | def inner(val): |
210 | 2556cf45 | Giorgos Korfiatis | kw = attr + "__in" if isinstance(val, list) else attr |
211 | 2556cf45 | Giorgos Korfiatis | return Q(**{kw: val})
|
212 | 2556cf45 | Giorgos Korfiatis | return inner
|
213 | 2556cf45 | Giorgos Korfiatis | |
214 | 2556cf45 | Giorgos Korfiatis | |
215 | 2556cf45 | Giorgos Korfiatis | def _get_project_state(val): |
216 | 2556cf45 | Giorgos Korfiatis | try:
|
217 | 2556cf45 | Giorgos Korfiatis | return PROJECT_STATE[val]
|
218 | 2556cf45 | Giorgos Korfiatis | except KeyError: |
219 | 2556cf45 | Giorgos Korfiatis | raise faults.BadRequest("Unrecognized state %s" % val) |
220 | 2556cf45 | Giorgos Korfiatis | |
221 | 2556cf45 | Giorgos Korfiatis | |
222 | 2556cf45 | Giorgos Korfiatis | def _project_state_query(val): |
223 | 2556cf45 | Giorgos Korfiatis | if isinstance(val, list): |
224 | 2556cf45 | Giorgos Korfiatis | states = [_get_project_state(v) for v in val] |
225 | 362dadaa | Giorgos Korfiatis | return Q(state__in=states)
|
226 | 362dadaa | Giorgos Korfiatis | return Q(state=_get_project_state(val))
|
227 | 2556cf45 | Giorgos Korfiatis | |
228 | 2556cf45 | Giorgos Korfiatis | |
229 | 2556cf45 | Giorgos Korfiatis | PROJECT_QUERY = { |
230 | 362dadaa | Giorgos Korfiatis | "name": _query("realname"), |
231 | 362dadaa | Giorgos Korfiatis | "owner": _query("owner__uuid"), |
232 | 2556cf45 | Giorgos Korfiatis | "state": _project_state_query,
|
233 | 2556cf45 | Giorgos Korfiatis | } |
234 | 2556cf45 | Giorgos Korfiatis | |
235 | 2556cf45 | Giorgos Korfiatis | |
236 | 2556cf45 | Giorgos Korfiatis | def make_project_query(filters): |
237 | 2556cf45 | Giorgos Korfiatis | qs = Q() |
238 | 2556cf45 | Giorgos Korfiatis | for attr, val in filters.iteritems(): |
239 | 2556cf45 | Giorgos Korfiatis | try:
|
240 | 2556cf45 | Giorgos Korfiatis | _q = PROJECT_QUERY[attr] |
241 | 2556cf45 | Giorgos Korfiatis | except KeyError: |
242 | 2556cf45 | Giorgos Korfiatis | raise faults.BadRequest("Unrecognized filter %s" % attr) |
243 | 2556cf45 | Giorgos Korfiatis | qs &= _q(val) |
244 | 2556cf45 | Giorgos Korfiatis | return qs
|
245 | 2556cf45 | Giorgos Korfiatis | |
246 | 2556cf45 | Giorgos Korfiatis | |
247 | 2556cf45 | Giorgos Korfiatis | class ExceptionHandler(object): |
248 | 2556cf45 | Giorgos Korfiatis | def __enter__(self): |
249 | 2556cf45 | Giorgos Korfiatis | pass
|
250 | 2556cf45 | Giorgos Korfiatis | |
251 | 2556cf45 | Giorgos Korfiatis | EXCS = { |
252 | 2556cf45 | Giorgos Korfiatis | functions.ProjectNotFound: faults.ItemNotFound, |
253 | 2556cf45 | Giorgos Korfiatis | functions.ProjectForbidden: faults.Forbidden, |
254 | 2556cf45 | Giorgos Korfiatis | functions.ProjectBadRequest: faults.BadRequest, |
255 | 2556cf45 | Giorgos Korfiatis | functions.ProjectConflict: faults.Conflict, |
256 | 2556cf45 | Giorgos Korfiatis | } |
257 | 2556cf45 | Giorgos Korfiatis | |
258 | 2556cf45 | Giorgos Korfiatis | def __exit__(self, exc_type, value, traceback): |
259 | 2556cf45 | Giorgos Korfiatis | if value is not None: # exception |
260 | 2556cf45 | Giorgos Korfiatis | try:
|
261 | 2556cf45 | Giorgos Korfiatis | e = self.EXCS[exc_type]
|
262 | 2556cf45 | Giorgos Korfiatis | except KeyError: |
263 | 2556cf45 | Giorgos Korfiatis | return False # reraise |
264 | 2556cf45 | Giorgos Korfiatis | raise e(value.message)
|
265 | 2556cf45 | Giorgos Korfiatis | |
266 | 2556cf45 | Giorgos Korfiatis | |
267 | 2556cf45 | Giorgos Korfiatis | @csrf_exempt
|
268 | 2556cf45 | Giorgos Korfiatis | def projects(request): |
269 | 2556cf45 | Giorgos Korfiatis | method = request.method |
270 | 2556cf45 | Giorgos Korfiatis | if method == "GET": |
271 | 2556cf45 | Giorgos Korfiatis | return get_projects(request)
|
272 | 2556cf45 | Giorgos Korfiatis | elif method == "POST": |
273 | 2556cf45 | Giorgos Korfiatis | return create_project(request)
|
274 | 2aba7764 | Sofia Papagiannaki | return api.api_method_not_allowed(request, allowed_methods=['GET', 'POST']) |
275 | 2556cf45 | Giorgos Korfiatis | |
276 | 2556cf45 | Giorgos Korfiatis | |
277 | 2556cf45 | Giorgos Korfiatis | @api.api_method(http_method="GET", token_required=True, user_required=False) |
278 | 2556cf45 | Giorgos Korfiatis | @user_from_token
|
279 | a3e3917f | Giorgos Korfiatis | @transaction.commit_on_success
|
280 | 2556cf45 | Giorgos Korfiatis | def get_projects(request): |
281 | 2556cf45 | Giorgos Korfiatis | user = request.user |
282 | 2556cf45 | Giorgos Korfiatis | input_data = read_json_body(request, default={}) |
283 | 2556cf45 | Giorgos Korfiatis | filters = input_data.get("filter", {})
|
284 | 2556cf45 | Giorgos Korfiatis | query = make_project_query(filters) |
285 | 2556cf45 | Giorgos Korfiatis | projects = _get_projects(query, request_user=user) |
286 | 2556cf45 | Giorgos Korfiatis | data = get_projects_details(projects, request_user=user) |
287 | 2556cf45 | Giorgos Korfiatis | return json_response(data)
|
288 | 2556cf45 | Giorgos Korfiatis | |
289 | 2556cf45 | Giorgos Korfiatis | |
290 | 2556cf45 | Giorgos Korfiatis | def _get_projects(query, request_user=None): |
291 | 2556cf45 | Giorgos Korfiatis | projects = Project.objects.filter(query) |
292 | 2556cf45 | Giorgos Korfiatis | |
293 | 2556cf45 | Giorgos Korfiatis | if not request_user.is_project_admin(): |
294 | 2556cf45 | Giorgos Korfiatis | membs = request_user.projectmembership_set.any_accepted() |
295 | 2556cf45 | Giorgos Korfiatis | memb_projects = membs.values_list("project", flat=True) |
296 | 2556cf45 | Giorgos Korfiatis | is_memb = Q(id__in=memb_projects) |
297 | 362dadaa | Giorgos Korfiatis | owned = Q(owner=request_user) |
298 | 362dadaa | Giorgos Korfiatis | active = (Q(state=Project.NORMAL) & |
299 | 362dadaa | Giorgos Korfiatis | Q(private=False))
|
300 | 2556cf45 | Giorgos Korfiatis | projects = projects.filter(is_memb | owned | active) |
301 | 362dadaa | Giorgos Korfiatis | return projects.select_related("last_application") |
302 | 2556cf45 | Giorgos Korfiatis | |
303 | 2556cf45 | Giorgos Korfiatis | |
304 | 2556cf45 | Giorgos Korfiatis | @api.api_method(http_method="POST", token_required=True, user_required=False) |
305 | 2556cf45 | Giorgos Korfiatis | @user_from_token
|
306 | a3e3917f | Giorgos Korfiatis | @transaction.commit_on_success
|
307 | 2556cf45 | Giorgos Korfiatis | def create_project(request): |
308 | 2556cf45 | Giorgos Korfiatis | user = request.user |
309 | b694875c | Christos Stavrakakis | data = request.body |
310 | 2556cf45 | Giorgos Korfiatis | app_data = json.loads(data) |
311 | 362dadaa | Giorgos Korfiatis | return submit_new_project(app_data, user)
|
312 | 2556cf45 | Giorgos Korfiatis | |
313 | 2556cf45 | Giorgos Korfiatis | |
314 | 2556cf45 | Giorgos Korfiatis | @csrf_exempt
|
315 | 2556cf45 | Giorgos Korfiatis | def project(request, project_id): |
316 | 2556cf45 | Giorgos Korfiatis | method = request.method |
317 | 2556cf45 | Giorgos Korfiatis | if method == "GET": |
318 | 2556cf45 | Giorgos Korfiatis | return get_project(request, project_id)
|
319 | 2556cf45 | Giorgos Korfiatis | if method == "POST": |
320 | 2556cf45 | Giorgos Korfiatis | return modify_project(request, project_id)
|
321 | 2aba7764 | Sofia Papagiannaki | return api.api_method_not_allowed(request, allowed_methods=['GET', 'POST']) |
322 | 2556cf45 | Giorgos Korfiatis | |
323 | 2556cf45 | Giorgos Korfiatis | |
324 | 2556cf45 | Giorgos Korfiatis | @api.api_method(http_method="GET", token_required=True, user_required=False) |
325 | 2556cf45 | Giorgos Korfiatis | @user_from_token
|
326 | a3e3917f | Giorgos Korfiatis | @transaction.commit_on_success
|
327 | 2556cf45 | Giorgos Korfiatis | def get_project(request, project_id): |
328 | 2556cf45 | Giorgos Korfiatis | user = request.user |
329 | 2556cf45 | Giorgos Korfiatis | with ExceptionHandler():
|
330 | 2556cf45 | Giorgos Korfiatis | project = _get_project(project_id, request_user=user) |
331 | 2556cf45 | Giorgos Korfiatis | data = get_project_details(project, user) |
332 | 2556cf45 | Giorgos Korfiatis | return json_response(data)
|
333 | 2556cf45 | Giorgos Korfiatis | |
334 | 2556cf45 | Giorgos Korfiatis | |
335 | 2556cf45 | Giorgos Korfiatis | def _get_project(project_id, request_user=None): |
336 | 88f5242e | Giorgos Korfiatis | project = functions.get_project_by_uuid(project_id) |
337 | 2556cf45 | Giorgos Korfiatis | functions.project_check_allowed( |
338 | 2556cf45 | Giorgos Korfiatis | project, request_user, level=functions.ANY_LEVEL) |
339 | 2556cf45 | Giorgos Korfiatis | return project
|
340 | 2556cf45 | Giorgos Korfiatis | |
341 | 2556cf45 | Giorgos Korfiatis | |
342 | 2556cf45 | Giorgos Korfiatis | @api.api_method(http_method="POST", token_required=True, user_required=False) |
343 | 2556cf45 | Giorgos Korfiatis | @user_from_token
|
344 | a3e3917f | Giorgos Korfiatis | @transaction.commit_on_success
|
345 | 2556cf45 | Giorgos Korfiatis | def modify_project(request, project_id): |
346 | 2556cf45 | Giorgos Korfiatis | user = request.user |
347 | b694875c | Christos Stavrakakis | data = request.body |
348 | 2556cf45 | Giorgos Korfiatis | app_data = json.loads(data) |
349 | 362dadaa | Giorgos Korfiatis | return submit_modification(app_data, user, project_id=project_id)
|
350 | 2556cf45 | Giorgos Korfiatis | |
351 | 2556cf45 | Giorgos Korfiatis | |
352 | 2556cf45 | Giorgos Korfiatis | def _get_date(d, key): |
353 | 2556cf45 | Giorgos Korfiatis | date_str = d.get(key) |
354 | 2556cf45 | Giorgos Korfiatis | if date_str is not None: |
355 | 2556cf45 | Giorgos Korfiatis | try:
|
356 | 2556cf45 | Giorgos Korfiatis | return date_util.isoparse(date_str)
|
357 | 2556cf45 | Giorgos Korfiatis | except:
|
358 | 2556cf45 | Giorgos Korfiatis | raise faults.BadRequest("Invalid %s" % key) |
359 | 2556cf45 | Giorgos Korfiatis | else:
|
360 | 2556cf45 | Giorgos Korfiatis | return None |
361 | 2556cf45 | Giorgos Korfiatis | |
362 | 2556cf45 | Giorgos Korfiatis | |
363 | 362dadaa | Giorgos Korfiatis | def _get_maybe_string(d, key, default=None): |
364 | 2556cf45 | Giorgos Korfiatis | value = d.get(key) |
365 | 2556cf45 | Giorgos Korfiatis | if value is not None and not isinstance(value, basestring): |
366 | 2556cf45 | Giorgos Korfiatis | raise faults.BadRequest("%s must be string" % key) |
367 | 362dadaa | Giorgos Korfiatis | if value is None: |
368 | 362dadaa | Giorgos Korfiatis | return default
|
369 | 2556cf45 | Giorgos Korfiatis | return value
|
370 | 2556cf45 | Giorgos Korfiatis | |
371 | 2556cf45 | Giorgos Korfiatis | |
372 | 362dadaa | Giorgos Korfiatis | def _get_maybe_boolean(d, key, default=None): |
373 | 62d30634 | Giorgos Korfiatis | value = d.get(key) |
374 | 62d30634 | Giorgos Korfiatis | if value is not None and not isinstance(value, bool): |
375 | 62d30634 | Giorgos Korfiatis | raise faults.BadRequest("%s must be boolean" % key) |
376 | 362dadaa | Giorgos Korfiatis | if value is None: |
377 | 362dadaa | Giorgos Korfiatis | return default
|
378 | 62d30634 | Giorgos Korfiatis | return value
|
379 | 62d30634 | Giorgos Korfiatis | |
380 | 62d30634 | Giorgos Korfiatis | |
381 | a23ac2f7 | Giorgos Korfiatis | DOMAIN_VALUE_REGEX = re.compile( |
382 | a23ac2f7 | Giorgos Korfiatis | r'^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$',
|
383 | a23ac2f7 | Giorgos Korfiatis | re.IGNORECASE) |
384 | a23ac2f7 | Giorgos Korfiatis | |
385 | a23ac2f7 | Giorgos Korfiatis | |
386 | a23ac2f7 | Giorgos Korfiatis | def valid_project_name(name): |
387 | a23ac2f7 | Giorgos Korfiatis | return DOMAIN_VALUE_REGEX.match(name) is not None |
388 | a23ac2f7 | Giorgos Korfiatis | |
389 | a23ac2f7 | Giorgos Korfiatis | |
390 | 362dadaa | Giorgos Korfiatis | def _parse_max_members(s): |
391 | 362dadaa | Giorgos Korfiatis | try:
|
392 | 362dadaa | Giorgos Korfiatis | max_members = units.parse(s) |
393 | 362dadaa | Giorgos Korfiatis | if max_members < 0: |
394 | 362dadaa | Giorgos Korfiatis | raise faults.BadRequest("Invalid max_members") |
395 | 362dadaa | Giorgos Korfiatis | return max_members
|
396 | 362dadaa | Giorgos Korfiatis | except units.ParseError:
|
397 | 362dadaa | Giorgos Korfiatis | raise faults.BadRequest("Invalid max_members") |
398 | 362dadaa | Giorgos Korfiatis | |
399 | 362dadaa | Giorgos Korfiatis | |
400 | 362dadaa | Giorgos Korfiatis | def submit_new_project(app_data, user): |
401 | 2556cf45 | Giorgos Korfiatis | uuid = app_data.get("owner")
|
402 | 2556cf45 | Giorgos Korfiatis | if uuid is None: |
403 | 2556cf45 | Giorgos Korfiatis | owner = user |
404 | 2556cf45 | Giorgos Korfiatis | else:
|
405 | 2556cf45 | Giorgos Korfiatis | try:
|
406 | 733f013d | Giorgos Korfiatis | owner = AstakosUser.objects.accepted().get(uuid=uuid) |
407 | 2556cf45 | Giorgos Korfiatis | except AstakosUser.DoesNotExist:
|
408 | 2556cf45 | Giorgos Korfiatis | raise faults.BadRequest("User does not exist.") |
409 | 2556cf45 | Giorgos Korfiatis | |
410 | 2556cf45 | Giorgos Korfiatis | try:
|
411 | 2556cf45 | Giorgos Korfiatis | name = app_data["name"]
|
412 | 2556cf45 | Giorgos Korfiatis | except KeyError: |
413 | 2556cf45 | Giorgos Korfiatis | raise faults.BadRequest("Name missing.") |
414 | 2556cf45 | Giorgos Korfiatis | |
415 | a23ac2f7 | Giorgos Korfiatis | if not valid_project_name(name): |
416 | a23ac2f7 | Giorgos Korfiatis | raise faults.BadRequest("Project name should be in domain format") |
417 | a23ac2f7 | Giorgos Korfiatis | |
418 | 2556cf45 | Giorgos Korfiatis | join_policy = app_data.get("join_policy", "moderated") |
419 | 2556cf45 | Giorgos Korfiatis | try:
|
420 | 2556cf45 | Giorgos Korfiatis | join_policy = MEMBERSHIP_POLICY[join_policy] |
421 | 2556cf45 | Giorgos Korfiatis | except KeyError: |
422 | 2556cf45 | Giorgos Korfiatis | raise faults.BadRequest("Invalid join policy") |
423 | 2556cf45 | Giorgos Korfiatis | |
424 | 2556cf45 | Giorgos Korfiatis | leave_policy = app_data.get("leave_policy", "auto") |
425 | 2556cf45 | Giorgos Korfiatis | try:
|
426 | 2556cf45 | Giorgos Korfiatis | leave_policy = MEMBERSHIP_POLICY[leave_policy] |
427 | 2556cf45 | Giorgos Korfiatis | except KeyError: |
428 | 2556cf45 | Giorgos Korfiatis | raise faults.BadRequest("Invalid leave policy") |
429 | 2556cf45 | Giorgos Korfiatis | |
430 | 2556cf45 | Giorgos Korfiatis | start_date = _get_date(app_data, "start_date")
|
431 | 2556cf45 | Giorgos Korfiatis | end_date = _get_date(app_data, "end_date")
|
432 | 2556cf45 | Giorgos Korfiatis | |
433 | 2556cf45 | Giorgos Korfiatis | if end_date is None: |
434 | 2556cf45 | Giorgos Korfiatis | raise faults.BadRequest("Missing end date") |
435 | 2556cf45 | Giorgos Korfiatis | |
436 | 362dadaa | Giorgos Korfiatis | try:
|
437 | 362dadaa | Giorgos Korfiatis | max_members = _parse_max_members(app_data["max_members"])
|
438 | 362dadaa | Giorgos Korfiatis | except KeyError: |
439 | 362dadaa | Giorgos Korfiatis | max_members = units.PRACTICALLY_INFINITE |
440 | 2556cf45 | Giorgos Korfiatis | |
441 | 62d30634 | Giorgos Korfiatis | private = bool(_get_maybe_boolean(app_data, "private")) |
442 | 362dadaa | Giorgos Korfiatis | homepage = _get_maybe_string(app_data, "homepage", "") |
443 | 362dadaa | Giorgos Korfiatis | description = _get_maybe_string(app_data, "description", "") |
444 | 362dadaa | Giorgos Korfiatis | comments = _get_maybe_string(app_data, "comments", "") |
445 | 362dadaa | Giorgos Korfiatis | resources = app_data.get("resources", {})
|
446 | 362dadaa | Giorgos Korfiatis | |
447 | 362dadaa | Giorgos Korfiatis | submit = functions.submit_application |
448 | 362dadaa | Giorgos Korfiatis | with ExceptionHandler():
|
449 | 362dadaa | Giorgos Korfiatis | application = submit( |
450 | 362dadaa | Giorgos Korfiatis | owner=owner, |
451 | 362dadaa | Giorgos Korfiatis | name=name, |
452 | 362dadaa | Giorgos Korfiatis | project_id=None,
|
453 | 362dadaa | Giorgos Korfiatis | homepage=homepage, |
454 | 362dadaa | Giorgos Korfiatis | description=description, |
455 | 362dadaa | Giorgos Korfiatis | start_date=start_date, |
456 | 362dadaa | Giorgos Korfiatis | end_date=end_date, |
457 | 362dadaa | Giorgos Korfiatis | member_join_policy=join_policy, |
458 | 362dadaa | Giorgos Korfiatis | member_leave_policy=leave_policy, |
459 | 362dadaa | Giorgos Korfiatis | limit_on_members_number=max_members, |
460 | 362dadaa | Giorgos Korfiatis | private=private, |
461 | 362dadaa | Giorgos Korfiatis | comments=comments, |
462 | 362dadaa | Giorgos Korfiatis | resources=resources, |
463 | 362dadaa | Giorgos Korfiatis | request_user=user) |
464 | 362dadaa | Giorgos Korfiatis | |
465 | 362dadaa | Giorgos Korfiatis | result = {"application": application.id,
|
466 | 362dadaa | Giorgos Korfiatis | "id": application.chain.uuid,
|
467 | 362dadaa | Giorgos Korfiatis | } |
468 | 362dadaa | Giorgos Korfiatis | return json_response(result, status_code=201) |
469 | 362dadaa | Giorgos Korfiatis | |
470 | 362dadaa | Giorgos Korfiatis | |
471 | 362dadaa | Giorgos Korfiatis | def submit_modification(app_data, user, project_id): |
472 | 362dadaa | Giorgos Korfiatis | owner = app_data.get("owner")
|
473 | 362dadaa | Giorgos Korfiatis | if owner is not None: |
474 | 362dadaa | Giorgos Korfiatis | try:
|
475 | 362dadaa | Giorgos Korfiatis | owner = AstakosUser.objects.accepted().get(uuid=owner) |
476 | 362dadaa | Giorgos Korfiatis | except AstakosUser.DoesNotExist:
|
477 | 362dadaa | Giorgos Korfiatis | raise faults.BadRequest("User does not exist.") |
478 | 362dadaa | Giorgos Korfiatis | |
479 | 362dadaa | Giorgos Korfiatis | name = app_data.get("name")
|
480 | 362dadaa | Giorgos Korfiatis | |
481 | 362dadaa | Giorgos Korfiatis | if name is not None and not valid_project_name(name): |
482 | 362dadaa | Giorgos Korfiatis | raise faults.BadRequest("Project name should be in domain format") |
483 | 362dadaa | Giorgos Korfiatis | |
484 | 362dadaa | Giorgos Korfiatis | join_policy = app_data.get("join_policy")
|
485 | 362dadaa | Giorgos Korfiatis | if join_policy is not None: |
486 | 362dadaa | Giorgos Korfiatis | try:
|
487 | 362dadaa | Giorgos Korfiatis | join_policy = MEMBERSHIP_POLICY[join_policy] |
488 | 362dadaa | Giorgos Korfiatis | except KeyError: |
489 | 362dadaa | Giorgos Korfiatis | raise faults.BadRequest("Invalid join policy") |
490 | 362dadaa | Giorgos Korfiatis | |
491 | 362dadaa | Giorgos Korfiatis | leave_policy = app_data.get("leave_policy")
|
492 | 362dadaa | Giorgos Korfiatis | if leave_policy is not None: |
493 | 362dadaa | Giorgos Korfiatis | try:
|
494 | 362dadaa | Giorgos Korfiatis | leave_policy = MEMBERSHIP_POLICY[leave_policy] |
495 | 362dadaa | Giorgos Korfiatis | except KeyError: |
496 | 362dadaa | Giorgos Korfiatis | raise faults.BadRequest("Invalid leave policy") |
497 | 362dadaa | Giorgos Korfiatis | |
498 | 362dadaa | Giorgos Korfiatis | start_date = _get_date(app_data, "start_date")
|
499 | 362dadaa | Giorgos Korfiatis | end_date = _get_date(app_data, "end_date")
|
500 | 362dadaa | Giorgos Korfiatis | |
501 | 362dadaa | Giorgos Korfiatis | max_members = app_data.get("max_members")
|
502 | 362dadaa | Giorgos Korfiatis | if max_members is not None: |
503 | 362dadaa | Giorgos Korfiatis | max_members = _parse_max_members(max_members) |
504 | 362dadaa | Giorgos Korfiatis | |
505 | 362dadaa | Giorgos Korfiatis | private = _get_maybe_boolean(app_data, "private")
|
506 | 2556cf45 | Giorgos Korfiatis | homepage = _get_maybe_string(app_data, "homepage")
|
507 | 2556cf45 | Giorgos Korfiatis | description = _get_maybe_string(app_data, "description")
|
508 | 2556cf45 | Giorgos Korfiatis | comments = _get_maybe_string(app_data, "comments")
|
509 | 2556cf45 | Giorgos Korfiatis | resources = app_data.get("resources", {})
|
510 | 2556cf45 | Giorgos Korfiatis | |
511 | 2556cf45 | Giorgos Korfiatis | submit = functions.submit_application |
512 | 2556cf45 | Giorgos Korfiatis | with ExceptionHandler():
|
513 | 2556cf45 | Giorgos Korfiatis | application = submit( |
514 | 2556cf45 | Giorgos Korfiatis | owner=owner, |
515 | 2556cf45 | Giorgos Korfiatis | name=name, |
516 | 2556cf45 | Giorgos Korfiatis | project_id=project_id, |
517 | 2556cf45 | Giorgos Korfiatis | homepage=homepage, |
518 | 2556cf45 | Giorgos Korfiatis | description=description, |
519 | 2556cf45 | Giorgos Korfiatis | start_date=start_date, |
520 | 2556cf45 | Giorgos Korfiatis | end_date=end_date, |
521 | 2556cf45 | Giorgos Korfiatis | member_join_policy=join_policy, |
522 | 2556cf45 | Giorgos Korfiatis | member_leave_policy=leave_policy, |
523 | 2556cf45 | Giorgos Korfiatis | limit_on_members_number=max_members, |
524 | 62d30634 | Giorgos Korfiatis | private=private, |
525 | 2556cf45 | Giorgos Korfiatis | comments=comments, |
526 | 2556cf45 | Giorgos Korfiatis | resources=resources, |
527 | 2556cf45 | Giorgos Korfiatis | request_user=user) |
528 | 2556cf45 | Giorgos Korfiatis | |
529 | 2556cf45 | Giorgos Korfiatis | result = {"application": application.id,
|
530 | 88f5242e | Giorgos Korfiatis | "id": application.chain.uuid,
|
531 | 2556cf45 | Giorgos Korfiatis | } |
532 | 2556cf45 | Giorgos Korfiatis | return json_response(result, status_code=201) |
533 | 2556cf45 | Giorgos Korfiatis | |
534 | 2556cf45 | Giorgos Korfiatis | |
535 | 2556cf45 | Giorgos Korfiatis | def get_action(actions, input_data): |
536 | 2556cf45 | Giorgos Korfiatis | action = None
|
537 | 2556cf45 | Giorgos Korfiatis | data = None
|
538 | 2556cf45 | Giorgos Korfiatis | for option in actions.keys(): |
539 | 2556cf45 | Giorgos Korfiatis | if option in input_data: |
540 | 2556cf45 | Giorgos Korfiatis | if action:
|
541 | 2556cf45 | Giorgos Korfiatis | raise faults.BadRequest("Multiple actions not supported") |
542 | 2556cf45 | Giorgos Korfiatis | else:
|
543 | 2556cf45 | Giorgos Korfiatis | action = option |
544 | 2556cf45 | Giorgos Korfiatis | data = input_data[action] |
545 | 2556cf45 | Giorgos Korfiatis | if not action: |
546 | 2556cf45 | Giorgos Korfiatis | raise faults.BadRequest("No recognized action") |
547 | 2556cf45 | Giorgos Korfiatis | return actions[action], data
|
548 | 2556cf45 | Giorgos Korfiatis | |
549 | 2556cf45 | Giorgos Korfiatis | |
550 | 2556cf45 | Giorgos Korfiatis | PROJECT_ACTION = { |
551 | 2556cf45 | Giorgos Korfiatis | "terminate": functions.terminate,
|
552 | 2556cf45 | Giorgos Korfiatis | "suspend": functions.suspend,
|
553 | 2556cf45 | Giorgos Korfiatis | "unsuspend": functions.unsuspend,
|
554 | 2556cf45 | Giorgos Korfiatis | "reinstate": functions.reinstate,
|
555 | 2556cf45 | Giorgos Korfiatis | } |
556 | 2556cf45 | Giorgos Korfiatis | |
557 | 2556cf45 | Giorgos Korfiatis | |
558 | 2556cf45 | Giorgos Korfiatis | APPLICATION_ACTION = { |
559 | 2556cf45 | Giorgos Korfiatis | "approve": functions.approve_application,
|
560 | 362dadaa | Giorgos Korfiatis | "deny": functions.deny_application,
|
561 | 2556cf45 | Giorgos Korfiatis | "dismiss": functions.dismiss_application,
|
562 | 362dadaa | Giorgos Korfiatis | "cancel": functions.cancel_application,
|
563 | 2556cf45 | Giorgos Korfiatis | } |
564 | 2556cf45 | Giorgos Korfiatis | |
565 | 2556cf45 | Giorgos Korfiatis | |
566 | 362dadaa | Giorgos Korfiatis | PROJECT_ACTION.update(APPLICATION_ACTION) |
567 | 362dadaa | Giorgos Korfiatis | APP_ACTION_FUNCS = APPLICATION_ACTION.values() |
568 | 362dadaa | Giorgos Korfiatis | |
569 | 362dadaa | Giorgos Korfiatis | |
570 | 2556cf45 | Giorgos Korfiatis | @csrf_exempt
|
571 | 2556cf45 | Giorgos Korfiatis | @api.api_method(http_method="POST", token_required=True, user_required=False) |
572 | 2556cf45 | Giorgos Korfiatis | @user_from_token
|
573 | a3e3917f | Giorgos Korfiatis | @transaction.commit_on_success
|
574 | 362dadaa | Giorgos Korfiatis | def project_action(request, project_id): |
575 | 2556cf45 | Giorgos Korfiatis | user = request.user |
576 | b694875c | Christos Stavrakakis | data = request.body |
577 | 2556cf45 | Giorgos Korfiatis | input_data = json.loads(data) |
578 | 2556cf45 | Giorgos Korfiatis | |
579 | 362dadaa | Giorgos Korfiatis | func, action_data = get_action(PROJECT_ACTION, input_data) |
580 | 2556cf45 | Giorgos Korfiatis | with ExceptionHandler():
|
581 | 362dadaa | Giorgos Korfiatis | kwargs = {"request_user": user,
|
582 | 362dadaa | Giorgos Korfiatis | "reason": action_data.get("reason", ""), |
583 | 362dadaa | Giorgos Korfiatis | } |
584 | 362dadaa | Giorgos Korfiatis | if func in APP_ACTION_FUNCS: |
585 | 362dadaa | Giorgos Korfiatis | kwargs["application_id"] = action_data["app_id"] |
586 | 362dadaa | Giorgos Korfiatis | func(project_id=project_id, **kwargs) |
587 | 2556cf45 | Giorgos Korfiatis | return HttpResponse()
|
588 | 2556cf45 | Giorgos Korfiatis | |
589 | 2556cf45 | Giorgos Korfiatis | |
590 | 2556cf45 | Giorgos Korfiatis | @csrf_exempt
|
591 | 2556cf45 | Giorgos Korfiatis | def memberships(request): |
592 | 2556cf45 | Giorgos Korfiatis | method = request.method |
593 | 2556cf45 | Giorgos Korfiatis | if method == "GET": |
594 | 2556cf45 | Giorgos Korfiatis | return get_memberships(request)
|
595 | 2556cf45 | Giorgos Korfiatis | elif method == "POST": |
596 | 2556cf45 | Giorgos Korfiatis | return post_memberships(request)
|
597 | 2aba7764 | Sofia Papagiannaki | return api.api_method_not_allowed(request, allowed_methods=['GET', 'POST']) |
598 | 2556cf45 | Giorgos Korfiatis | |
599 | 2556cf45 | Giorgos Korfiatis | |
600 | 2556cf45 | Giorgos Korfiatis | def make_membership_query(input_data): |
601 | 2556cf45 | Giorgos Korfiatis | project_id = input_data.get("project")
|
602 | 2556cf45 | Giorgos Korfiatis | if project_id is not None: |
603 | 88f5242e | Giorgos Korfiatis | return Q(project__uuid=project_id)
|
604 | 2556cf45 | Giorgos Korfiatis | return Q()
|
605 | 2556cf45 | Giorgos Korfiatis | |
606 | 2556cf45 | Giorgos Korfiatis | |
607 | 2556cf45 | Giorgos Korfiatis | @api.api_method(http_method="GET", token_required=True, user_required=False) |
608 | 2556cf45 | Giorgos Korfiatis | @user_from_token
|
609 | a3e3917f | Giorgos Korfiatis | @transaction.commit_on_success
|
610 | 2556cf45 | Giorgos Korfiatis | def get_memberships(request): |
611 | 2556cf45 | Giorgos Korfiatis | user = request.user |
612 | 2556cf45 | Giorgos Korfiatis | input_data = read_json_body(request, default={}) |
613 | 2556cf45 | Giorgos Korfiatis | query = make_membership_query(input_data) |
614 | 2556cf45 | Giorgos Korfiatis | memberships = _get_memberships(query, request_user=user) |
615 | 2556cf45 | Giorgos Korfiatis | data = get_memberships_details(memberships, user) |
616 | 2556cf45 | Giorgos Korfiatis | return json_response(data)
|
617 | 2556cf45 | Giorgos Korfiatis | |
618 | 2556cf45 | Giorgos Korfiatis | |
619 | 2556cf45 | Giorgos Korfiatis | def _get_memberships(query, request_user=None): |
620 | 2556cf45 | Giorgos Korfiatis | memberships = ProjectMembership.objects |
621 | 2556cf45 | Giorgos Korfiatis | if not request_user.is_project_admin(): |
622 | 362dadaa | Giorgos Korfiatis | owned = Q(project__owner=request_user) |
623 | 2556cf45 | Giorgos Korfiatis | memb = Q(person=request_user) |
624 | 2556cf45 | Giorgos Korfiatis | memberships = memberships.filter(owned | memb) |
625 | 2556cf45 | Giorgos Korfiatis | |
626 | 2556cf45 | Giorgos Korfiatis | return memberships.select_related(
|
627 | 362dadaa | Giorgos Korfiatis | "project", "project__owner", "person").filter(query) |
628 | 2556cf45 | Giorgos Korfiatis | |
629 | 2556cf45 | Giorgos Korfiatis | |
630 | 2556cf45 | Giorgos Korfiatis | def join_project(data, request_user): |
631 | 2556cf45 | Giorgos Korfiatis | project_id = data.get("project")
|
632 | 2556cf45 | Giorgos Korfiatis | with ExceptionHandler():
|
633 | 2556cf45 | Giorgos Korfiatis | membership = functions.join_project(project_id, request_user) |
634 | 2556cf45 | Giorgos Korfiatis | response = {"id": membership.id}
|
635 | 2556cf45 | Giorgos Korfiatis | return json_response(response)
|
636 | 2556cf45 | Giorgos Korfiatis | |
637 | 2556cf45 | Giorgos Korfiatis | |
638 | 2556cf45 | Giorgos Korfiatis | def enroll_user(data, request_user): |
639 | 2556cf45 | Giorgos Korfiatis | project_id = data.get("project")
|
640 | 2556cf45 | Giorgos Korfiatis | email = data.get("user")
|
641 | 2556cf45 | Giorgos Korfiatis | with ExceptionHandler():
|
642 | 2556cf45 | Giorgos Korfiatis | m = functions.enroll_member_by_email( |
643 | 2556cf45 | Giorgos Korfiatis | project_id, email, request_user) |
644 | 2556cf45 | Giorgos Korfiatis | |
645 | 2556cf45 | Giorgos Korfiatis | response = {"id": m.id}
|
646 | 2556cf45 | Giorgos Korfiatis | return json_response(response)
|
647 | 2556cf45 | Giorgos Korfiatis | |
648 | 2556cf45 | Giorgos Korfiatis | |
649 | 2556cf45 | Giorgos Korfiatis | MEMBERSHIPS_ACTION = { |
650 | 2556cf45 | Giorgos Korfiatis | "join": join_project,
|
651 | 2556cf45 | Giorgos Korfiatis | "enroll": enroll_user,
|
652 | 2556cf45 | Giorgos Korfiatis | } |
653 | 2556cf45 | Giorgos Korfiatis | |
654 | 2556cf45 | Giorgos Korfiatis | |
655 | 2556cf45 | Giorgos Korfiatis | @api.api_method(http_method="POST", token_required=True, user_required=False) |
656 | 2556cf45 | Giorgos Korfiatis | @user_from_token
|
657 | a3e3917f | Giorgos Korfiatis | @transaction.commit_on_success
|
658 | 2556cf45 | Giorgos Korfiatis | def post_memberships(request): |
659 | 2556cf45 | Giorgos Korfiatis | user = request.user |
660 | b694875c | Christos Stavrakakis | data = request.body |
661 | 2556cf45 | Giorgos Korfiatis | input_data = json.loads(data) |
662 | 2556cf45 | Giorgos Korfiatis | func, action_data = get_action(MEMBERSHIPS_ACTION, input_data) |
663 | 2556cf45 | Giorgos Korfiatis | return func(action_data, user)
|
664 | 2556cf45 | Giorgos Korfiatis | |
665 | 2556cf45 | Giorgos Korfiatis | |
666 | 2556cf45 | Giorgos Korfiatis | @api.api_method(http_method="GET", token_required=True, user_required=False) |
667 | 2556cf45 | Giorgos Korfiatis | @user_from_token
|
668 | a3e3917f | Giorgos Korfiatis | @transaction.commit_on_success
|
669 | 2556cf45 | Giorgos Korfiatis | def membership(request, memb_id): |
670 | 2556cf45 | Giorgos Korfiatis | user = request.user |
671 | 2556cf45 | Giorgos Korfiatis | with ExceptionHandler():
|
672 | 2556cf45 | Giorgos Korfiatis | m = _get_membership(memb_id, request_user=user) |
673 | 2556cf45 | Giorgos Korfiatis | data = get_membership_details(m, user) |
674 | 2556cf45 | Giorgos Korfiatis | return json_response(data)
|
675 | 2556cf45 | Giorgos Korfiatis | |
676 | 2556cf45 | Giorgos Korfiatis | |
677 | 2556cf45 | Giorgos Korfiatis | def _get_membership(memb_id, request_user=None): |
678 | 2556cf45 | Giorgos Korfiatis | membership = functions.get_membership_by_id(memb_id) |
679 | 2556cf45 | Giorgos Korfiatis | functions.membership_check_allowed(membership, request_user) |
680 | 2556cf45 | Giorgos Korfiatis | return membership
|
681 | 2556cf45 | Giorgos Korfiatis | |
682 | 2556cf45 | Giorgos Korfiatis | |
683 | 2556cf45 | Giorgos Korfiatis | MEMBERSHIP_ACTION = { |
684 | 2556cf45 | Giorgos Korfiatis | "leave": functions.leave_project,
|
685 | 2556cf45 | Giorgos Korfiatis | "cancel": functions.cancel_membership,
|
686 | 2556cf45 | Giorgos Korfiatis | "accept": functions.accept_membership,
|
687 | 2556cf45 | Giorgos Korfiatis | "reject": functions.reject_membership,
|
688 | 2556cf45 | Giorgos Korfiatis | "remove": functions.remove_membership,
|
689 | 2556cf45 | Giorgos Korfiatis | } |
690 | 2556cf45 | Giorgos Korfiatis | |
691 | 2556cf45 | Giorgos Korfiatis | |
692 | 2556cf45 | Giorgos Korfiatis | @csrf_exempt
|
693 | 2556cf45 | Giorgos Korfiatis | @api.api_method(http_method="POST", token_required=True, user_required=False) |
694 | 2556cf45 | Giorgos Korfiatis | @user_from_token
|
695 | a3e3917f | Giorgos Korfiatis | @transaction.commit_on_success
|
696 | 2556cf45 | Giorgos Korfiatis | def membership_action(request, memb_id): |
697 | 2556cf45 | Giorgos Korfiatis | user = request.user |
698 | 2556cf45 | Giorgos Korfiatis | input_data = read_json_body(request, default={}) |
699 | 2556cf45 | Giorgos Korfiatis | func, action_data = get_action(MEMBERSHIP_ACTION, input_data) |
700 | 2556cf45 | Giorgos Korfiatis | with ExceptionHandler():
|
701 | 2556cf45 | Giorgos Korfiatis | func(memb_id, user, reason=action_data) |
702 | 2556cf45 | Giorgos Korfiatis | return HttpResponse() |