diff --git a/authserver/authserver/settings.py b/authserver/authserver/settings.py index 72a4585..b0aae22 100644 --- a/authserver/authserver/settings.py +++ b/authserver/authserver/settings.py @@ -25,9 +25,6 @@ SECRET_KEY = 'h$p_vf^h$h@cebvgeynhda3-@i&+f-(3k9w-qsftn_+!-o_)$0' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True -ALLOWED_HOSTS = [] - - # Application definition INSTALLED_APPS = [ @@ -39,6 +36,7 @@ INSTALLED_APPS = [ 'django.contrib.staticfiles', 'rest_framework', 'rest_framework.authtoken', + 'corsheaders', 'authserver.api', ] @@ -49,8 +47,14 @@ REST_FRAMEWORK = { ), } +#CORS_ORIGIN_WHITELIST = ( +# 'localhost:8000', +#) + +CORS_ORIGIN_ALLOW_ALL = True MIDDLEWARE = [ + 'corsheaders.middleware.CorsMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', diff --git a/authserver/requirements.txt b/authserver/requirements.txt index 81d5fab..db23043 100644 --- a/authserver/requirements.txt +++ b/authserver/requirements.txt @@ -1,6 +1,7 @@ certifi==2018.8.24 chardet==3.0.4 Django==2.1.1 +django-cors-headers==2.4.0 djangorestframework==3.8.2 idna==2.7 Pillow==5.2.0 diff --git a/webclient/src/App.js b/webclient/src/App.js index 0e55082..fafc125 100644 --- a/webclient/src/App.js +++ b/webclient/src/App.js @@ -2,46 +2,71 @@ import React, { Component } from 'react'; import Categories from './Categories'; import Category from './Category'; import Tool from './Tool'; -import { Container, Dimmer, Dropdown, Header, Icon, Item, Loader, Menu, Segment, Input } from 'semantic-ui-react'; +import { Button, Confirm, Container, Dimmer, Form, Header, Icon, Item, Label, Loader, Menu, Message, Segment, Input } from 'semantic-ui-react'; import { Link, Route } from 'react-router-dom'; import io from 'socket.io-client'; // Move to env var -const SERVER_URL = 'http://localhost:8080'; +const SOCKET_SERVER_URL = 'http://localhost:8080'; +const AUTH_SERVER_URL = 'http://localhost:8000'; class App extends Component { constructor() { super(); - this.socket = io(SERVER_URL); + this.socket = io(SOCKET_SERVER_URL); + this.storage = typeof localStorage !== 'undefined'; + + let token = this.storage ? localStorage.getItem('token') : null; this.state = { + login: {token: token, error: null, username: '', password: '', confirmLogout: false}, user: null, toolData: null, toolStatus: null, connected: false, + network: true, }; } + getUser = () => { + fetch(AUTH_SERVER_URL + '/user/', { + headers: {'Authorization': 'Token ' + this.state.login.token}, + }) + .then(response => { + if (response.ok) { + response.json().then(data => this.setState({ user: data[0] })); + } else { + this.handleLogout(); + } + }) + .catch(error => { + console.log(error) + }); + } + componentDidMount() { - fetch(SERVER_URL + '/api/tooldata') + fetch(AUTH_SERVER_URL + '/tooldata/') .then(response => response.json()) - .then(data => this.setState({ toolData: data })); - fetch(SERVER_URL + '/api/user') - .then(response => response.json()) - .then(data => this.setState({ user: data })); + .then(data => this.setState({ toolData: data })) + .catch(error => { + console.log(error) + this.setState({network: false}); + }); + + if (this.state.login.token) this.getUser(); this.socket.on('toolStatus', toolStatus => this.setState({ toolStatus: toolStatus }) ); - this.socket.on('connect', toolStatus => + this.socket.on('connect', () => this.setState({ connected: true }) ); - this.socket.on('disconnect', toolStatus => - this.setState({ toolStatus: null, connected: false }) - ); + this.socket.on('disconnect', () => { + this.setState({ toolStatus: null, connected: false }); + }); } componentWillUnmount() { @@ -50,63 +75,161 @@ class App extends Component { requestInterlock = change => { this.socket.emit('requestInterlock', { - username: this.state.user.username, + token: this.state.login.token, change: change, }); } + handleChange = event => { + const name = event.target.name; + const value = event.target.value; + + this.setState({ + login: {...this.state.login, [name]: value} + }); + } + + handleSubmit = () => { + const login = this.state.login; + fetch(AUTH_SERVER_URL + '/login/', { + method: 'POST', + headers: {'Content-Type': 'application/json; charset=utf-8'}, + body: JSON.stringify({'username': login.username, 'password': login.password}) + }) + .then(response => { + if (response.ok) { + response.json().then(data => { + this.setState({login: {...login, ...data, error: false}}); + if (this.storage) localStorage.setItem('token', data.token); + this.getUser(); + }); + } else { + this.setState({login: {...login, error: true}}); + } + }) + .catch(error => { + console.log(error) + this.setState({network: false}); + }); + } + + confirmLogout = () => { + if (this.state.login.token) { + this.setState({ + login: {...this.state.login, confirmLogout: true} + }); + } + } + + cancelLogout = () => { + this.setState({ + login: {...this.state.login, confirmLogout: false} + }); + } + + handleLogout = () => { + this.setState({ + login: {...this.state.login, token: null, confirmLogout: false} + }); + localStorage.removeItem('token'); + } + + handleRefresh = () => { + window.location.reload(); + } + render() { + const login = this.state.login; + const user = this.state.user; const toolData = this.state.toolData; const toolStatus = this.state.toolStatus; - const user = this.state.user; const connected = this.state.connected; + const network = this.state.network; return ( -
- - - - - - - - - - - - - + network ? +
+ + + - - -
+ + + + + + {connected && toolStatus ? 'Connected' : 'Disconnected'} + +
+
+ - {toolData && user ? -
- - - } /> + {login.token ? +
+ {toolData && user ? +
+ + + } /> - - - } /> + + + } /> - - - } /> -
- : - - Loading - - } -
+ + + } /> +
+ : + + Loading + + } +
+ : + +
+ {login.error ? + + : + + } + + + + + + + + + + +
+ } +
+ : + +
+ + Please connect to the "Protospace" wifi +
+
+ +
); } } diff --git a/webclient/src/Category.js b/webclient/src/Category.js index 73c07c9..bb74686 100644 --- a/webclient/src/Category.js +++ b/webclient/src/Category.js @@ -23,12 +23,12 @@ class Category extends Component { {category.tools.map((x, n) => - + {x.name} - {user.authorizedTools.includes(x.id) ? + {user.profile.authorized_tools.includes(x.slug) ? :