Skip to content

Commit

Permalink
Merge pull request #92 from AnnaDodson/update-admin-auth-flow
Browse files Browse the repository at this point in the history
 New Admin Auth flow to make the page better
  • Loading branch information
AnnaDodson authored Nov 4, 2019
2 parents 1eae419 + f1a2bf3 commit b509ab0
Show file tree
Hide file tree
Showing 13 changed files with 265 additions and 125 deletions.
54 changes: 54 additions & 0 deletions StepChallenge/ClientApp/src/Admin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React, { Component } from 'react';
import { Route } from 'react-router';
import { AdminLayout } from './components/AdminLayout';
import Auth from './components/Auth';
import { EditParticipant } from './components/admin/editParticipant';
import { EditTeams } from './components/admin/editTeams';
import { EditChallengeSettings } from './components/admin/editChallengeSettings';
import { AdminScoreBoard } from './components/admin/adminScoreBoard';

export class Admin extends Component {
static displayName = Admin.name;

constructor(props) {
super(props);
this.state = {
loading: true,
editParticipant : false,
editTeams : false,
editChallengeSettings : false,
showLeaderBoard : false,
}
this.auth = new Auth()
this.auth.isAdminRequest()
.then(isAdmin => {
if(!isAdmin){
console.log("not an admin")
// redirect to home if not an admin
window.location.href = "/";
}else{
this.setState({
loading: false,
})
}
})
}

render () {
return (
<div>
{this.state.loading &&
<p><em>Loading...</em></p>
}
{!this.state.loading &&
<AdminLayout >
<Route path='/admin/participants' component={EditParticipant} />
<Route path='/admin/teams' component={EditTeams} />
<Route path='/admin/settings' component={EditChallengeSettings} />
<Route path='/admin/leaderboard' component={AdminScoreBoard} />
</AdminLayout>
}
</div>
);
}
}
2 changes: 1 addition & 1 deletion StepChallenge/ClientApp/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { TeamScoreboard } from './components/TeamScoreboard';
import { Register } from './components/Register';
import { Login } from './components/Login';
import { Account } from './components/Account';
import { Admin } from './components/Admin';
import { Admin } from './Admin';
import './App.css';

