18 |
18 |
import hashlib
|
19 |
19 |
import inspect
|
20 |
20 |
import json
|
|
21 |
import re
|
21 |
22 |
|
22 |
23 |
from django.apps import apps
|
23 |
24 |
from django.conf.urls import url
|
24 |
25 |
from django.core.cache import cache
|
25 |
|
from django.core.exceptions import PermissionDenied
|
|
26 |
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
|
26 |
27 |
from django.contrib.auth import logout as auth_logout
|
27 |
28 |
from django.contrib.auth import views as auth_views
|
28 |
29 |
from django.db import transaction
|
29 |
30 |
from django.db.models import TextField
|
30 |
31 |
from django.db.models.functions import Cast
|
31 |
|
from django.http import HttpResponse, HttpResponseRedirect, Http404
|
|
32 |
from django.http import HttpResponse, HttpResponseRedirect, Http404, HttpResponseBadRequest
|
|
33 |
from django.http.response import HttpResponseBase
|
32 |
34 |
from django.views.decorators.csrf import csrf_exempt
|
33 |
35 |
from django.views.generic import (
|
34 |
36 |
RedirectView, View, TemplateView, CreateView, DeleteView, UpdateView,
|
... | ... | |
46 |
48 |
|
47 |
49 |
from dateutil import parser as date_parser
|
48 |
50 |
from jsonschema import validate, ValidationError
|
|
51 |
from requests import RequestException
|
49 |
52 |
|
50 |
53 |
from passerelle.base.models import BaseResource, ResourceLog
|
51 |
54 |
from passerelle.compat import json_loads
|
52 |
|
from passerelle.utils.jsonresponse import APIError
|
|
55 |
from passerelle.utils.conversion import exception_to_text
|
53 |
56 |
from passerelle.utils.json import unflatten
|
|
57 |
from passerelle.utils.jsonresponse import APIError
|
|
58 |
from passerelle.utils.jsonresponse import CALLBACK_NAME
|
|
59 |
from passerelle.utils.jsonresponse import DEFAULT_DEBUG
|
|
60 |
from passerelle.utils.jsonresponse import JSONEncoder
|
54 |
61 |
|
55 |
|
from .utils import to_json, is_authorized
|
|
62 |
from .utils import is_authorized
|
56 |
63 |
from .forms import GenericConnectorForm
|
57 |
64 |
|
58 |
65 |
if 'mellon' in settings.INSTALLED_APPS:
|
... | ... | |
75 |
82 |
+ quote(request.GET.get('next')))
|
76 |
83 |
return super(LoginView, self).dispatch(request, *args, **kwargs)
|
77 |
84 |
|
|
85 |
|
78 |
86 |
login = LoginView.as_view()
|
79 |
87 |
|
80 |
88 |
|
... | ... | |
305 |
313 |
def __str__(self):
|
306 |
314 |
return 'invalid value for parameter "%s"' % self.parameter_name
|
307 |
315 |
|
|
316 |
|
308 |
317 |
IGNORED_PARAMS = ('apikey', 'signature', 'nonce', 'algo', 'timestamp', 'orig', 'jsonpCallback',
|
309 |
318 |
'callback', '_', 'raise', 'debug', 'decode', 'format')
|
310 |
319 |
|
... | ... | |
469 |
478 |
cache.set(cache_key, result, self.endpoint.endpoint_info.cache_duration)
|
470 |
479 |
return result
|
471 |
480 |
|
|
481 |
def _obj_to_response(self, req, obj):
|
|
482 |
if isinstance(obj, dict) and 'err' not in obj:
|
|
483 |
obj['err'] = 0
|
|
484 |
return obj
|
|
485 |
|
|
486 |
def _err_to_response(self, err):
|
|
487 |
if hasattr(err, "__module__"):
|
|
488 |
err_module = err.__module__ + "."
|
|
489 |
else:
|
|
490 |
err_module = ""
|
|
491 |
|
|
492 |
if hasattr(err, "owner"):
|
|
493 |
err_module += err.owner.__name__ + "."
|
|
494 |
|
|
495 |
err_class = err_module + err.__class__.__name__
|
|
496 |
|
|
497 |
err_desc = force_text(err)
|
|
498 |
|
|
499 |
return {
|
|
500 |
"err": 1,
|
|
501 |
"err_class": err_class,
|
|
502 |
"err_desc": err_desc,
|
|
503 |
"data": getattr(err, 'data', None),
|
|
504 |
}
|
|
505 |
|
|
506 |
def _render_data(self, req, data, status=200):
|
|
507 |
debug = DEFAULT_DEBUG
|
|
508 |
debug = debug or req.GET.get('debug', 'false').lower() in ('true', 't', '1', 'on')
|
|
509 |
debug = debug or req.GET.get('decode', '0').lower() in ('true', 't', '1', 'on')
|
|
510 |
if 'callback' in req.GET or 'jsonpCallback' in req.GET:
|
|
511 |
output_format = req.GET.get('format', 'jsonp')
|
|
512 |
else:
|
|
513 |
output_format = req.GET.get('format', 'json')
|
|
514 |
jsonp_cb = req.GET.get('callback') or req.GET.get('jsonpCallback') or CALLBACK_NAME
|
|
515 |
if not re.match(r'^[$a-zA-Z_][a-zA-Z0-9_]*$', jsonp_cb):
|
|
516 |
return HttpResponseBadRequest('invalid JSONP callback name')
|
|
517 |
content_type = "application/json"
|
|
518 |
|
|
519 |
kwargs = {'cls': JSONEncoder}
|
|
520 |
if debug:
|
|
521 |
kwargs["indent"] = 4
|
|
522 |
kwargs["ensure_ascii"] = False
|
|
523 |
kwargs["encoding"] = "utf8"
|
|
524 |
|
|
525 |
plain = json.dumps(data, **kwargs)
|
|
526 |
if output_format == 'jsonp':
|
|
527 |
plain = "%s(%s);" % (jsonp_cb, plain)
|
|
528 |
content_type = "application/javascript"
|
|
529 |
|
|
530 |
return HttpResponse(plain, content_type="%s; charset=UTF-8" % content_type, status=status)
|
|
531 |
|
472 |
532 |
def get(self, request, *args, **kwargs):
|
473 |
533 |
if self.endpoint.endpoint_info.pattern:
|
474 |
534 |
pattern = url(self.endpoint.endpoint_info.pattern, self.endpoint)
|
... | ... | |
478 |
538 |
kwargs['other_params'] = match.kwargs
|
479 |
539 |
elif kwargs.get('rest'):
|
480 |
540 |
raise Http404()
|
|
541 |
|
481 |
542 |
connector = self.get_object()
|
482 |
|
return to_json(logger=connector.logger)(self.perform)(request, *args, **kwargs)
|
|
543 |
|
|
544 |
try:
|
|
545 |
resp = self.perform(request, *args, **kwargs)
|
|
546 |
if isinstance(resp, HttpResponseBase):
|
|
547 |
return resp
|
|
548 |
|
|
549 |
data = self._obj_to_response(request, resp)
|
|
550 |
status = 200
|
|
551 |
except Exception as e:
|
|
552 |
extras = {'method': request.method, 'exception': exception_to_text(e), 'request': request}
|
|
553 |
if request.method == 'POST':
|
|
554 |
max_size = connector.logging_parameters.requests_max_size
|
|
555 |
extras.update({'body': repr(request.body[:max_size])})
|
|
556 |
if (not isinstance(e, (Http404, PermissionDenied, ObjectDoesNotExist, RequestException))
|
|
557 |
and getattr(e, 'log_error', True)):
|
|
558 |
connector.logger.exception("Error occurred while processing request", extra=extras)
|
|
559 |
elif isinstance(e, APIError):
|
|
560 |
connector.logger.warning("Error occurred while processing request", extra=extras)
|
|
561 |
|
|
562 |
if int(request.GET.get('raise', 0)):
|
|
563 |
raise
|
|
564 |
|
|
565 |
data = self._err_to_response(e)
|
|
566 |
if getattr(e, 'err_code', None):
|
|
567 |
data['err'] = e.err_code
|
|
568 |
if getattr(e, 'http_status', None):
|
|
569 |
status = e.http_status
|
|
570 |
elif isinstance(e, (ObjectDoesNotExist, Http404)):
|
|
571 |
status = 404
|
|
572 |
elif isinstance(e, PermissionDenied):
|
|
573 |
status = 403
|
|
574 |
else:
|
|
575 |
status = 500
|
|
576 |
|
|
577 |
return self._render_data(request, data, status)
|
483 |
578 |
|
484 |
579 |
def post(self, request, *args, **kwargs):
|
485 |
580 |
return self.get(request, *args, **kwargs)
|