Skip to content

Commit

Permalink
fix unipiAuth
Browse files Browse the repository at this point in the history
  • Loading branch information
paolini committed Jan 4, 2024
1 parent 5eb3d8a commit e6fdb01
Show file tree
Hide file tree
Showing 12 changed files with 79 additions and 38 deletions.
12 changes: 7 additions & 5 deletions api/.env.sample
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
CAPS_NAME="Development" # brand name

SERVER_URL="http://localhost:3000"
CORS_ORIGIN="http://localhost:3000" # comma separated URLS

SESSION_SECRET="" # set a string or leave empty for a random string
SESSION_SECRET="" # set a string or leave empty for a random string
PERMISSION_SECRET=""

MONGO_DB_URI="mongodb://localhost:27017"
MONGO_DB="caps"
MONGO_DB_URI="mongodb://localhost:27017/caps"
MONGO_DB="caps" # repetita juvant

ADMIN_USER="admin" # if set the user is created
ADMIN_PASSWORD="" # if empty the password is not changed
ADMIN_PASSWORD="" # if set this password is set

# Client ID for OAuth2, leave empty to disable OAuth2
OAUTH2_CLIENT_ID=""
Expand All @@ -17,4 +19,4 @@ OAUTH2_AUTHORIZE_URL="https://iam.unipi.it/oauth2/authorize"
OAUTH2_TOKEN_URL="https://iam.unipi.it/oauth2/token"
OAUTH2_USERINFO_URL="https://iam.unipi.it/oauth2/userinfo"
OAUTH2_LOGOUT_URL="https://iam.unipi.it/oidc/logout"
OAUTH2_USERNAME_FIELD="email"
OAUTH2_USERNAME_FIELD="credential"
12 changes: 9 additions & 3 deletions api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const cors = require('cors')
const { randomUUID } = require('crypto')
const MongoStore = require('connect-mongo')
const dotenv = require('dotenv')
const fs = require('fs')
dotenv.config() // read environment variabiles from .env

const ApiException = require('./exceptions/ApiException');
Expand All @@ -25,6 +26,13 @@ function logErrors(err : any, req : any, res : any, next : any) {
next(err);
}

const config = {
CAPS_NAME: process.env.CAPS_NAME || "Develop",
}
const SPA_FILENAME = path.join(__dirname, "./webroot/index.html")
const SPA_HTML = fs.readFileSync(SPA_FILENAME, 'utf8')
.replace('/**INJECT-CONFIG-HERE**/', JSON.stringify(config))

