Commit bdb603ea authored by David Haynes's avatar David Haynes 🙆
Browse files

Add page template for auth checking

- ping the api to check for status before rendering
- render children if true, else hit the auth wall
parent ce7a5548
Pipeline #3813 passed with stage
in 1 minute and 37 seconds
import React from "react"; import React from "react";
import * as Yup from "yup"; import * as Yup from "yup";
import { Formik, Field, Form, ErrorMessage } from "formik"; import { Formik, Field, Form as FormikForm, ErrorMessage } from "formik";
import { GetCSRFToken } from "../../Utils"; import { GetCSRFToken } from "../../Utils";
import { SingleDatePicker } from "react-dates"; import { SingleDatePicker } from "react-dates";
import moment from "moment"; import moment from "moment";
import { Form, FormGroup, Button, Card, CardBody, CardTitle } from "reactstrap";
const DebugCreateYup = Yup.object().shape({ const DebugCreateYup = Yup.object().shape({
destination: Yup.string() destination: Yup.string()
...@@ -21,70 +22,85 @@ class DebugCreate extends React.Component { ...@@ -21,70 +22,85 @@ class DebugCreate extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
focused: false, focused: false
date: null
}; };
} }
render() { render() {
return ( return (
<div> <Card>
<Formik <CardBody>
initialValues={{ <CardTitle>Create</CardTitle>
destination: "", <Formik
short: "", initialValues={{
expires: moment(new Date()) destination: "",
}} short: "",
validationSchema={DebugCreateYup} expires: moment(new Date())
onSubmit={(values, { setSubmitting }) => { }}
const newValues = { validationSchema={DebugCreateYup}
destination: values.destination, onSubmit={(values, { setSubmitting }) => {
short: values.short, const newValues = {
date_expires: values.expires.format() destination: values.destination,
}; short: values.short,
console.log(newValues); date_expires: values.expires.format()
fetch("/api/golinks/", { };
method: "post", console.log(newValues);
headers: { fetch("/api/golinks/", {
"Content-Type": "application/json", method: "post",
"X-CSRFToken": GetCSRFToken() headers: {
}, "Content-Type": "application/json",
body: JSON.stringify(newValues) "X-CSRFToken": GetCSRFToken()
}) },
.then(response => console.log(response)) body: JSON.stringify(newValues)
.then(setSubmitting(false)); })
}} .then(response => console.log(response))
render={({ values, isSubmitting, setFieldValue }) => ( .then(setSubmitting(false));
<Form> }}
{"Destination: "} render={({ values, isSubmitting, setFieldValue }) => (
<Field <Form>
name="destination" <FormikForm>
placeholder="https://longwebsitelink.com" <FormGroup>
/> {"Destination: "}
<ErrorMessage name="destination" component="div" /> <Field
<br /> className="form-control"
{"Short: "} name="destination"
<Field name="short" /> placeholder="https://longwebsitelink.com"
<ErrorMessage name="short" /> />
<br /> <ErrorMessage name="destination" component="div" />
{"Expires: "} </FormGroup>
<SingleDatePicker <FormGroup>
date={values["expires"]} // momentPropTypes.momentObj or null {"Short: "}
onDateChange={date => setFieldValue("expires", date)} // PropTypes.func.isRequired <Field className="form-control" name="short" />
focused={this.state.focused} // PropTypes.bool <ErrorMessage name="short" />
onFocusChange={({ focused }) => this.setState({ focused })} // PropTypes.func.isRequired </FormGroup>
id="expires" // PropTypes.string.isRequired, <FormGroup>
/> {"Expires: "}
<br />
<ErrorMessage name="expires" /> <SingleDatePicker
<br /> date={values["expires"]} // momentPropTypes.momentObj or null
<button type="submit" disabled={isSubmitting}> onDateChange={date => setFieldValue("expires", date)} // PropTypes.func.isRequired
Submit focused={this.state.focused} // PropTypes.bool
</button> onFocusChange={({ focused }) =>
</Form> this.setState({ focused })
)} } // PropTypes.func.isRequired
/> id="expires" // PropTypes.string.isRequired,
</div> />
<ErrorMessage name="expires" />
</FormGroup>
<Button
type="submit"
disabled={isSubmitting}
outline
color="primary"
>
Submit
</Button>
</FormikForm>
</Form>
)}
/>
</CardBody>
</Card>
); );
} }
} }
......
import React from "react"; import React from "react";
import { import {
PageTemplate, AuthedPageTemplate,
DebugRead, DebugRead,
DebugCreate, DebugCreate,
DebugDelete, DebugDelete,
...@@ -15,21 +15,18 @@ class DebugCRUD extends React.Component { ...@@ -15,21 +15,18 @@ class DebugCRUD extends React.Component {
render() { render() {
return ( return (
<PageTemplate> <AuthedPageTemplate>
<div> <DebugCreate />
<h3>Create</h3>
<DebugCreate />
<h3>Read</h3> <h3>Read</h3>
<DebugRead /> <DebugRead />
<h3>Update</h3> <h3>Update</h3>
<DebugUpdate /> <DebugUpdate />
<h3>Delete</h3> <h3>Delete</h3>
<DebugDelete /> <DebugDelete />
</div> </AuthedPageTemplate>
</PageTemplate>
); );
} }
} }
......
import React from "react";
import { Container } from "reactstrap";
class AuthedPageTemplate extends React.Component {
constructor(props) {
super(props);
this.state = { isLoggedIn: null, loaded: false };
}
componentDidMount() {
fetch("/auth/status/", {
headers: {
"Content-Type": "application/json"
}
})
.then(r => r.json())
.then(res =>
this.setState({
isLoggedIn: res.is_authenticated,
loaded: true
})
);
}
render() {
const { isLoggedIn, loaded } = this.state;
return (
<div>
{loaded ? (
<div>
{isLoggedIn ? (
<Container>{this.props.children}</Container>
) : (
<h1>You're not authed!</h1>
)}
</div>
) : (
<div />
)}
</div>
);
}
}
export default AuthedPageTemplate;
import PageTemplate from "./PageTemplate"; import PageTemplate from "./PageTemplate";
import AuthedPageTemplate from "./AuthedPageTemplate";
export { PageTemplate }; export { PageTemplate, AuthedPageTemplate };
...@@ -7,7 +7,7 @@ import { ...@@ -7,7 +7,7 @@ import {
} from "./Molecules"; } from "./Molecules";
import { NavBar } from "./Organisms"; import { NavBar } from "./Organisms";
import { HomePage, AboutPage, DhaynesPage, DebugCRUD } from "./Pages"; import { HomePage, AboutPage, DhaynesPage, DebugCRUD } from "./Pages";
import { PageTemplate } from "./Templates"; import { PageTemplate, AuthedPageTemplate } from "./Templates";
export { export {
//Molecules //Molecules
...@@ -24,5 +24,6 @@ export { ...@@ -24,5 +24,6 @@ export {
DhaynesPage, DhaynesPage,
DebugCRUD, DebugCRUD,
//Templates //Templates
PageTemplate PageTemplate,
AuthedPageTemplate
}; };
...@@ -10,7 +10,7 @@ from rest_framework.authentication import TokenAuthentication, SessionAuthentica ...@@ -10,7 +10,7 @@ from rest_framework.authentication import TokenAuthentication, SessionAuthentica
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.authtoken.models import Token from rest_framework.authtoken.models import Token
from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.authtoken.views import ObtainAuthToken from rest_framework.authtoken.views import ObtainAuthToken
from .serializers import URLSerializer from .serializers import URLSerializer
...@@ -60,17 +60,12 @@ class CustomAuthToken(ObtainAuthToken): ...@@ -60,17 +60,12 @@ class CustomAuthToken(ObtainAuthToken):
class GetSessionInfo(APIView): class GetSessionInfo(APIView):
"""Handy endpoint to return current user session status & information to the frontend.""" """Handy endpoint to return current user session status & information to the frontend."""
authentication_classes = (SessionAuthentication,) permission_classes = (AllowAny,)
permission_classes = (IsAuthenticated,)
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
token, created = Token.objects.get_or_create(user=request.user)
session_info = { session_info = {
"username": request.user.username, "username": request.user.username,
# "full_name": f"{request.user.get_full_name}",
"last_login": request.user.last_login,
"is_authenticated": request.user.is_authenticated, "is_authenticated": request.user.is_authenticated,
"token": token.key,
} }
return Response(session_info) return Response(session_info)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment