mirror of
https://github.com/sasjs/server.git
synced 2025-12-10 19:34:34 +00:00
feat: defined register permission and get all permissions api endpoints
This commit is contained in:
@@ -7,3 +7,4 @@ export * from './session'
|
||||
export * from './stp'
|
||||
export * from './user'
|
||||
export * from './info'
|
||||
export * from './permission'
|
||||
|
||||
176
api/src/controllers/permission.ts
Normal file
176
api/src/controllers/permission.ts
Normal file
@@ -0,0 +1,176 @@
|
||||
import {
|
||||
Security,
|
||||
Route,
|
||||
Tags,
|
||||
Path,
|
||||
Example,
|
||||
Get,
|
||||
Post,
|
||||
Delete,
|
||||
Body
|
||||
} from 'tsoa'
|
||||
|
||||
import Permission from '../model/Permission'
|
||||
import User from '../model/User'
|
||||
import Group from '../model/Group'
|
||||
import Client from '../model/Client'
|
||||
import { UserResponse } from './user'
|
||||
import { GroupResponse } from './group'
|
||||
|
||||
interface PermissionPayload {
|
||||
/**
|
||||
* Name of affected resource
|
||||
* @example "/SASjsApi/code/execute"
|
||||
*/
|
||||
uri: string
|
||||
/**
|
||||
* The indication of whether (and to what extent) access is provided
|
||||
* @example "Grant"
|
||||
*/
|
||||
setting: string
|
||||
/**
|
||||
* Indicates the type of principal
|
||||
* @example "user"
|
||||
*/
|
||||
principalType: string
|
||||
/**
|
||||
* The id of user(number), group(name), or client(clientId) to which a rule is assigned.
|
||||
* @example 123
|
||||
*/
|
||||
principalId: any
|
||||
}
|
||||
|
||||
interface PermissionDetailsResponse {
|
||||
permissionId: number
|
||||
uri: string
|
||||
setting: string
|
||||
user?: UserResponse
|
||||
group?: GroupResponse
|
||||
clientId?: string
|
||||
}
|
||||
|
||||
@Security('bearerAuth')
|
||||
@Route('SASjsApi/permission')
|
||||
@Tags('Permission')
|
||||
export class PermissionController {
|
||||
/**
|
||||
* @summary Get list of all permissions (uri, setting and userDetail).
|
||||
*
|
||||
*/
|
||||
@Example<PermissionDetailsResponse[]>([
|
||||
{
|
||||
permissionId: 123,
|
||||
uri: '/SASjsApi/code/execute',
|
||||
setting: 'Grant',
|
||||
user: { id: 1, username: 'johnSnow01', displayName: 'John Snow' }
|
||||
},
|
||||
{
|
||||
permissionId: 124,
|
||||
uri: '/SASjsApi/code/execute',
|
||||
setting: 'Grant',
|
||||
group: {
|
||||
groupId: 1,
|
||||
name: 'DCGroup',
|
||||
description: 'This group represents Data Controller Users'
|
||||
}
|
||||
},
|
||||
{
|
||||
permissionId: 125,
|
||||
uri: '/SASjsApi/code/execute',
|
||||
setting: 'Deny',
|
||||
clientId: 'clientId1'
|
||||
}
|
||||
])
|
||||
@Get('/')
|
||||
public async getAllPermissions(): Promise<PermissionDetailsResponse[]> {
|
||||
return getAllPermissions()
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Create a new permission. Admin only.
|
||||
*
|
||||
*/
|
||||
@Example<PermissionDetailsResponse>({
|
||||
permissionId: 123,
|
||||
uri: '/SASjsApi/code/execute',
|
||||
setting: 'Grant',
|
||||
user: { id: 1, username: 'johnSnow01', displayName: 'John Snow' }
|
||||
})
|
||||
@Post('/')
|
||||
public async createPermission(
|
||||
@Body() body: PermissionPayload
|
||||
): Promise<PermissionDetailsResponse> {
|
||||
return createPermission(body)
|
||||
}
|
||||
}
|
||||
|
||||
const getAllPermissions = async (): Promise<PermissionDetailsResponse[]> =>
|
||||
(await Permission.find({})
|
||||
.select({
|
||||
_id: 0,
|
||||
permissionId: 1,
|
||||
uri: 1,
|
||||
setting: 1
|
||||
})
|
||||
.populate({ path: 'user', select: 'id username displayName -_id' })
|
||||
.populate({
|
||||
path: 'group',
|
||||
select: 'groupId name description -_id'
|
||||
})
|
||||
.populate({
|
||||
path: 'client',
|
||||
select: 'clientId -_id'
|
||||
})) as unknown as PermissionDetailsResponse[]
|
||||
|
||||
const createPermission = async ({
|
||||
uri,
|
||||
setting,
|
||||
principalType,
|
||||
principalId
|
||||
}: PermissionPayload): Promise<PermissionDetailsResponse> => {
|
||||
const permission = new Permission({
|
||||
uri,
|
||||
setting
|
||||
})
|
||||
|
||||
let user, group, client
|
||||
|
||||
switch (principalType) {
|
||||
case 'user':
|
||||
user = await User.findOne({ id: principalId })
|
||||
if (!user) throw new Error('User not found.')
|
||||
permission.user = user._id
|
||||
break
|
||||
case 'group':
|
||||
group = await Group.findOne({ groupId: principalId })
|
||||
if (!group) throw new Error('Group not found.')
|
||||
permission.group = group._id
|
||||
break
|
||||
case 'client':
|
||||
client = await Client.findOne({ clientId: principalId })
|
||||
if (!client) throw new Error('Client not found.')
|
||||
permission.client = client._id
|
||||
break
|
||||
default:
|
||||
throw new Error('Invalid principal type.')
|
||||
}
|
||||
|
||||
const savedPermission = await permission.save()
|
||||
|
||||
return {
|
||||
permissionId: savedPermission.permissionId,
|
||||
uri: savedPermission.uri,
|
||||
setting: savedPermission.setting,
|
||||
user: !!user
|
||||
? { id: user.id, username: user.username, displayName: user.displayName }
|
||||
: undefined,
|
||||
group: !!group
|
||||
? {
|
||||
groupId: group.groupId,
|
||||
name: group.name,
|
||||
description: group.description
|
||||
}
|
||||
: undefined,
|
||||
clientId: !!client ? client.clientId : undefined
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import groupRouter from './group'
|
||||
import clientRouter from './client'
|
||||
import authRouter from './auth'
|
||||
import sessionRouter from './session'
|
||||
import permissionRouter from './permission'
|
||||
|
||||
const router = express.Router()
|
||||
|
||||
@@ -36,6 +37,7 @@ router.use('/group', desktopRestrict, groupRouter)
|
||||
router.use('/stp', authenticateAccessToken, stpRouter)
|
||||
router.use('/code', authenticateAccessToken, codeRouter)
|
||||
router.use('/user', desktopRestrict, userRouter)
|
||||
router.use('/permission', desktopRestrict, permissionRouter)
|
||||
router.use(
|
||||
'/',
|
||||
swaggerUi.serve,
|
||||
|
||||
35
api/src/routes/api/permission.ts
Normal file
35
api/src/routes/api/permission.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import express from 'express'
|
||||
import { PermissionController } from '../../controllers/'
|
||||
import { authenticateAccessToken, verifyAdmin } from '../../middlewares'
|
||||
import { registerPermissionValidation } from '../../utils'
|
||||
|
||||
const permissionRouter = express.Router()
|
||||
const controller = new PermissionController()
|
||||
|
||||
permissionRouter.get('/', authenticateAccessToken, async (req, res) => {
|
||||
try {
|
||||
const response = await controller.getAllPermissions()
|
||||
res.send(response)
|
||||
} catch (err: any) {
|
||||
res.status(403).send(err.toString())
|
||||
}
|
||||
})
|
||||
|
||||
permissionRouter.post(
|
||||
'/',
|
||||
authenticateAccessToken,
|
||||
verifyAdmin,
|
||||
async (req, res) => {
|
||||
const { error, value: body } = registerPermissionValidation(req.body)
|
||||
if (error) return res.status(400).send(error.details[0].message)
|
||||
|
||||
try {
|
||||
const response = await controller.createPermission(body)
|
||||
res.send(response)
|
||||
} catch (err: any) {
|
||||
res.status(403).send(err.toString())
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
export default permissionRouter
|
||||
Reference in New Issue
Block a user