export default class App extends Component {
Expand Down
78 changes: 0 additions & 78 deletions StepChallenge/ClientApp/src/components/Admin.js

This file was deleted.

18 changes: 18 additions & 0 deletions StepChallenge/ClientApp/src/components/AdminLayout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React, { Component } from 'react';
import { Container } from 'reactstrap';
import { AdminNavMenu } from './AdminNavMenu';

export class AdminLayout extends Component {
static displayName = AdminLayout.name;

render () {
return (
<div>
<AdminNavMenu />
<Container>
{this.props.children}
</Container>
</div>
);
}
}
56 changes: 56 additions & 0 deletions StepChallenge/ClientApp/src/components/AdminNavMenu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React, { Component } from 'react';
import { Collapse, Container, Navbar, NavbarBrand, NavbarToggler, NavItem, NavLink } from 'reactstrap';
import { Link } from 'react-router-dom';
import Auth from './Auth';
import './NavMenu.css';

export class AdminNavMenu extends Component {
static displayName = AdminNavMenu.name;

constructor (props) {
super(props);
this.auth = new Auth();
this.toggleNavbar = this.toggleNavbar.bind(this);
this.state = {
collapsed: true,
isLoggedIn : this.auth.isLoggedIn()
};
}

toggleNavbar () {
this.setState({
collapsed: !this.state.collapsed
});
}

render () {
return (
<header>
<Navbar className="admin-container navbar-expand-sm navbar-toggleable-sm ng-white border-bottom box-shadow mb-3" light>
<Container>
<NavbarBrand tag={Link} to="/admin">Admin</NavbarBrand>
<NavbarToggler onClick={this.toggleNavbar} className="mr-2" />
{this.state.isLoggedIn &&
<Collapse className="d-sm-inline-flex flex-sm-row-reverse" isOpen={!this.state.collapsed} navbar>
<ul className="navbar-nav flex-grow">
<NavItem>
<NavLink tag={Link} className="text-dark" to="/admin/participants">Participants</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} className="text-dark" to="/admin/teams">Teams</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} className="text-dark" to="/admin/settings">Settings</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} className="text-dark" to="/admin/leaderboard">Leader Board</NavLink>
</NavItem>
</ul>
</Collapse>
}
</Container>
</Navbar>
</header>
);
}
}
74 changes: 53 additions & 21 deletions StepChallenge/ClientApp/src/components/Auth.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,49 @@
export default class Auth {
cookieName = "loggedIn"
cookieNames = {
loggedIn : "loggedIn",
isAdmin : "isAdmin"
}

createLoggedInCookies (session){
document.cookie = this.cookieNames.loggedIn + "=true;";
document.cookie = this.cookieNames.isAdmin + "=" + session.isAdmin + ";";
}

createLoggedInCookie (){
document.cookie = this.cookieName + "=true;";
setIsAdminCookie (isAdmin){
document.cookie = this.cookieNames.isAdmin + "=" + isAdmin + ";";
}

deleteLoggedInCookie (){
document.cookie = this.cookieName + "=true; expires=expires=Thu, 01 Jan 1970 00:00:01 GMT; " ;
deleteLoggedInCookies (){
document.cookie = this.cookieNames.loggedIn + "=true; expires=expires=Thu, 01 Jan 1970 00:00:01 GMT; " ;
}

getLoggedInCookie (){
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i <ca.length; i++) {
var c = ca[i];
while (c.charAt(0) === ' ') {
c = c.substring(1);
}
if (c.indexOf(this.cookieName) === 0) {
return c.substring(this.cookieName.length, c.length);
}
getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i <ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
return "";
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}

isLoggedIn(){
var loggedIn = this.getLoggedInCookie();
if(loggedIn){
var loggedIn = this.getCookie(this.cookieNames.loggedIn);
if(loggedIn === 'true'){
return true
}
return false
}

isAdmin(){
var isAdmin = this.getCookie(this.cookieNames.isAdmin);
if(isAdmin === 'true'){
return true
}
return false
Expand All @@ -44,16 +61,17 @@ export default class Auth {
const result = await response;
var responseBody = await result.json();
if(result.status === 400){
console.log(responseBody.errorLogMessage)
return { error : responseBody.error}
}
else{
this.createLoggedInCookie()
this.createLoggedInCookies(responseBody)
return responseBody;
}
}

logout = async function(){
this.deleteLoggedInCookie();
this.deleteLoggedInCookies();
const response = await fetch('/api/user/logout', {
method:'POST',
headers:{'content-type':'application/json'},
Expand All @@ -62,4 +80,18 @@ export default class Auth {
window.location.href = "/login";
}

isAdminRequest = async function(){
const response = await fetch('/api/user/is_admin', {
method:'GET',
headers:{'content-type':'application/json'},
})
var result = await response.json();
if(result.hasOwnProperty("isAdmin")){
this.setIsAdminCookie (result.isAdmin)
return result.isAdmin;
}
else{
return false;
}
}
}
9 changes: 9 additions & 0 deletions StepChallenge/ClientApp/src/components/NavMenu.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,12 @@ html {
.box-shadow {
box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
}

.admin-container {
padding-left: 0;
padding-right: 0;
}
.admin-container .container{
padding-left: 0;
padding-right: 0;
}
12 changes: 8 additions & 4 deletions StepChallenge/ClientApp/src/components/SettingsMenu.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import Dropdown from 'react-bootstrap/Dropdown';
import Auth from './Auth';

export default class SettingsMenu extends Component {
static displayName = SettingsMenu.name;
constructor (props) {
super(props);
this.state = {
};
this.handleLogout = this.handleLogout.bind(this);
this.auth = new Auth()
this.isAdmin = this.auth.isAdmin();
this.state = {
isAdmin : this.auth.isAdmin(),
};
}

render () {
Expand All @@ -21,7 +22,10 @@ export default class SettingsMenu extends Component {
</Dropdown.Toggle>

<Dropdown.Menu>
<Dropdown.Item><Link to="/account">Account</Link></Dropdown.Item>
<Dropdown.Item href="/account">Account</Dropdown.Item>
{this.state.isAdmin &&
<Dropdown.Item href="/admin">Admin</Dropdown.Item>
}
<Dropdown.Item onClick={this.handleLogout}>Log out</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export class EditChallengeSettings extends Component {
}

handleSaveDisplayLeaderBoard(setting) {
var newState = this.state.showLeaderBoard == true ? false : true;
var newState = this.state.showLeaderBoard === true ? false : true;
this.setState({showLeaderBoard : newState, error: false})
updateSetting({
showLeaderBoard : newState,
Expand All @@ -67,7 +67,7 @@ export class EditChallengeSettings extends Component {
}

handleSaveDisplayTeamScores(setting) {
var newSettings = this.state.displayTeamScores == true ? false : true;
var newSettings = this.state.displayTeamScores === true ? false : true;
this.setState({displayTeamScores : newSettings, error : false})
updateSetting({
showLeaderBoard : this.state.showLeaderBoard,
Expand Down
Loading

0 comments on commit b509ab0

Please sign in to comment.