Skip to content

Commit 128ea68

Browse files
authored
fix: gitea connect error & jwt decode (#681)
* test: connect gitea * test: jwt * test: jwt * test: jwt error * test: jwt * fix: jwt error * fix: jwt error * fix: jwt * fix: update jwt middleware & gitea connect
1 parent ec63c1b commit 128ea68

File tree

5 files changed

+35
-41
lines changed

5 files changed

+35
-41
lines changed

package-lock.json

Lines changed: 8 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"json-stable-stringify": "^1.0.1",
3434
"jsonpath": "^1.1.1",
3535
"jsonwebtoken": "^9.0.0",
36-
"jwt-decode": "^2.2.0",
36+
"jwt-decode": "^4.0.0",
3737
"lightship": "^6.7.2",
3838
"lodash": "^4.17.21",
3939
"lowdb": "^1.0.0",

src/app.ts

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
import $parser from '@apidevtools/json-schema-ref-parser'
44
import cors from 'cors'
55
import Debug from 'debug'
6-
import express, { request } from 'express'
6+
import express from 'express'
77
import 'express-async-errors'
88
import { initialize } from 'express-openapi'
99
import { Server } from 'http'
10-
import httpSignature from 'http-signature'
1110
import { createLightship } from 'lightship'
1211
import logger from 'morgan'
1312
import path from 'path'
13+
import { CleanOptions } from 'simple-git'
1414
import { default as Authz } from 'src/authz'
1515
import {
1616
authzMiddleware,
@@ -37,7 +37,6 @@ import {
3737
import swaggerUi from 'swagger-ui-express'
3838
import giteaCheckLatest from './gitea/connect'
3939
import { getBuildStatus, getSealedSecretStatus, getServiceStatus, getWorkloadStatus } from './k8s_operations'
40-
import { CleanOptions } from 'simple-git'
4140

4241
const env = cleanEnv({
4342
DRONE_WEBHOOK_SECRET,
@@ -61,8 +60,7 @@ type OtomiSpec = {
6160
const checkAgainstGitea = async () => {
6261
const encodedToken = Buffer.from(`${env.GIT_USER}:${env.GIT_PASSWORD}`).toString('base64')
6362
const otomiStack = await getSessionStack()
64-
const clusterInfo = otomiStack?.getSettings(['cluster'])
65-
const latestOtomiVersion = await giteaCheckLatest(encodedToken, clusterInfo)
63+
const latestOtomiVersion = await giteaCheckLatest(encodedToken)
6664
// check the local version against the latest online version
6765
// if the latest online is newer it will be pulled locally
6866
if (latestOtomiVersion && latestOtomiVersion.data[0].sha !== otomiStack.git.commitSha) {
@@ -176,27 +174,6 @@ export async function initApp(inOtomiStack?: OtomiStack | undefined) {
176174
setInterval(async function () {
177175
await checkAgainstGitea()
178176
}, gitCheckVersionInterval)
179-
app.all('/drone', async (req, res, next) => {
180-
const parsed = httpSignature.parseRequest(req, {
181-
algorithm: 'hmac-sha256',
182-
})
183-
if (!httpSignature.verifyHMAC(parsed, env.DRONE_WEBHOOK_SECRET)) return res.status(401).send()
184-
const event = req.headers['x-drone-event']
185-
res.send('ok')
186-
if (event !== 'build') return
187-
const io = getIo()
188-
// emit now to let others know, before doing anything else
189-
if (io) io.emit('drone', req.body)
190-
// deployment might have changed data, so reload
191-
const { build } = request.body || {}
192-
if (!build) return
193-
const { status } = build
194-
if (status === 'success') {
195-
const stack = await getSessionStack()
196-
debug('Drone deployed, root pull')
197-
await stack.git.pull()
198-
}
199-
})
200177
let server: Server | undefined
201178
if (!inOtomiStack) {
202179
// initialize full server

src/gitea/connect.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
import axios from 'axios'
22
import Debug from 'debug'
3+
import { cleanEnv, GIT_REPO_URL } from 'src/validators'
34

45
const debug = Debug('otomi:gitea-connect')
56

7+
const env = cleanEnv({
8+
GIT_REPO_URL,
9+
})
10+
611
// get call to the api to retrieve all the commits
7-
export default async function giteaCheckLatest(token: string, clusterData: any): Promise<any> {
8-
const domainSuffix: string | undefined = clusterData?.cluster?.domainSuffix
9-
const giteaUrl = `https://gitea.${domainSuffix}/api/v1/repos/otomi/values/commits`
10-
if (domainSuffix) {
12+
export default async function giteaCheckLatest(token: string): Promise<any> {
13+
// Extracts "http://gitea-http.gitea.svc.cluster.local:3000" or "https://gitea.<domainSuffix>"
14+
const baseDomain = new URL(env.GIT_REPO_URL).origin
15+
if (baseDomain) {
16+
const giteaUrl = `${baseDomain}/api/v1/repos/otomi/values/commits`
1117
const response = await axios({
1218
url: giteaUrl,
1319
method: 'GET',
@@ -18,7 +24,6 @@ export default async function giteaCheckLatest(token: string, clusterData: any):
1824
}).catch((error) => {
1925
debug('Gitea error: ', error.message)
2026
})
21-
2227
return response
2328
}
2429
}

src/middleware/jwt.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-disable no-param-reassign */
22
import { debug } from 'console'
33
import { RequestHandler } from 'express'
4-
import jwtDecode from 'jwt-decode'
4+
import { jwtDecode } from 'jwt-decode'
55
import { getMockEmail, getMockGroups, getMockName } from 'src/mocks'
66
import { JWT, OpenApiRequestExt, SessionUser } from 'src/otomi-models'
77
import OtomiStack from 'src/otomi-stack'
@@ -21,7 +21,7 @@ export function getUser(user: JWT, otomi: OtomiStack): SessionUser {
2121
}
2222
// keycloak does not (yet) give roles, so
2323
// for now we map correct group names to roles
24-
user.groups.forEach((group) => {
24+
user?.groups?.forEach((group) => {
2525
if (['platform-admin', 'all-teams-admin'].includes(group)) {
2626
if (!sessionUser.roles.includes('platformAdmin')) {
2727
sessionUser.isPlatformAdmin = true
@@ -70,8 +70,16 @@ export function jwtMiddleware(): RequestHandler {
7070
debug('anonymous request')
7171
return next()
7272
}
73-
const { name, email, roles, groups, sub } = jwtDecode(token)
74-
req.user = getUser({ name, email, roles, groups, sub }, otomi)
75-
return next()
73+
try {
74+
const { name, email, roles, groups, sub } = jwtDecode<JWT>(token)
75+
req.user = getUser({ name, email, roles, groups, sub }, otomi)
76+
return next()
77+
} catch (error) {
78+
debug('JWT decode fails:', error.message)
79+
return res.status(401).send({
80+
message: 'Unauthorized',
81+
error: 'JWT decode fails',
82+
})
83+
}
7684
}
7785
}

0 commit comments

Comments
 (0)