const mongo_uri = process.env.MONGODB_URI || 'mongodb://localhost:27017/caps'
mongoose.connect(mongo_uri).then((res : any) => {
console.log("Connected to MongoDB", mongo_uri)
Expand Down Expand Up @@ -66,9 +74,7 @@ mongoose.connect(mongo_uri).then((res : any) => {
app.use('/img/', express.static('./webroot/img'));
app.use('/favicon.ico', express.static('./webroot/favicon.ico'));

const spa = (req : any, res : any) => res.sendFile(path.join(__dirname, "./webroot/index.html"));

app.use("/", spa);
app.use("/", (req: any,res: any)=>res.send(SPA_HTML));
app.use(logErrors); // log errors on console

app.use(ApiException.apiErrors); // convert ApiErrors into http responses
Expand Down
3 changes: 2 additions & 1 deletion api/models/User.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ const userSchema = new mongoose.Schema({
type: String
},
*/
comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }]

//comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }]
})

userSchema.plugin(passportLocalMongoose)
Expand Down
5 changes: 4 additions & 1 deletion api/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,21 @@ passport.deserializeUser(User.deserializeUser())
// unipi oauth2 authentication
const env = process.env
if (env.OAUTH2_CLIENT_ID) {
const callbackURL = `${SERVER_URL}/api/v0/login/oauth2/callback`
passport.use(new UnipiAuthStrategy({
authorizationURL: env.OAUTH2_AUTHORIZE_URL,
tokenURL: env.OAUTH2_TOKEN_URL,
clientID: env.OAUTH2_CLIENT_ID,
clientSecret: env.OAUTH2_CLIENT_SECRET,
callbackURL: `${SERVER_URL}/api/v0/login/oauth2/callback`,
callbackURL,
usernameField: env.OAUTH2_USERNAME_FIELD,
}))
console.log("OAUTH2 authentication enabled")
console.log(`OAUTH2_AUTHORIZE_URL: ${env.OAUTH2_AUTHORIZE_URL}`)
console.log(`OAUTH2_CLIENT_ID: ${env.OAUTH2_CLIENT_ID}`)
console.log(`OAUTH2_USERNAME_FIELD: ${env.OAUTH2_USERNAME_FIELD}`)
console.log(`SERVER_URL: ${SERVER_URL}`)
console.log(`callbackURL: ${callbackURL}`)
} else {
console.log("OAUTH2 authentication disabled")
console.log("set OAUTH2_CLIENT_ID to enable")
Expand Down
35 changes: 22 additions & 13 deletions api/unipiAuth.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,29 @@ class UnipiAuthStrategy extends OAuth2Strategy {

if (! username) throw new Error("invalid username")

User.findOneAndUpdate({ username: username }, {
$set: {
username: username,
firstName: profile['given_name'],
lastName: profile['family_name'],
email: profile['email'],
}
}, {
upsert: true,
new: true
}, function (err, user) {
async function update() {
let user = null
try {
user = await User.findOneAndUpdate({ username: username }, {
$set: {
username: username,
first_name: profile?.given_name,
last_name: profile?.family_name,
email: profile?.email,
id_number: profile?.unipiMatricolaStudente || profile?.unipiMatricolaDipendente || profile?.credential || profile?.principal || profile?.sub,
}
}, {
upsert: true,
new: true
})
user.oauth2 = {accessToken, refreshToken}
return cb(err, user)
})
cb(null, user)
} catch (err) {
cb(err,null)
}
}

update()
})
}

Expand Down
9 changes: 7 additions & 2 deletions docker-compose-production.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
version: '3'
# Questo file è un esempio di configurazione di docker-compose per CAPS.
# Per utilizzarlo, rinominare il file in docker-compose.yml e modificare i parametri
# di configurazione come indicato nei commenti.

version: '3'
services:
caps:
image: harbor.cs.dm.unipi.it/caps/caps:api
Expand All @@ -23,7 +26,9 @@ services:
- OAUTH2_TOKEN_URL=https://iam.unipi.it/oauth2/token
- OAUTH2_USERINFO_URL=https://iam.unipi.it/oauth2/userinfo
- OAUTH2_LOGOUT_URL=https://iam.unipi.it/oidc/logout
- OAUTH2_USERNAME_FIELD=email
- OAUTH2_USERNAME_FIELD=credential
# callback url is: ${SERVER_URL}/api/v0/login/oauth2/callback

