mirror of
https://github.com/sasjs/server.git
synced 2025-12-11 19:44:35 +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 './stp'
|
||||||
export * from './user'
|
export * from './user'
|
||||||
export * from './info'
|
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 clientRouter from './client'
|
||||||
import authRouter from './auth'
|
import authRouter from './auth'
|
||||||
import sessionRouter from './session'
|
import sessionRouter from './session'
|
||||||
|
import permissionRouter from './permission'
|
||||||
|
|
||||||
const router = express.Router()
|
const router = express.Router()
|
||||||
|
|
||||||
@@ -36,6 +37,7 @@ router.use('/group', desktopRestrict, groupRouter)
|
|||||||
router.use('/stp', authenticateAccessToken, stpRouter)
|
router.use('/stp', authenticateAccessToken, stpRouter)
|
||||||
router.use('/code', authenticateAccessToken, codeRouter)
|
router.use('/code', authenticateAccessToken, codeRouter)
|
||||||
router.use('/user', desktopRestrict, userRouter)
|
router.use('/user', desktopRestrict, userRouter)
|
||||||
|
router.use('/permission', desktopRestrict, permissionRouter)
|
||||||
router.use(
|
router.use(
|
||||||
'/',
|
'/',
|
||||||
swaggerUi.serve,
|
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