diff options
author | Matt Strapp <matt@mattstrapp.net> | 2022-04-05 17:47:36 +0200 |
---|---|---|
committer | Matt Strapp <matt@mattstrapp.net> | 2022-04-05 17:48:13 +0200 |
commit | e1b9b6f5b80530620b7df2a0bebfd8941eadad3b (patch) | |
tree | 1fd746f187a3cfb35f032f1bc47997add2e57b63 /src | |
parent | Bump prettier from 2.6.1 to 2.6.2 (#38) (diff) | |
download | ee4511w-web-e1b9b6f5b80530620b7df2a0bebfd8941eadad3b.tar ee4511w-web-e1b9b6f5b80530620b7df2a0bebfd8941eadad3b.tar.gz ee4511w-web-e1b9b6f5b80530620b7df2a0bebfd8941eadad3b.tar.bz2 ee4511w-web-e1b9b6f5b80530620b7df2a0bebfd8941eadad3b.tar.lz ee4511w-web-e1b9b6f5b80530620b7df2a0bebfd8941eadad3b.tar.xz ee4511w-web-e1b9b6f5b80530620b7df2a0bebfd8941eadad3b.tar.zst ee4511w-web-e1b9b6f5b80530620b7df2a0bebfd8941eadad3b.zip |
Add Shibboleth login support
Signed-off-by: Matt Strapp <matt@mattstrapp.net>
Diffstat (limited to 'src')
-rw-r--r-- | src/index.ts | 4 | ||||
-rw-r--r-- | src/routes/api.ts | 10 | ||||
-rw-r--r-- | src/routes/middleware/saml.ts | 52 | ||||
-rw-r--r-- | src/views/pages/index.ejs | 2 | ||||
-rw-r--r-- | src/views/partials/nav.ejs | 4 |
5 files changed, 55 insertions, 17 deletions
diff --git a/src/index.ts b/src/index.ts index c4b346a..88c6f58 100644 --- a/src/index.ts +++ b/src/index.ts @@ -43,10 +43,10 @@ app.use('/public', express.static(path.join(__dirname, 'public'))); // Set stati /* ROUTING */ -app.get('/', csrf, (req: Request, res: Response) => { +app.get('/pendulum', csrf, saml, (req: Request, res: Response) => { res.render('index', { csrfToken: req.csrfToken() }); }); -app.get('/about', csrf, saml, (req: Request, res: Response) => { +app.get('/', csrf, (req: Request, res: Response) => { res.render('about'); }); app.all('/login', csrf, (req: Request, res: Response) => { diff --git a/src/routes/api.ts b/src/routes/api.ts index 6cb804c..4b10121 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -5,6 +5,7 @@ import express, { Request, Response } from 'express'; import fileUpload, { UploadedFile } from 'express-fileupload'; import { access, stat } from 'fs/promises'; import { quote } from 'shell-quote'; +import { saml_api } from './middleware/saml.js'; /** * The endpoint for the API calls involving file uploads and running the files on the pendulum. @@ -17,6 +18,9 @@ api.use(express.json()); api.use(cookieParser()); const csrf = csurf({ cookie: true }); +// Require authentication for all API calls +api.use(saml_api); + // For file uploads api.use( fileUpload({ @@ -230,14 +234,12 @@ api */ async function verifyFile(file: string, res: Response): Promise<boolean> { // Make sure the file being requested to run exists - try { - await access(file); - } catch (err) { + await access(file).catch(() => { res .status(404) .json({ error: 'File is not accessible or does not exist.' }); return false; - } + }); // This is a try catch because otherwise type checking will fail and get all messed up // Handle your promise rejections, kids try { diff --git a/src/routes/middleware/saml.ts b/src/routes/middleware/saml.ts index cce29a2..5904d6e 100644 --- a/src/routes/middleware/saml.ts +++ b/src/routes/middleware/saml.ts @@ -1,13 +1,49 @@ import BasicAuthenticator from 'umn-shib-nodejs'; import { Request, Response, NextFunction } from 'express'; -const saml = function (req: Request, res: Response, next: NextFunction): void { +/** + * Express Middleware to check if the user is authenticated with Shibboleth, wraps {@link isLoggedIn} + * @param req Express request object + * @param res Express response object + * @param next Express next function + */ +export default function saml( + req: Request, + res: Response, + next: NextFunction +): void { const authenticator = new BasicAuthenticator(req, res); - if (!authenticator.hasSession()) { - res.redirect(authenticator.buildLoginURL()); - return; - } - next(); -}; + if (isLoggedIn(req)) next(); + else res.redirect(authenticator.buildLoginURL()); +} -export default saml; +/** + * A much simpler way to respond to a user that is not logged in for API calls. + * @param req Express request object + * @param res Express response object + * @param next Express next function + */ +export function saml_api( + req: Request, + res: Response, + next: NextFunction +): void { + if (isLoggedIn(req)) next(); + else res.status(401).json({ error: 'Not logged in.' }); +} + +/** + * Rudimentary check to see if the user is logged in by checking if the user has a session cookie + * @param req Express request object + * @returns true if the user is logged in, false otherwise + */ +function isLoggedIn(req: Request): boolean { + /* + Shibboleth token always contains _shibsession_, so we can check for that + Is this a good way to check if the user is logged in? + Not even slightly. + But it works. + */ + const cookies = JSON.stringify(req.cookies); + return cookies.includes('_shibsession_'); +} diff --git a/src/views/pages/index.ejs b/src/views/pages/index.ejs index 3d9d0be..ca9b20f 100644 --- a/src/views/pages/index.ejs +++ b/src/views/pages/index.ejs @@ -5,7 +5,7 @@ <!-- HTML headers --> <%- include('../partials/head.ejs') %> <title>Upload your code here!</title> - <script type="module" src="public/js/form.js" defer></script> + <script type="module" src="public/js/form.js"></script> </head> <body> diff --git a/src/views/partials/nav.ejs b/src/views/partials/nav.ejs index 04054a9..3244ca1 100644 --- a/src/views/partials/nav.ejs +++ b/src/views/partials/nav.ejs @@ -1,7 +1,7 @@ <nav> <ul class="navbar"> - <li><a href="/">Home</a></li> - <li><a href="/about">About the Inverted Pendulum</a></li> + <li><a href="/pendulum">Run the Pendulum!</a></li> + <li><a href="/">About the Inverted Pendulum</a></li> <li><a href="https://github.com/UMN-EE4951W-Lamperski/pendulum" style="right: 0px">GitHub Repo</a></li> </ul> </nav>
\ No newline at end of file |