forked from conwetlab/wstore
-
Notifications
You must be signed in to change notification settings - Fork 0
/
views.py
318 lines (244 loc) · 10.5 KB
/
views.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
# -*- coding: utf-8 -*-
# Copyright (c) 2013 CoNWeT Lab., Universidad Politécnica de Madrid
# This file is part of WStore.
# WStore is free software: you can redistribute it and/or modify
# it under the terms of the European Union Public Licence (EUPL)
# as published by the European Commission, either version 1.1
# of the License, or (at your option) any later version.
# WStore is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# European Union Public Licence for more details.
# You should have received a copy of the European Union Public Licence
# along with WStore.
# If not, see <https://joinup.ec.europa.eu/software/page/eupl/licence-eupl>.
import os
import json
import smtplib
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from django.conf import settings
from django.utils.encoding import smart_str
from django.views.static import serve
from django.contrib.auth.models import User
from django.http import HttpResponse
from django.utils.safestring import mark_safe
from store_commons.utils.http import build_response, authentication_required, \
supported_request_mime_types
from wstore.store_commons.resource import Resource as API_Resource
from wstore.models import UserProfile, Organization
from wstore.models import Purchase, Resource, Offering
from wstore.offerings.offerings_management import get_offering_info
MAIN_PORTAL_URL = "http://help.lab.fi-ware.org/"
CLOUD_PORTAL_URL = "http://cloud.lab.fi-ware.org/"
MASHUP_PORTAL_URL = "http://mashup.lab.fi-ware.org/"
ACCOUNT_PORTAL_URL = "https://account.lab.fi-ware.org/"
DATA_PORTAL_URL = "https://data.lab.fi-ware.org/"
def _load_home_context(request):
context = {
'organization': request.user.userprofile.current_organization.name,
'oil': settings.OILAUTH,
'portal': settings.PORTALINSTANCE
}
# Include Portals URLs if needed
if settings.PORTALINSTANCE:
context['main'] = MAIN_PORTAL_URL
context['cloud'] = CLOUD_PORTAL_URL
context['mashup'] = MASHUP_PORTAL_URL
context['account'] = ACCOUNT_PORTAL_URL
context['data'] = DATA_PORTAL_URL
return context
@login_required
def home(request):
context = _load_home_context(request)
context['loader'] = 'home'
return render(request, 'index.html', context)
@login_required
def home_search(request):
context = _load_home_context(request)
context['loader'] = 'offerings'
return render(request, 'index.html', context)
@login_required
def home_search_text(request, keyword):
context = _load_home_context(request)
context['loader'] = 'keyword'
context['info'] = mark_safe(keyword)
return render(request, 'index.html', context)
@login_required
def home_search_tag(request, tag):
context = _load_home_context(request)
context['loader'] = 'tag'
context['info'] = tag
return render(request, 'index.html', context)
@login_required
def home_details(request, org, name, version):
context = _load_home_context(request)
context['loader'] = 'details'
try:
owner_org = Organization.objects.get(name=org)
offering = Offering.objects.get(owner_organization=owner_org, name=name, version=version)
offering_info = get_offering_info(offering, request.user)
except:
return build_response(request, 404, 'Not found')
context['info'] = mark_safe(json.dumps(offering_info))
return render(request, 'index.html', context)
@login_required
def home_search_resource(request, org, name, version):
context = _load_home_context(request)
context['loader'] = 'resource'
context['info'] = mark_safe(json.dumps({
'org': org,
'name': name,
'version': version
}))
return render(request, 'index.html', context)
@login_required
def admin(request):
if request.user.is_staff:
context = {
'oil': settings.OILAUTH,
'portal': settings.PORTALINSTANCE
}
# Include Portals URLs if needed
if settings.PORTALINSTANCE:
context['main'] = MAIN_PORTAL_URL
context['cloud'] = CLOUD_PORTAL_URL
context['mashup'] = MASHUP_PORTAL_URL
context['account'] = ACCOUNT_PORTAL_URL
context['data'] = DATA_PORTAL_URL
return render(request, 'admin/admin.html', context)
else:
return build_response(request, 403, 'Forbidden')
@login_required
def catalogue(request):
profile = UserProfile.objects.get(user=request.user)
context = {
'roles': profile.get_current_roles(),
'usdl_editor': settings.USDL_EDITOR_URL,
'organization': profile.current_organization.name,
'oil': settings.OILAUTH,
'portal': settings.PORTALINSTANCE
}
# Include Portals URLs if needed
if settings.PORTALINSTANCE:
context['main'] = MAIN_PORTAL_URL
context['cloud'] = CLOUD_PORTAL_URL
context['mashup'] = MASHUP_PORTAL_URL
context['account'] = ACCOUNT_PORTAL_URL
context['data'] = DATA_PORTAL_URL
return render(request, 'catalogue/catalogue.html', context)
@login_required
def organization(request):
if not settings.OILAUTH:
profile = UserProfile.objects.get(user=request.user)
context = {
'roles': profile.get_current_roles(),
'organization': profile.current_organization.name,
'oil': settings.OILAUTH,
'portal': settings.PORTALINSTANCE
}
# Include Portals URLs if needed
if settings.PORTALINSTANCE:
context['main'] = MAIN_PORTAL_URL
context['cloud'] = CLOUD_PORTAL_URL
context['mashup'] = MASHUP_PORTAL_URL
context['account'] = ACCOUNT_PORTAL_URL
context['data'] = DATA_PORTAL_URL
return render(request, 'organizations/organization_template.html', context)
else:
return build_response(request, 403, 'This view is not enabled with iDM auth')
class ProviderRequest(API_Resource):
@authentication_required
@supported_request_mime_types(('application/json',))
def create(self, request):
# Get user info
try:
data = json.loads(request.raw_post_data)
if not 'username' in data or not 'message' in data:
raise Exception('')
except:
return build_response(request, 400, 'Invalid Json content')
try:
user = User.objects.get(username=data['username'])
except:
return build_response(request, 400, 'Invalid user')
try:
# Send email
fromaddr = settings.WSTOREMAIL
toaddrs = settings.WSTOREPROVIDERREQUEST
msg = 'Subject: Provider request: ' + user.username + '\n'
msg += user.userprofile.complete_name + '\n'
msg += data['message']
# Credentials (if needed)
username = settings.WSTOREMAILUSER
password = settings.WSTOREMAILPASS
# The mail is sent
server = smtplib.SMTP('smtp.gmail.com:587')
server.starttls()
server.login(username, password)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()
except:
return build_response(request, 400, 'Problem sending the email')
user.userprofile.provider_requested = True
user.userprofile.save()
return build_response(request, 200, 'OK')
class ServeMedia(API_Resource):
def read(self, request, path, name):
if request.method != 'GET':
return build_response(request, 415, 'Method not supported')
dir_path = os.path.join(settings.MEDIA_ROOT, path)
# Protect the resources from not authorized downloads
if dir_path.endswith('resources') :
if request.user.is_anonymous():
return build_response(request, 401, 'Unauthorized')
# Check if the request user has access to the resource
splited_name = name.split('__')
prov = Organization.objects.get(name=splited_name[0])
resource = Resource.objects.get(provider=prov, name=splited_name[1], version=splited_name[2])
if not resource.open:
user_profile = UserProfile.objects.get(user=request.user)
found = False
# Check if the user has purchased an offering with the resource
# only if the offering is not open
for off in user_profile.offerings_purchased:
o = Offering.objects.get(pk=off)
for res in o.resources:
if str(res) == resource.pk:
found = True
break
if found:
break
if not found:
# Check if the user organization has an offering with the resource
for off in user_profile.current_organization.offerings_purchased:
o = Offering.objects.get(pk=off)
for res in o.resources:
if str(res) == resource.pk:
found = True
break
if found:
break
if not found:
return build_response(request, 404, 'Not found')
if dir_path.endswith('bills'):
if request.user.is_anonymous():
return build_response(request, 401, 'Unauthorized')
user_profile = UserProfile.objects.get(user=request.user)
purchase = Purchase.objects.get(ref=name[:24])
if purchase.organization_owned:
user_org = user_profile.current_organization
if not purchase.owner_organization.name == user_org.name:
return build_response(request, 404, 'Not found')
else:
if not purchase.customer == request.user:
return build_response(request, 404, 'Not found')
local_path = os.path.join(dir_path, name)
if not os.path.isfile(local_path):
return build_response(request, 404, 'Not found')
if not getattr(settings, 'USE_XSENDFILE', False):
return serve(request, local_path, document_root='/')
else:
response = HttpResponse()
response['X-Sendfile'] = smart_str(local_path)
return response