-
-
Notifications
You must be signed in to change notification settings - Fork 24.2k
Expand file tree
/
Copy pathorganization-user.controller.ts
More file actions
167 lines (155 loc) · 8.36 KB
/
organization-user.controller.ts
File metadata and controls
167 lines (155 loc) · 8.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
import { NextFunction, Request, Response } from 'express'
import { StatusCodes } from 'http-status-codes'
import { InternalFlowiseError } from '../../errors/internalFlowiseError'
import { GeneralErrorMessage } from '../../utils/constants'
import { checkUsageLimit } from '../../utils/quotaUsage'
import { OrganizationUser } from '../database/entities/organization-user.entity'
import { Organization } from '../database/entities/organization.entity'
type OrganizationUserQuery = Partial<Pick<OrganizationUser, 'organizationId' | 'userId' | 'roleId'>>
import { QueryRunner } from 'typeorm'
import { Platform } from '../../Interface'
import { getRunningExpressApp } from '../../utils/getRunningExpressApp'
import { GeneralRole } from '../database/entities/role.entity'
import { User, UserStatus } from '../database/entities/user.entity'
import { WorkspaceUser } from '../database/entities/workspace-user.entity'
import { OrganizationUserService } from '../services/organization-user.service'
import { RoleService } from '../services/role.service'
import { WorkspaceService } from '../services/workspace.service'
import { assertQueryOrganizationMatchesActiveOrg, getLoggedInUser, userMayManageOrgUsers } from '../utils/tenantRequestGuards'
export class OrganizationUserController {
public async create(req: Request, res: Response, next: NextFunction) {
try {
const organizationUserservice = new OrganizationUserService()
const totalOrgUsers = await organizationUserservice.readOrgUsersCountByOrgId(req.body.organizationId)
const subscriptionId = req.user?.activeOrganizationSubscriptionId || ''
await checkUsageLimit('users', subscriptionId, getRunningExpressApp().usageCacheManager, totalOrgUsers + 1)
const newOrganizationUser = await organizationUserservice.createOrganizationUser(req.body)
return res.status(StatusCodes.CREATED).json(newOrganizationUser)
} catch (error) {
next(error)
}
}
public async read(req: Request, res: Response, next: NextFunction) {
let queryRunner
try {
const user = getLoggedInUser(req)
queryRunner = getRunningExpressApp().AppDataSource.createQueryRunner()
await queryRunner.connect()
const query = req.query as OrganizationUserQuery
const organizationUserservice = new OrganizationUserService()
assertQueryOrganizationMatchesActiveOrg(user, query.organizationId)
let organizationUser:
| {
organization: Organization
organizationUser: OrganizationUser | null
}
| OrganizationUser
| null
| OrganizationUser[]
| (OrganizationUser & {
roleCount: number
})[]
if (query.organizationId && query.userId) {
organizationUser = await organizationUserservice.readOrganizationUserByOrganizationIdUserId(
query.organizationId,
query.userId,
queryRunner
)
} else if (query.organizationId && query.roleId) {
if (!userMayManageOrgUsers(user)) {
throw new InternalFlowiseError(StatusCodes.FORBIDDEN, GeneralErrorMessage.FORBIDDEN)
}
organizationUser = await organizationUserservice.readOrganizationUserByOrganizationIdRoleId(
query.organizationId,
query.roleId,
queryRunner
)
} else if (query.organizationId) {
if (!userMayManageOrgUsers(user)) {
throw new InternalFlowiseError(StatusCodes.FORBIDDEN, GeneralErrorMessage.FORBIDDEN)
}
organizationUser = await organizationUserservice.readOrganizationUserByOrganizationId(query.organizationId, queryRunner)
} else if (query.userId) {
if (query.userId === user.id) {
organizationUser = await organizationUserservice.readOrganizationUserByUserId(query.userId, queryRunner)
} else {
if (!userMayManageOrgUsers(user)) {
throw new InternalFlowiseError(StatusCodes.FORBIDDEN, GeneralErrorMessage.FORBIDDEN)
}
organizationUser = await organizationUserservice.readOrganizationUserByOrganizationIdUserId(
user.activeOrganizationId,
query.userId,
queryRunner
)
}
} else {
throw new InternalFlowiseError(StatusCodes.BAD_REQUEST, GeneralErrorMessage.UNHANDLED_EDGE_CASE)
}
return res.status(StatusCodes.OK).json(organizationUser)
} catch (error) {
next(error)
} finally {
if (queryRunner) await queryRunner.release()
}
}
public async update(req: Request, res: Response, next: NextFunction) {
try {
const organizationUserService = new OrganizationUserService()
const organizationUser = await organizationUserService.updateOrganizationUser(req.body)
return res.status(StatusCodes.OK).json(organizationUser)
} catch (error) {
next(error)
}
}
public async delete(req: Request, res: Response, next: NextFunction) {
let queryRunner: QueryRunner | undefined
try {
queryRunner = getRunningExpressApp().AppDataSource.createQueryRunner()
const currentPlatform = getRunningExpressApp().identityManager.getPlatformType()
await queryRunner.connect()
const query = req.query as Partial<OrganizationUser>
if (!query.organizationId) {
throw new InternalFlowiseError(StatusCodes.BAD_REQUEST, 'Organization ID is required')
}
if (!query.userId) {
throw new InternalFlowiseError(StatusCodes.BAD_REQUEST, 'User ID is required')
}
const organizationUserService = new OrganizationUserService()
const workspaceService = new WorkspaceService()
const roleService = new RoleService()
let organizationUser: OrganizationUser
await queryRunner.startTransaction()
if (currentPlatform === Platform.ENTERPRISE) {
const personalRole = await roleService.readGeneralRoleByName(GeneralRole.PERSONAL_WORKSPACE, queryRunner)
const personalWorkspaces = await queryRunner.manager.findBy(WorkspaceUser, {
userId: query.userId,
roleId: personalRole.id
})
if (personalWorkspaces.length === 1)
// delete personal workspace
await workspaceService.deleteWorkspaceById(queryRunner, personalWorkspaces[0].workspaceId)
// remove user from other workspces
organizationUser = await organizationUserService.deleteOrganizationUser(queryRunner, query.organizationId, query.userId)
// soft delete user because they might workspace might created by them
const deleteUser = await queryRunner.manager.findOneBy(User, { id: query.userId })
if (!deleteUser) throw new InternalFlowiseError(StatusCodes.INTERNAL_SERVER_ERROR, GeneralErrorMessage.UNHANDLED_EDGE_CASE)
deleteUser.name = UserStatus.DELETED
deleteUser.email = `deleted_${deleteUser.id}_${Date.now()}@deleted.flowise`
deleteUser.status = UserStatus.DELETED
deleteUser.credential = null
deleteUser.tokenExpiry = null
deleteUser.tempToken = null
await queryRunner.manager.save(User, deleteUser)
} else {
organizationUser = await organizationUserService.deleteOrganizationUser(queryRunner, query.organizationId, query.userId)
}
await queryRunner.commitTransaction()
return res.status(StatusCodes.OK).json(organizationUser)
} catch (error) {
if (queryRunner && queryRunner.isTransactionActive) await queryRunner.rollbackTransaction()
next(error)
} finally {
if (queryRunner && !queryRunner.isReleased) await queryRunner.release()
}
}
}