add vvsu auth (still needs work)
This commit is contained in:
parent
1702a2f0d8
commit
35d7148c95
|
@ -1,4 +1,5 @@
|
||||||
from django.urls import path
|
from django.urls import path, re_path
|
||||||
|
# from django.conf.urls import url
|
||||||
from rest_framework.urlpatterns import format_suffix_patterns
|
from rest_framework.urlpatterns import format_suffix_patterns
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
|
@ -10,5 +11,6 @@ urlpatterns = format_suffix_patterns([
|
||||||
path("apartaments/favorite/", views.ApartamentGetManyViewSet.as_view({'get': 'list'})), # пример: apartaments/favorite/?user_id=1 user_id - id пользователя
|
path("apartaments/favorite/", views.ApartamentGetManyViewSet.as_view({'get': 'list'})), # пример: apartaments/favorite/?user_id=1 user_id - id пользователя
|
||||||
path("apartaments/filters/", views.ApartmentFilter.as_view({'post': 'list'})),
|
path("apartaments/filters/", views.ApartmentFilter.as_view({'post': 'list'})),
|
||||||
path("psych_test/add_result/<int:pk>", views.PsychTestAddResultViewSet.as_view({'patch': 'update'})), # пример: psych_test/add_result/1/?result=50 result - результат псих теста пользователя
|
path("psych_test/add_result/<int:pk>", views.PsychTestAddResultViewSet.as_view({'patch': 'update'})), # пример: psych_test/add_result/1/?result=50 result - результат псих теста пользователя
|
||||||
path("users/get_compatible", views.CompatibleUsersView.as_view({'post': 'list'}))
|
path("users/get_compatible", views.CompatibleUsersView.as_view({'post': 'list'})),
|
||||||
|
re_path(r'^auth/vvsu/', views.VVSUAuthProxy),
|
||||||
])
|
])
|
||||||
|
|
|
@ -3,7 +3,7 @@ from rest_framework.response import Response
|
||||||
from rest_framework.views import APIView, View
|
from rest_framework.views import APIView, View
|
||||||
from rest_framework.request import Request
|
from rest_framework.request import Request
|
||||||
|
|
||||||
from django.http import HttpResponseBadRequest
|
from django.http import HttpResponseBadRequest, HttpResponse
|
||||||
from django.db.models.query import QuerySet
|
from django.db.models.query import QuerySet
|
||||||
|
|
||||||
from django.core.validators import validate_email
|
from django.core.validators import validate_email
|
||||||
|
@ -15,7 +15,7 @@ from .serializer import (ApartamentListSerializer,
|
||||||
PsychTestAddResultSerializer,
|
PsychTestAddResultSerializer,
|
||||||
PublicUserSerializer)
|
PublicUserSerializer)
|
||||||
|
|
||||||
import json, math, random, re
|
import json, math, random, re, requests
|
||||||
|
|
||||||
class ApartamentViewSet(viewsets.ReadOnlyModelViewSet):
|
class ApartamentViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Вывод списка квартир или отдельной квартиры"""
|
"""Вывод списка квартир или отдельной квартиры"""
|
||||||
|
@ -138,3 +138,17 @@ class CompatibleUsersView(viewsets.ViewSet):
|
||||||
random.shuffle(users);
|
random.shuffle(users);
|
||||||
|
|
||||||
return Response(users);
|
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'];
|
||||||
|
|
||||||
|
return resp;
|
|
@ -3,3 +3,4 @@ django
|
||||||
djangorestframework
|
djangorestframework
|
||||||
django-cors-headers
|
django-cors-headers
|
||||||
Pillow
|
Pillow
|
||||||
|
requests
|
|
@ -0,0 +1,34 @@
|
||||||
|
import { styled } from "styled-components";
|
||||||
|
|
||||||
|
const BlueButton = styled.button`
|
||||||
|
background: white;
|
||||||
|
border: 2px solid royalblue;
|
||||||
|
border-radius: 12px;
|
||||||
|
color: royalblue;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 20px;
|
||||||
|
transition: 150ms ease;
|
||||||
|
width: 100%;
|
||||||
|
font-size: 10.5pt;
|
||||||
|
height: 36px;
|
||||||
|
padding: 6px 10px;
|
||||||
|
clip-path: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
& svg {
|
||||||
|
fill: royalblue;
|
||||||
|
margin: 0;
|
||||||
|
margin-right: 6px;
|
||||||
|
transform: translateY(2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: white;
|
||||||
|
background: royalblue;
|
||||||
|
}
|
||||||
|
&:hover svg {
|
||||||
|
fill: white
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default BlueButton;
|
|
@ -0,0 +1 @@
|
||||||
|
// TODO: Make a logged in handler
|
|
@ -0,0 +1,130 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { styled } from 'styled-components';
|
||||||
|
import BlueButton from '../../components/UI/BlueButton';
|
||||||
|
import { HashLoader } from 'react-spinners';
|
||||||
|
|
||||||
|
import * as OpenID from 'oidc-client-ts';
|
||||||
|
import constants from '../../constants';
|
||||||
|
|
||||||
|
const { API_ROOT } = constants;
|
||||||
|
|
||||||
|
const LoginBox = styled.div`
|
||||||
|
position: fixed;
|
||||||
|
top: 45%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
border: 1px solid #c2c4c2;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 24px 36px;
|
||||||
|
background: white;
|
||||||
|
box-shadow: 0 2px 1px #00000010;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
& h2 {
|
||||||
|
margin: 0px 0;
|
||||||
|
}
|
||||||
|
& hr {
|
||||||
|
margin: 16px 0;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
height: 0px;
|
||||||
|
border: 0;
|
||||||
|
border-bottom: 1px solid #c2c4c2;
|
||||||
|
box-shadow: 0 2px 1px #c2c4c280;
|
||||||
|
}
|
||||||
|
& p {
|
||||||
|
font-size: 8pt;
|
||||||
|
color: gray;
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const LoginButton = styled(BlueButton)`
|
||||||
|
font-size: 11pt;
|
||||||
|
width: 250px;
|
||||||
|
height: 60px;
|
||||||
|
padding: 16px 20px;
|
||||||
|
|
||||||
|
font-size: 11.5pt;
|
||||||
|
font-weight: 700;
|
||||||
|
cursor: ${props => props.disabled ? 'default' : 'pointer'};
|
||||||
|
|
||||||
|
& svg {
|
||||||
|
height: 12pt;
|
||||||
|
margin-left: 6px
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
background: ${props => props.disabled ? 'white' : 'royalblue'};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const OIDCConfig = {
|
||||||
|
onSignIn: () => {},
|
||||||
|
authority: API_ROOT + '/api/auth/vvsu/',
|
||||||
|
client_id: 'it-hub-client',
|
||||||
|
redirect_uri: 'https://pairent.vvsu.ru/sign-in/',
|
||||||
|
scope: [
|
||||||
|
'openid',
|
||||||
|
// 'vvsu_IdUser',
|
||||||
|
// 'vvsu_IdEmpl',
|
||||||
|
// 'vvsu_IdStud',
|
||||||
|
// 'vvsu_login',
|
||||||
|
// 'given_name',
|
||||||
|
// 'family_name'
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const VVSULogoSVG = () => {
|
||||||
|
return <svg xmlns="http://www.w3.org/2000/svg" xmlSpace="preserve" viewBox="0 0 451.5 155.9"><path fillRule="evenodd" d="M408.7 0h42.8L416 102.5l-2.8 8.1c-8.2 23.9-33.9 43.6-58 45.2h-.6c-.8.1-1.6.1-2.5.1H348c-.8 0-1.6 0-2.4-.1h-43l15.7-45.2.3-.8h35.7c9.1 0 19.2-7.8 22.5-17.2l.4-1 1.2-3.5h-32.7c-4.4 0-19.5 0-13.1-18.5l4.4-12.9 3.9-11.2L356.5 0H393l-21.7 62.8H387c2.6-7.5 15.8-45.6 21.7-62.8zm-91.2 0h25.9l-15.7 45.3h-7c-9.6 0-20.1 7.9-23.5 17.4L265 155.9c-.5 0-1-.1-1.5-.1h-43l15.8-45.2 7.8-22.6 14.8-42.5c8.3-24.1 34.4-44 58.6-45.2V0zM208 0h48.7l-20.1 58.1c-3.2 9.1-9.4 15.2-19.4 17.2l16.8.1-12.3 35.2c-8.2 23.9-33.9 43.6-58 45.2h-.7c-.8.1-1.6.1-2.5.1h-4.1c-.8 0-1.6 0-2.4-.1h-43l38.2-110.4c8.4-24.1 34.4-44 58.7-45.2l.1-.2zm-12.7 40.8h15.4l-8.1 23h-23.9l4.4-12.5c1.7-4.6 7.3-10.5 12.2-10.5zm-25.6 48.8H194l-5.5 16.1c-1.1 3.4-6.1 10.8-13.6 10.8h-14.1l8.9-26.9zM96.9 0h48.7l-20.2 58.1c-3.2 9.1-9.4 15.2-19.4 17.2l16.8.1-9.3 27.1h-.2l-2.8 8.1c-8.2 23.9-33.9 43.6-58 45.2h-.6c-.8.1-1.7.1-2.5.1h-4.1c-.8 0-1.6 0-2.4-.1H0l15.7-45.2L23.6 88l14.7-42.5C46.7 21.4 72.7 1.5 97 .3V0zM84.2 40.8h15.4l-8.1 23H67.6L72 51.3c1.7-4.6 7.3-10.5 12.2-10.5zM58.6 89.6h24.3l-5.5 16.1c-1.1 3.4-6.1 10.8-13.5 10.8H49.7l8.9-26.9z" clipRule="evenodd"/></svg>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class LoginPage extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
loading: false
|
||||||
|
}
|
||||||
|
|
||||||
|
this.openid = this.openid.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
async openid() {
|
||||||
|
if (this.state.loading === true) return;
|
||||||
|
this.setState({loading: true});
|
||||||
|
|
||||||
|
OpenID.Log.setLogger(console);
|
||||||
|
OpenID.Log.setLevel(OpenID.Log.DEBUG);
|
||||||
|
|
||||||
|
let client = new OpenID.OidcClient(OIDCConfig);
|
||||||
|
|
||||||
|
const req = await client.createSigninRequest({});
|
||||||
|
window.location.href = req.url;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div style={{height: '50vh'}}>
|
||||||
|
<LoginBox>
|
||||||
|
<h2>Вход</h2>
|
||||||
|
<hr/>
|
||||||
|
<LoginButton onClick={this.openid} disabled={this.state.loading}>
|
||||||
|
{
|
||||||
|
this.state.loading ?
|
||||||
|
<HashLoader size='24px' color='#4169e1' /> :
|
||||||
|
<>
|
||||||
|
Войти через
|
||||||
|
<VVSULogoSVG />
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</LoginButton>
|
||||||
|
<p>
|
||||||
|
Вход осуществляется только через<br/>
|
||||||
|
Систему Единого Входа ВВГУ
|
||||||
|
</p>
|
||||||
|
</LoginBox>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ import Comparisons from "../pages/Comparisons";
|
||||||
import IndexApartment from "../pages/IndexApartment";
|
import IndexApartment from "../pages/IndexApartment";
|
||||||
import IndexPage from "../pages/IndexPage";
|
import IndexPage from "../pages/IndexPage";
|
||||||
import Tinder from "../pages/Tinder";
|
import Tinder from "../pages/Tinder";
|
||||||
|
import LoginPage from "../pages/LoginPage";
|
||||||
|
|
||||||
// НА ПРОДАШКЕНЕ СДЕЛАТЬ ПРИВАТНЫЕ МАРШРУТЫ
|
// НА ПРОДАШКЕНЕ СДЕЛАТЬ ПРИВАТНЫЕ МАРШРУТЫ
|
||||||
// export const privateRoutes = [
|
// export const privateRoutes = [
|
||||||
|
@ -16,7 +17,9 @@ export default Object.freeze({
|
||||||
{ path: '/apartment/:id', component: <IndexApartment />, exact: true },
|
{ path: '/apartment/:id', component: <IndexApartment />, exact: true },
|
||||||
{ path: '/favorites', component: <Favorites />, exact: true },
|
{ path: '/favorites', component: <Favorites />, exact: true },
|
||||||
{ path: '/comparisons', component: <Comparisons />, exact: true },
|
{ path: '/comparisons', component: <Comparisons />, exact: true },
|
||||||
{ path: '/tinder', component: <Tinder />, exact: true }
|
{ path: '/tinder', component: <Tinder />, exact: true },
|
||||||
|
{ path: '/login', component: <LoginPage />, exact: true },
|
||||||
|
{ path: '/sign-in', component: <LoginPage />, exact: true }
|
||||||
],
|
],
|
||||||
privateRoutes: []
|
privateRoutes: []
|
||||||
})
|
})
|
|
@ -1821,6 +1821,11 @@ cross-spawn@^7.0.2:
|
||||||
shebang-command "^2.0.0"
|
shebang-command "^2.0.0"
|
||||||
which "^2.0.1"
|
which "^2.0.1"
|
||||||
|
|
||||||
|
crypto-js@^4.1.1:
|
||||||
|
version "4.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.1.1.tgz#9e485bcf03521041bd85844786b83fb7619736cf"
|
||||||
|
integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==
|
||||||
|
|
||||||
css-color-keywords@^1.0.0:
|
css-color-keywords@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05"
|
resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05"
|
||||||
|
@ -2802,6 +2807,11 @@ json5@^2.2.2:
|
||||||
array-includes "^3.1.5"
|
array-includes "^3.1.5"
|
||||||
object.assign "^4.1.3"
|
object.assign "^4.1.3"
|
||||||
|
|
||||||
|
jwt-decode@^3.1.2:
|
||||||
|
version "3.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-3.1.2.tgz#3fb319f3675a2df0c2895c8f5e9fa4b67b04ed59"
|
||||||
|
integrity sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==
|
||||||
|
|
||||||
levn@^0.4.1:
|
levn@^0.4.1:
|
||||||
version "0.4.1"
|
version "0.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade"
|
resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade"
|
||||||
|
@ -2989,6 +2999,14 @@ object.values@^1.1.6:
|
||||||
define-properties "^1.1.4"
|
define-properties "^1.1.4"
|
||||||
es-abstract "^1.20.4"
|
es-abstract "^1.20.4"
|
||||||
|
|
||||||
|
oidc-client-ts@^2.2.3:
|
||||||
|
version "2.2.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/oidc-client-ts/-/oidc-client-ts-2.2.3.tgz#85c6382540cf59383896d6470c9c3908d5d625f7"
|
||||||
|
integrity sha512-nheMI8kSJu8L+Pmg7E4ra+LJ7lOTK60IfyblFmyx5qaJwwDpc1zkzFyH9eyERAQ92xUTF1uaB8WiaVxXATjLGA==
|
||||||
|
dependencies:
|
||||||
|
crypto-js "^4.1.1"
|
||||||
|
jwt-decode "^3.1.2"
|
||||||
|
|
||||||
once@^1.3.0:
|
once@^1.3.0:
|
||||||
version "1.4.0"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||||
|
|
Loading…
Reference in New Issue