Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add "authenticated" user roles and permissions, and amend API definitions [DEV-2684] #267

Merged
merged 4 commits into from
Jun 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,15 @@ We use a self-hosted version of [LogTo](https://logto.io/), which supports OpenI
1. `ENABLE_AUTHENTICATION`: Turns API authentication guards on/off (Default: `false`). If `ENABLE_AUTHENTICATION=false`, then define below environment variable in `.env` file:
- `DEFAULT_CUSTOMER_ID`: Customer/user in LogTo to use for unauthenticated users.
2. `LOGTO_ENDPOINT`: API endpoint for LogTo server
3. `LOGTO_RESOURCE_URL`: API resource associated with application
3. `LOGTO_DEFAULT_RESOURCE_URL`: Usually it will be a root of all API resources. All the resourceAPI will be constructed on top of that.
4. `LOGTO_APP_ID`: Application ID from LogTo. For now, Application is supposed to be a TraditionalWeb
5. `LOGTO_APP_SECRET`: Application secret. Also should encrypted in deployment
6. `ALL_SCOPES`: List of all scopes. Should be a string with scopes divided by whitespace, like `account:create account:read did:create`
7. `COOKIE_SECRET`: Secret for cookie encryption.
6. `LOGTO_M2M_APP_ID`: Machine-to-machine Application ID
7. `LOGTO_M2M_APP_SECRET`: Machine-to-machine Application secret
8. `LOGTO_MANAGEMENT_API`: URL of management API for LogTo (default is `https://default.logto.app/api`)
9. `ALLOWED_ORIGINS`: CORS allowed origins used in the app
10. `DEFAULT_CUSTOMER_ID`: Customer/user in LogTo to use for unauthenticated users
11. `COOKIE_SECRET`: Secret for cookie encryption.
lampkin-diet marked this conversation as resolved.
Show resolved Hide resolved

### 3rd Party Connectors

Expand Down
12 changes: 8 additions & 4 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,15 @@ ARG EXTERNAL_DB_CERT
# LogTo: build-time
ARG ENABLE_AUTHENTICATION=false
ARG LOGTO_ENDPOINT
ARG LOGTO_RESOURCE_URL
ARG LOGTO_DEFAULT_RESOURCE_URL
ARG LOGTO_APP_ID
ARG LOGTO_APP_SECRET
ARG ALLOWED_ORIGINS
ARG DEFAULT_CUSTOMER_ID
ARG ALL_SCOPES
ARG COOKIE_SECRET
ARG LOGTO_M2M_APP_ID
ARG LOGTO_M2M_APP_SECRET
ARG LOGTO_MANAGEMENT_API

# Verida connector: build-time
ARG ENABLE_VERIDA_CONNECTOR=false
Expand Down Expand Up @@ -93,12 +95,14 @@ ENV EXTERNAL_DB_CERT ${EXTERNAL_DB_CERT}
ENV ENABLE_AUTHENTICATION ${ENABLE_AUTHENTICATION}
ENV DEFAULT_CUSTOMER_ID ${DEFAULT_CUSTOMER_ID}
ENV LOGTO_ENDPOINT ${LOGTO_ENDPOINT}
ENV LOGTO_RESOURCE_URL ${LOGTO_RESOURCE_URL}
ENV LOGTO_DEFAULT_RESOURCE_URL ${LOGTO_DEFAULT_RESOURCE_URL}
ENV LOGTO_APP_ID ${LOGTO_APP_ID}
ENV LOGTO_APP_SECRET ${LOGTO_APP_SECRET}
ENV ALLOWED_ORIGINS ${ALLOWED_ORIGINS}
ENV ALL_SCOPES ${ALL_SCOPES}
ENV COOKIE_SECRET ${COOKIE_SECRET}
ENV LOGTO_M2M_APP_ID ${LOGTO_M2M_APP_ID}
ENV LOGTO_M2M_APP_SECRET ${LOGTO_M2M_APP_SECRET}
ENV LOGTO_MANAGEMENT_API ${LOGTO_MANAGEMENT_API}

# Environment variables: Verida connector
ENV ENABLE_VERIDA_CONNECTOR ${ENABLE_VERIDA_CONNECTOR}
Expand Down
7 changes: 4 additions & 3 deletions example.env
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,20 @@ EXTERNAL_DB_ENCRYPTION_KEY="<db-encryption-key>"
EXTERNAL_DB_CERT="<path/to/extenal-db-cert>"

# OpenId
LOGTO_RESOURCE_URL='http://localhost:8787'
LOGTO_DEFAULT_RESOURCE_URL='http://localhost:8787'

# LogTo
LOGTO_ENDPOINT='http://localhost:3001'
LOGTO_APP_ID='ldfsr...rq432'
LOGTO_APP_SECRET='sdf...sdf'
LOGTO_M2M_APP_ID="aaaa.....ddddd"
LOGTO_M2M_APP_SECRET="aaaa.....ddddd"
LOGTO_MANAGEMENT_API="https://default.logto.app/api"
COOKIE_SECRET='sdf...sdf'

# Authentication
ENABLE_AUTHENTICATION="false"
DEFAULT_CUSTOMER_ID="default customer id"
ALL_SCOPES="account:create did:create credential:issue"


# verida
ENABLE_VERIDA_CONNECTOR="string,default:false"
Expand Down
24 changes: 18 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"express-session": "^1.17.3",
"express-validator": "^7.0.1",
"helmet": "^7.0.0",
"json-stringify-safe": "^5.0.1",
"node-cache": "^5.1.2",
"pg": "^8.11.0",
"pg-connection-string": "^2.6.0",
Expand All @@ -90,6 +91,7 @@
"@types/express": "^4.17.17",
"@types/express-session": "^1.17.7",
"@types/helmet": "^4.0.0",
"@types/json-stringify-safe": "^5.0.0",
"@types/node": "^20.2.5",
"@types/secp256k1": "^4.0.3",
"@types/swagger-ui-express": "^4.1.3",
Expand Down
19 changes: 11 additions & 8 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@ dotenv.config()
import { UserInfo } from './controllers/user_info.js'
import path from 'path'

const swagger_options = {
customJs: '/static/custom-button.js',
let swagger_options = {}
if (process.env.ENABLE_AUTHENTICATION === 'true') {
swagger_options = {
customJs: '/static/custom-button.js',
}
}

class App {
Expand Down Expand Up @@ -55,9 +58,10 @@ class App {
this.express.use(cookieParser())
if (process.env.ENABLE_AUTHENTICATION === 'true') {
this.express.use(session({secret: process.env.COOKIE_SECRET, cookie: { maxAge: 14 * 24 * 60 * 60 }}))
this.express.use(Authentication.withLogtoWrapper)
this.express.use(Authentication.guard)
this.express.use(Authentication.wrapperHandleAuthRoutes)
}
this.express.use(handleAuthRoutes(configLogToExpress))
this.express.use(withLogto(configLogToExpress))
this.express.use(express.text())

this.express.use(
Expand All @@ -67,7 +71,6 @@ class App {
return res.send(swaggerUi.generateHTML(swaggerJSONDoc, swagger_options))
}
)
this.express.use(Authentication.guard)
this.express.use(Authentication.handleError)
this.express.use(Authentication.accessControl)
}
Expand All @@ -85,9 +88,9 @@ class App {
app.post('/credential/suspend', new CredentialController().suspend)
app.post('/credential/reinstate', new CredentialController().reinstate)

//revocation
app.post('/revocation/statusList2021/create', RevocationController.didValidator, RevocationController.statusListValidator, new RevocationController().createStatusList)
app.get('/revocation/statusList2021/list', RevocationController.didValidator, new RevocationController().fetchStatusList)
//credential-status
app.post('/credential-status/statusList2021/create', RevocationController.didValidator, RevocationController.statusListValidator, new RevocationController().createStatusList)
app.get('/credential-status/statusList2021/list', RevocationController.didValidator, new RevocationController().fetchStatusList)
// store
app.post(`/store`, new StoreController().set)
app.get(`/store/:id`, new StoreController().get)
Expand Down
2 changes: 1 addition & 1 deletion src/controllers/user_info.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Request, Response, NextFunction, json } from 'express'
import { Request, Response } from 'express'

import * as dotenv from 'dotenv'
dotenv.config()
Expand Down
19 changes: 19 additions & 0 deletions src/middleware/auth/account_auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Request, Response } from "express";
import { AbstractAuthHandler } from "./base_auth.js";
import { IAuthResponse } from "../../types/authentication.js";

export class AccountAuthHandler extends AbstractAuthHandler {

constructor () {
super()
this.registerRoute('/account', 'GET', 'read:account')
this.registerRoute('/account', 'POST', 'create:account')
}
public async handle(request: Request, response: Response): Promise<IAuthResponse> {
if (!request.path.includes('/account')) {
return super.handle(request, response)
}
return this.commonPermissionCheck(request)
}

}
Loading