legacy/pairent_backend/pairent_app/views.py

290 lines
12 KiB
Python
Raw Normal View History

from rest_framework import viewsets
2023-05-07 11:48:53 +02:00
from rest_framework.response import Response
2023-05-11 01:52:32 +02:00
from rest_framework.views import APIView, View
from rest_framework.request import Request
2023-05-16 08:24:22 +02:00
from django.views.decorators.csrf import csrf_exempt
2023-05-11 01:52:32 +02:00
2023-05-16 09:42:44 +02:00
from django.http import HttpResponseBadRequest, HttpResponse, JsonResponse, HttpRequest
2023-05-15 06:54:30 +02:00
from django.db.models.query import QuerySet
from django.core.validators import validate_email
from django.core.exceptions import ValidationError
from .models import Apartament, User, PsychTestAnswers
from .serializer import (ApartamentListSerializer,
ApartamentDetailSerializer,
2023-05-15 05:12:05 +02:00
PsychTestAddResultSerializer,
2023-05-15 06:54:30 +02:00
PublicUserSerializer)
2023-05-01 12:39:34 +02:00
2023-05-16 11:35:20 +02:00
import json, math, random, re, requests, oidc_client, base64, hashlib
2023-05-01 12:39:34 +02:00
class ApartamentViewSet(viewsets.ReadOnlyModelViewSet):
"""Вывод списка квартир или отдельной квартиры"""
2023-05-01 12:39:34 +02:00
def get_queryset(self):
2023-05-01 12:39:34 +02:00
apartaments = Apartament.objects.all()
return apartaments
def get_serializer_class(self):
if self.action == 'list':
return ApartamentListSerializer
elif self.action == "retrieve":
2023-05-07 11:48:53 +02:00
return ApartamentDetailSerializer
class ApartamentGetManyViewSet(viewsets.ReadOnlyModelViewSet):
2023-05-07 11:48:53 +02:00
"""Вывод отдельных квартир для сравнения"""
2023-05-09 13:03:37 +02:00
def get_queryset(self): # получение id квартир для избранного или сравнения
2023-05-09 10:32:18 +02:00
pk = self.request.query_params.get("pk", None) # получение id пользователя
if self.action == "retrieve": # если для страницы сравнения
apartaments_id = User.objects.get(pk=pk).apartaments_for_comparison.split(',') # получение id квартир
elif self.action == "list": # если для страницы избранного
apartaments_id = User.objects.get(pk=pk).favorites_apartaments.split(',') # получение id квартир
2023-05-09 13:03:37 +02:00
queryset = []
for i in apartaments_id:
queryset.append(Apartament.objects.get(pk=i))
return queryset
2023-05-09 10:32:18 +02:00
2023-05-09 11:05:47 +02:00
def retrieve(self, request, *args, **kwargs):
2023-05-09 13:03:37 +02:00
queryset = self.get_queryset()
2023-05-09 11:05:47 +02:00
apartaments = []
2023-05-09 13:03:37 +02:00
for i in queryset:
apartaments.append(ApartamentDetailSerializer(i).data)
return Response({'results': apartaments})
def list(self, request, *args, **kwargs):
queryset = self.get_queryset()
apartaments = []
for i in queryset:
apartaments.append(ApartamentListSerializer(i).data)
2023-05-09 11:05:47 +02:00
return Response({'results': apartaments})
2023-05-11 01:52:32 +02:00
2023-05-11 01:52:32 +02:00
class ApartmentFilter(viewsets.ViewSet):
"""Вывод списка квартир или отдельной квартиры"""
def list(self, req: Request):
filters = dict(req.data);
2023-05-11 15:11:38 +02:00
unfiltered = Apartament.objects.all();
2023-05-11 01:52:32 +02:00
filtered = [];
2023-05-11 15:11:38 +02:00
# TODO: Some better converting practice?
filters['price_range']['from'] = int(filters['price_range']['from']);
filters['price_range']['to'] = int(filters['price_range']['to']);
filters['area_range']['from'] = int(filters['area_range']['from']);
filters['area_range']['to'] = int(filters['area_range']['to']);
filters['rooms'] = int(filters['rooms'])
2023-05-11 01:52:32 +02:00
for entry in unfiltered:
2023-05-11 15:11:38 +02:00
if (filters['price_range']['from'] >= entry.price and (filters['price_range']['to'] != -1 and filters['price_range']['to'] <= entry.price)):
2023-05-11 01:52:32 +02:00
continue;
2023-05-11 15:11:38 +02:00
if (filters['area_range']['from'] >= entry.perimetrs and (filters['area_range']['to'] != -1 and filters['area_range']['to'] <= entry.perimetrs)):
2023-05-11 01:52:32 +02:00
continue;
2023-05-11 15:11:38 +02:00
if (filters['rooms'] != -1 and entry.rooms != filters['rooms']):
2023-05-11 01:52:32 +02:00
continue;
filtered.append(entry);
return Response(ApartamentListSerializer(filtered, many=True).data);
class PsychTestAddResultViewSet(viewsets.ViewSet):
2023-05-12 15:01:55 +02:00
def get_object(self, pk):
return User.objects.get(pk=pk)
def create(self, request, pk):
2023-05-12 15:01:55 +02:00
user = self.get_object(pk)
results = request.data
PsychTestAnswers.objects.create(
user=user,
first_question=results['first'],
second_question=results['second'],
third_question=results['third'],
fourth_question=results['fourth'],
fifth_question=results['fifth'],
sixth_question=results['sixth'],
seventh_question=results['seventh'],
eighth_question=results['eighth'],
nineth_question=results['nineth'],
tenth_question=results['tenth'],
eleventh_question=results['eleventh'],
twelfth_question=results['twelfth'],
thirteenth_question=results['thirteenth']
)
return Response({'successfully': 'results post'})
2023-05-15 05:12:05 +02:00
class CompatibleUsersView(viewsets.ViewSet):
def list(self, req: Request):
user_data = dict(req.data);
2023-05-15 06:54:30 +02:00
# TODO: Verify auth
vvsu_login = user_data['openid'];
# Exclude already viewed users
exclude = [];
if ('exclude' in user_data.keys()):
exclude = user_data['exclude'];
try:
validate_email(vvsu_login);
except ValidationError:
return Request({'error': 'bad login'}, 400);
try:
this_user = User.objects.get(openid_addr=vvsu_login);
except User.DoesNotExist:
return Response({'error': 'user not found'}, 404);
score = this_user.psych_test_result;
users_query = User.objects.all();
users = [];
for user in users_query:
if (abs(user.psych_test_result - score) < 20):
users.append(PublicUserSerializer(user).data);
random.shuffle(users);
users = users[:7];
for i in range(3):
users.append(PublicUserSerializer(random.choice(users_query)).data);
random.shuffle(users);
2023-05-15 13:01:57 +02:00
return Response(users);
def VVSUAuthProxy(req: Request):
proxy = 'https://vvsu.ru/connect' + req.path[len('/api/auth/vvsu'):];
preq = requests.request(req.method, proxy, headers={
'User-Agent': 'OIDC Client / Pairent',
'Origin': 'http://pairent.vvsu.ru',
'Referer': 'http://pairent.vvsu.ru'
});
resp = HttpResponse(preq.content);
resp.headers['Content-Type'] = preq.headers['Content-Type'];
2023-05-16 08:24:22 +02:00
return resp;
def regiserUser(oid, provider_id, name, date_of_birth):
user = User(
favorites_apartments='',
comparison_apartments='',
name=name,
date_of_birth=date_of_birth,
about_me='',
gender='?',
phone='+00000',
# email=,
# telegram=,
# discord=,
# city=,
role='s',
# photo_provider=,
openid_addr=oid,
openid_id=provider_id,
)
def get_oauth_token(remote, data):
return requests.post(remote + '/oauth2/token', data,
headers={
'Origin': 'https://pairent.vvsu.ru',
'Referer': 'https://pairent.vvsu.ru'
}).json();
def get_oauth_data(remote, key):
return requests.get(remote + '/userinfo', headers={
'Origin': 'https://pairent.vvsu.ru',
'Authorization': 'Bearer ' + key,
'User-Agent': 'curl/8.1'
}).json();
2023-05-16 09:42:44 +02:00
class UserLogin(APIView):
# TODO: Remove csrf exempt when index.html is loaded through django
@csrf_exempt
def post(self, req: HttpRequest):
2023-05-16 11:35:20 +02:00
if (req.session.has_key('auth_data')):
# TODO: Return user object instead of error
return JsonResponse({'error': 'already authenticated'})
2023-05-16 09:42:44 +02:00
if (req.content_type != 'application/json'):
res = HttpResponse({'error': 'bad content type'});
res.status_code = 400;
return res;
2023-05-16 11:35:20 +02:00
2023-05-16 09:42:44 +02:00
data = json.loads(req.body.decode('utf8'));
2023-05-16 11:35:20 +02:00
if not ('code' in data and 'code_verifier' in data):
res = JsonResponse({'error': 'no code'});
res.status_code = 400;
return res;
2023-05-16 11:35:20 +02:00
# auth_data = get_oauth_token('https://vvsu.ru/connect', {
# 'grant_type': 'authorization_code',
# 'redirect_uri': 'https://pairent.vvsu.ru/sign-in/',
# 'code': data['code'],
# 'code_verifier': data['code_verifier'],
# 'client_id': 'it-hub-client',
# 'client_secret': 'U8y@uPVee6Q^*729esHTo4Vd'
# });
auth_data = {'access_token': '5kHvrjy91LJgJLKitejBBG24c7JiX45tEstKVHRpfHc._WQDwQ2F13aytbGFjlGnjXJeUWcDD1V3om3cRW0IujM', 'expires_in': 3600, 'id_token': 'eyJhbGciOiJSUzI1NiIsImtpZCI6InB1YmxpYzpoeWRyYS5vcGVuaWQuaWQtdG9rZW4iLCJ0eXAiOiJKV1QifQ.eyJhY3IiOiIwIiwiYXRfaGFzaCI6IjRMR1dRekxVaXFodUVTYjU0QWFIM0EiLCJhdWQiOlsiaXQtaHViLWNsaWVudCJdLCJhdXRoX3RpbWUiOjE2ODQyMzc4MDksImNhbGxiYWNrX3VybCI6IiIsImV4cCI6MTY4NDI0MTQ1NSwiZmFtaWx5X25hbWUiOiLQn9GD0YHRgtC-0LLQsNC70L7QsiIsImdpdmVuX25hbWUiOiLQndC40LrQuNGC0LAiLCJpYXQiOjE2ODQyMzc4NTUsImlkIjoiMDk2Qzc4Q0QtNDk0My00RDU3LUJDNkQtNUNERTEyRjY4NkUzIiwiaXNzIjoiaHR0cHM6Ly93d3cudnZzdS5ydS9jb25uZWN0LyIsImp0aSI6IjEzMTBhNzcwLWFhZWUtNGExYS1hMTc1LWM3MzY3ZWM0ZjVhNyIsImxvZ2luIjoiaHR0cHM6Ly9vcGVuaWQudnZzdS5ydS9ibGVrX18iLCJvcGVuaWQiOiJodHRwczovL29wZW5pZC52dnN1LnJ1L2JsZWtfXyIsInBpY3R1cmUiOiJodHRwczovL3d3dy52dnN1LnJ1L29pc2twL3Bob3RvL3B0aC5hc3A_SUQ9MDk2Qzc4Q0QtNDk0My00RDU3LUJDNkQtNUNERTEyRjY4NkUzXHUwMDI2IiwicHJvZmlsZV91cmwiOm51bGwsInJhdCI6MTY4NDIzNzc5Nywic2lkIjoiOTYyYzg0OGYtZThkNS00ZDJjLWEwZmEtYjI5YmU3YjBlODAxIiwic3ViIjoiaHR0cHM6Ly9vcGVuaWQudnZzdS5ydS9ibGVrX18iLCJzdXJuYW1lIjoi0J_Rg9GB0YLQvtCy0LDQu9C-0LIiLCJ0aXRsZSI6ItCh0YLRg9C00LXQvdGCIiwidnZzdV9JZEVtcGwiOm51bGwsInZ2c3VfSWRTdHVkIjoiMTk3MDgwIiwidnZzdV9JZFVzZXIiOjE5MDQ4OSwidnZzdV9sb2dpbiI6ImJsZWtfXyJ9.A4BiOxpOqnesSiTGRdcTsC-lGhSABswivpUovD9EOdYmqKW753VlLcXQxfBPcfmq8Fdf7RmVvXTXPXYqkX7AKxQT-yUUm7XtJHCb85g2YfL64cjTP2sFYD6wPIU9nzXbCrsgKqKubY3p16Dn9VyrBCXE9N6jdbuNOFbWMLPLPlp7U5fx2SzVGaBMUONlTf8KiLkcisQoN4c_rPGqdi38gzhLf7WGEiKLOldXH1q-s_kPeObFvcdbsFrrnDPnJtdqBx8SF02wqJsrZlBiB9Hl-d6sSJYLZZWumFhS-qscfwRlTEZKqC-hWF5c9R8CUYewk89JxRvCcKrHZvPMip9j9vJF1_OjkSrC5EkGaprl765FgVPEBJqXj9LjGRkTOYfYUFAAMia_HhjtinQFp6XJ-Rh3JrmIfLAQ7DEUSOldMQ1xUw9GeHo_0sIsnjaM6lVx6M_SiDTWihxNu58DiI8tmvkdw7in95OJRoJZ30EhR3SGYsK3b51qdYK1aieufJHX40bN_S1gc84pisTg58z-zC5kGsjsZNv6gRSTO4oOpZMK1FMjv7HyasSMWEu-J052X4Qxquj4pWglpiGQNt3-E0jZUUjqmZ0-7AYiyEC_3IItBqWrve-LTXRF5faIZB5v3F3urY6Qjgn93m_AoK1oujfNAPk8WOLTv419CuC2fAc', 'scope': 'openid vvsu_IdUser vvsu_IdEmpl vvsu_IdStud vvsu_login given_name family_name', 'token_type': 'bearer'}
2023-05-16 09:42:44 +02:00
user = None;
new_user = False;
print(auth_data);
2023-05-16 09:42:44 +02:00
return JsonResponse(get_oauth_data('https://vvsu.ru/connect', auth_data['access_token']));
2023-05-16 11:35:20 +02:00
req.session['auth_data'] = vvsu_data;
2023-05-16 11:35:20 +02:00
if ('error' in vvsu_data):
res = JsonResponse(vvsu_data);
res.status_code = cb.status_code;
return res
2023-05-16 09:42:44 +02:00
vvsu_data['vvsu_login'] += '@vvsu.ru';
try:
user = User.objects.get(openid_addr=vvsu_data['vvsu_login']);
except User.DoesNotExist:
registerUser(vvsu_data['vvsu_login'], cb.id, f'{cb.given_name} {cb.family_name}');
user = User.objects.get(openid_addr=vvsu_data['vvsu_login']);
new_user = True;
return JsonResponse({
'user_data': user,
'new_user': new_user
});
2023-05-16 12:07:50 +02:00
class UserGet(APIView):
def get(self, req: HttpRequest):
if not ('id' in req.GET.keys() or 'login' in req.GET.keys()):
res = JsonResponse({'error': 'no id or login'});
res.status_code = 400;
return res;
id_type = 'id' if 'id' in req.GET.keys() else 'login';
id = req.GET.get(id_type);
if (id_type == 'login'):
if not id.endswith('@vvsu.ru'):
id += '@vvsu.ru';
id_type = 'openid_addr';
user = None;
try:
user = User.objects.get(**{id_type: id});
except User.DoesNotExist:
res = JsonResponse({'error': 'not found'});
res.status_code = 404;
return res;
return JsonResponse(PublicUserSerializer(user).data);