aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatt Strapp <matt@mattstrapp.net>2022-04-05 17:47:36 +0200
committerMatt Strapp <matt@mattstrapp.net>2022-04-05 17:48:13 +0200
commite1b9b6f5b80530620b7df2a0bebfd8941eadad3b (patch)
tree1fd746f187a3cfb35f032f1bc47997add2e57b63 /src
parentBump prettier from 2.6.1 to 2.6.2 (#38) (diff)
downloadee4511w-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.ts4
-rw-r--r--src/routes/api.ts10
-rw-r--r--src/routes/middleware/saml.ts52
-rw-r--r--src/views/pages/index.ejs2
-rw-r--r--src/views/partials/nav.ejs4
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