ports:
- 3000:3000
networks:
Expand Down
3 changes: 2 additions & 1 deletion frontend/deploy-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class CAPSDeployPlugin {
const index_filename = INSTALL_DIR + 'index.html';
console.log(`Creating ${index_filename}`);
fs.writeFileSync(index_filename,`<!DOCTYPE html>
<!-- *** DO NOT EDIT THIS FILE: automatically created by frontend/deploy-plugin.js *** -->
<html>
<head>
<script type="text/javascript" src="/js/${name}${extension}"></script>
Expand All @@ -80,7 +81,7 @@ class CAPSDeployPlugin {
<div id="app">...loading...</div>
<script>
// globally defined in /js/caps.js
capsStart();
capsStart(/**INJECT-CONFIG-HERE**/);
</script>
</body>
</html>`);
Expand Down
2 changes: 1 addition & 1 deletion frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<div id="app">...loading...</div>
<script>
// globally defined in /js/caps.js
capsStart();
capsStart({name:'develop'});
</script>
</body>
</html>
4 changes: 2 additions & 2 deletions frontend/src/caps.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import SinglePage from './pages/SinglePage';
import React from 'react';
import ReactDOM from 'react-dom';

function capsStart() {
function capsStart(config) {
ReactDOM.render(
<SinglePage />,
<SinglePage config={config}/>,
document.getElementById("app")
);
}
Expand Down
10 changes: 7 additions & 3 deletions frontend/src/components/NavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import settings from "../modules/settings"
export default function NavBar() {
const engine = useEngine()
if (!engine) return null

const user = engine.user
const config = engine.config

return <Nav className="navbar-nav bg-primary sidebar sidebar-dark accordion" id="accordionSidebar">
<Link className="sidebar-brand d-flex align-items-center justify-content-center" to="/">
<div className="sidebar-brand-icon">
Expand All @@ -17,7 +21,7 @@ export default function NavBar() {
</Link>
<div className="d-flex justify-content-center">
<div className="text-white text-uppercase font-weight-bold my-2 mx-2 px-2" style={{fontSize: "0.7rem"}}>
Development
{config.CAPS_NAME}
</div>
</div>
<hr className="sidebar-divider" />
Expand Down Expand Up @@ -47,7 +51,7 @@ export default function NavBar() {
<span>Nuovo modulo</span>
</NavLink>
</NavItem>

{ user.admin && <>
<hr className="sidebar-divider" />

<div className="sidebar-heading">
Expand Down Expand Up @@ -123,7 +127,7 @@ export default function NavBar() {
<span>Impostazioni</span>
</NavLink >
</NavItem>

</> }
<hr className="sidebar-divider" />
<NavItem>
<a className="nav-link" href="mailto:[email protected]">
Expand Down
14 changes: 12 additions & 2 deletions frontend/src/modules/engine.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ export function useEngine(): Engine {
return engine
}

type Config = {
CAPS_NAME: string
}

interface EngineState {
flashMessages: Array<{ message: string, type: string }>,
modalConfirmData: {
Expand All @@ -23,11 +27,13 @@ interface EngineState {
},
user: any,
connected: boolean,
config: Config,
}

interface Engine {
state: EngineState,
state: EngineState, // private
user: any,
config: Config,
modalConfirm: (title: string, content: string) => Promise<boolean>,
flashMessage: (message: string, type?: string) => void,
flashSuccess: (message: string) => void,
Expand All @@ -40,7 +46,9 @@ interface Engine {
logout: () => void,
}

export function useCreateEngine(): Engine {
export function useCreateEngine(config:{
config: Config,
}): Engine {
const [state, setState] = useState<EngineState>({
flashMessages: [],
modalConfirmData: {
Expand All @@ -50,6 +58,7 @@ export function useCreateEngine(): Engine {
},
user: null,
connected: false,
config,
})

const queryClient=useQueryClient()
Expand Down Expand Up @@ -81,6 +90,7 @@ export function useCreateEngine(): Engine {
return {
state,
user: state.user,
config: state.config,

modalConfirm: (title, content) => {
return new Promise((resolve) => {
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/pages/SinglePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ import {QueryClient, QueryClientProvider } from 'react-query'

const queryClient = new QueryClient()

export default function SinglePage() {
export default function SinglePage({config}) {
return <QueryClientProvider client={queryClient}>
<SinglePageInternal/>
<SinglePageInternal config={config}/>
</QueryClientProvider>
}

function SinglePageInternal () {
const engine = useCreateEngine()
function SinglePageInternal({config}) {
const engine = useCreateEngine(config)
// engine.sync(useState(engine.state))
const modalConfirmData = engine.state.modalConfirmData

Expand Down

0 comments on commit e6fdb01

Please sign in to comment.