feat: apply auth to container and cli client

This commit is contained in:
wancat committed 2023-09-12 00:12:09 +08:00
1 parent 030dc95e24
commit 0f53696f71
8 files changed
+64 -27

No files matched your search

+40 -3
View File
@@ -57,21 +57,29 @@ async function lastSession() {
return session
}
async function connect(sessionId) {
async function connect(sessionId, token) {
console.log(`Session ID: ${sessionId}`)
console.log('Use Ctrl + D to exit.')
if (!sessionId) exit()
const socket = io(program.opts().host, {
auth: {
token,
},
query: {
session_id: sessionId,
},
})
socket.on('open', function open() {
socket.on('connection', function open() {
console.log('Connected to the server.')
})
socket.on('connect_error', (err) => {
console.error(err.message)
exit(1)
})
socket.on('message', console.log)
socket.on('terminal', function incoming(data) {
@@ -101,6 +109,26 @@ async function connect(sessionId) {
})
}
async function login() {
try {
const res = await api.post('/login/password', {
username: program.opts().user,
password: program.opts().password,
})
const { token } = res.data
if (!token) {
console.error(res.data)
exit(1)
}
console.log('Login success.')
return token
} catch (err) {
console.error(err.message)
exit(1)
return null
}
}
async function main() {
api = axios.create({
baseURL: `${program.opts().host}/api/v1`,
@@ -111,18 +139,27 @@ async function main() {
console.log(program.opts().session)
// main()
const token = await login()
api.defaults.headers.common.Authorization = `Bearer ${token}`
const sessionId =
program.opts().session ||
(program.opts().create ? (await createSession())._id : null) ||
(await lastSession())._id
await connect(sessionId)
await connect(sessionId, token)
}
program
.option('-s, --session <string>', 'Session ID')
.option('-c, --create', 'Create a new session')
.option('-d, --debug', 'Debug mode')
.option('-u, --user <string>', 'Username', get('USERNAME', 'testUser'))
.option(
'-p, --password <string>',
'Password',
get('PASSWORD', 'testPassword')
)
.option(
'-h, --host <string>',
'Server host',
+1 -1
View File
@@ -49,7 +49,6 @@ async function main() {
output,
error,
exit_code: CMD_EXIT_CODE,
token: TOKEN,
pwd: PWD,
...additionalData,
}
@@ -58,6 +57,7 @@ async function main() {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${TOKEN}`,
},
body: JSON.stringify(payload),
})
@@ -1,26 +1,18 @@
/* eslint-disable import/prefer-default-export */
import Command from '../../models/command.js'
import Session from '../../models/session.js'
import { verifySessionJWT } from '../../utils/auth.js'
import CommandHandler from '../../game/commandHandler.js'
export async function newCommand(req, res) {
console.log('new command:', req.body)
const { token, command, pwd, output, error, ...additionalData } = req.body
const { command, pwd, output, error, ...additionalData } = req.body
if (!command) {
res.status(400).json({ message: 'command is required' })
return
}
let sessionId
try {
const decoded = await verifySessionJWT(token)
sessionId = decoded.session_id
} catch (err) {
res.status(401).json({ message: 'token not valid' })
return
}
const sessionId = req.user.session_id
const session = await Session.findById(sessionId)
@@ -5,7 +5,7 @@ import SessionHandler from '../../game/sessionHandler.js'
export async function getSessionList(req, res) {
try {
const query = { user: req.user.id }
const query = { user: req.user._id }
if (req.query.quest_id) {
query.quest = req.query.quest_id
}
@@ -70,7 +70,7 @@ export async function getSessionById(req, res) {
try {
const session = await Session.findOne({
_id: req.params.id,
user: req.user.id,
user: req.user._id,
})
if (!session) {
@@ -88,7 +88,7 @@ export async function deleteSessionById(req, res) {
try {
const session = await Session.findOneAndDelete({
_id: req.params.id,
user: req.user.id,
user: req.user._id,
})
if (!session) {
+2 -2
View File
@@ -1,13 +1,13 @@
import { Router } from 'express'
import passport from 'passport'
import { genJwt } from '../../utils/auth.js'
import { genJWT } from '../../utils/auth.js'
const router = Router()
async function issueToken(req, res) {
const { user } = req
const token = await genJwt({
const token = await genJWT({
_id: user.id,
username: user.username,
email: user.email,
+11 -3
View File
@@ -1,7 +1,7 @@
import { Server } from 'socket.io'
import { getAndStartContainer, attachContainer } from '../containers/docker.js'
import Session from '../models/session.js'
import { defaultUser, genSessionJWT } from '../utils/auth.js'
import { genJWT, verifyJWT } from '../utils/auth.js'
const sessions = new Map()
@@ -45,7 +45,9 @@ async function connectClient(socket) {
return
}
const token = await genSessionJWT(session)
const token = await genJWT({
session_id: session.id,
})
let container
let stream
@@ -90,8 +92,14 @@ export default (server) => {
io.use(async (socket, next) => {
console.log('Authenticating...')
try {
const user = await defaultUser()
const { token } = socket.handshake.auth
if (!token) {
next(new Error('Token not found.'))
return
}
const user = await verifyJWT(token)
// eslint-disable-next-line no-param-reassign
console.log(user)
socket.user = user
next()
} catch (err) {
+1 -1
View File
@@ -27,7 +27,7 @@ export async function defaultUser() {
return user
}
export function genJwt(payload) {
export function genJWT(payload) {
return new Promise((resolve, reject) => {
jwt.sign(
payload,
+4 -4
View File
@@ -303,6 +303,10 @@ paths:
/commands:
post:
summary: Record a command that was executed in a session
tags:
- signed-in
security:
- BearerAuth: []
requestBody:
required: true
content:
@@ -433,13 +437,9 @@ components:
Command:
type: object
required:
- token
- pwd
- command
properties:
token:
type: string
description: The JWT token of the session
pwd:
type: string
example: '/root'