Advertisement
djbob2000

Untitled

Jan 27th, 2025
11
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.15 KB | None | 0 0
  1. //server/fd/fd-toolbox-asp-net/permission-data-provider.ts
  2. import { FdMemoryCacheOptions } from "@server/fd/fd-toolbox/cachings/fd-memory-cache-options";
  3. import { Permission } from "@/fd/fd-toolbox-web/permissions/permission.resource";
  4. import { PermissionPackageToPermission } from "@/fd/fd-toolbox-web/permissions/permission-package-to-permission.resource";
  5. import { PermissionDto } from "@server/auth/permission-dto";
  6. import {
  7. PermissionLevel,
  8. permissionType,
  9. PermissionType,
  10. } from "@/fd/fd-toolbox-core/auth/permissions/permission-enums";
  11. import { setCoreCache, tryGetObjectFromCoreCache } from "@server/fd/fd-toolbox/cachings/core-memory-cache";
  12. import { addListValueToDictionary, addMapValueToMap } from "@server/fd/fd-toolbox/services/dictionaries";
  13. import { RoleToPermission } from "@server/auth/role-to-permission";
  14. import { getAllIncludingUserToRoles } from "@server/auth/role-db";
  15. import {
  16. resourceSchema,
  17. permissionSchema as permissionTable,
  18. roleToPermissionSchema,
  19. } from "@packages/plugin/schema";
  20. import { eq, getTableColumns } from "drizzle-orm";
  21. import { getQuery } from "@server/web/drizzle";
  22. import { UserRole } from "@/users/user-role.resource";
  23. import { getPermissionPackageToPermissions } from "../fd-toolbox-web/auth/permissions/permission-package-to-permission-db";
  24. import { getRoleToPermissionPackages } from "../fd-toolbox-web/models/roles/role-to-permission-package-db";
  25. import { getPermissionCacheKey, createShallowPermission } from "../fd-toolbox-web/permissions/permissions";
  26. import { fdCacheKeys } from "../fd-toolbox-web/constants/fd-cache-keys";
  27.  
  28. export async function getUserRoleIdsToRoleLevels() {
  29. const roles = await getAllIncludingUserToRoles();
  30.  
  31. const userRoleIdsLevels = new Map<string, Map<string, PermissionLevel>>();
  32.  
  33. for (const roleItem of roles) {
  34. if (roleItem.userRoleList) {
  35. for (const userRoleItem of roleItem.userRoleList.filter(
  36. (ur: UserRole) => ur.roleId === roleItem.id,
  37. )) {
  38. addMapValueToMap(userRoleIdsLevels, userRoleItem.userId, userRoleItem.roleId, roleItem.level);
  39. }
  40. }
  41. }
  42.  
  43. return userRoleIdsLevels;
  44. }
  45.  
  46. export async function saveRoleToPermissionsToCache(
  47. rolePackageToPermissions: Map<string, string[]>,
  48. ids: string[],
  49. type: PermissionType,
  50. ) {
  51. let cacheKeyPrefix: string = fdCacheKeys.roleToDefaultPermissions;
  52.  
  53. if (type === permissionType.resource) {
  54. cacheKeyPrefix = fdCacheKeys.roleToResourcePermissions;
  55. } else if (type === permissionType.property) {
  56. cacheKeyPrefix = fdCacheKeys.roleToPropertyPermissions;
  57. }
  58.  
  59. for (const id of ids) {
  60. await addMapFromCache(rolePackageToPermissions, id, cacheKeyPrefix);
  61.  
  62. if (!rolePackageToPermissions.has(id)) {
  63. await saveRoleToPermissionsToCacheById(id);
  64. await addMapFromCache(rolePackageToPermissions, id, cacheKeyPrefix);
  65. }
  66. }
  67.  
  68. return rolePackageToPermissions;
  69. }
  70.  
  71. export async function getRoleToPermissionList() {
  72. return getQuery(roleToPermissionSchema);
  73. }
  74.  
  75. export async function getUserPermissionCacheKey(type: PermissionType, userId: string) {
  76. return getPermissionCacheKey(type.toString(), userId);
  77. }
  78.  
  79. export async function getUserResourcePermissionCacheKey(
  80. type: PermissionType,
  81. resourceName: string,
  82. userId: string,
  83. ) {
  84. return getPermissionCacheKey(await getPermissionCacheKey(type.toString(), resourceName), userId);
  85. }
  86.  
  87. export async function saveUserPermissionsToMemoryCache(
  88. userPermissionKey: string,
  89. type: PermissionType,
  90. userPermissions: Map<string, PermissionDto>,
  91. ) {
  92. const cacheKey = await getUserPermissionCacheKey(type, userPermissionKey);
  93. await saveToMemoryCache(cacheKey, userPermissions);
  94. }
  95.  
  96. export async function getUserRoleIdsToRolePermissionLevels(userId: string) {
  97. const roleIdsLevels = new Map<string, PermissionLevel>();
  98. const memoryCacheKey = await getPermissionCacheKey(fdCacheKeys.userRolePermissionLevels, userId);
  99.  
  100. const cachedUserRoleIdsLevels = tryGetObjectFromCoreCache<Map<string, PermissionLevel>>(memoryCacheKey);
  101.  
  102. if (cachedUserRoleIdsLevels) {
  103. return cachedUserRoleIdsLevels;
  104. } else {
  105. await saveUserRoleIdsToRolePermissionLevelsToCache();
  106. const rolesToLevels = tryGetObjectFromCoreCache<Map<string, PermissionLevel>>(memoryCacheKey);
  107. if (rolesToLevels) {
  108. return rolesToLevels;
  109. }
  110. }
  111.  
  112. return roleIdsLevels;
  113. }
  114.  
  115. export async function savePackageToPermissionsToCache(
  116. rolePackageToPermissions: Map<string, string[]>,
  117. ids: string[],
  118. type: PermissionType,
  119. ) {
  120. let cacheKeyPrefix;
  121.  
  122. switch (type) {
  123. case permissionType.resource:
  124. cacheKeyPrefix = fdCacheKeys.packagesToResourcePermissions;
  125. break;
  126. case permissionType.property:
  127. cacheKeyPrefix = fdCacheKeys.packagesToPropertyPermissions;
  128. break;
  129. default:
  130. cacheKeyPrefix = fdCacheKeys.packagesToDefaultPermissions;
  131. }
  132.  
  133. for (const id of ids) {
  134. await addMapFromCache(rolePackageToPermissions, id, cacheKeyPrefix);
  135. if (!rolePackageToPermissions.has(id)) {
  136. await privateSavePackageToPermissionsToCache(id);
  137.  
  138. await addMapFromCache(rolePackageToPermissions, id, cacheKeyPrefix);
  139. }
  140. }
  141.  
  142. return rolePackageToPermissions;
  143. }
  144.  
  145. export async function getPermission(id: string) {
  146. let permission = tryGetObjectFromCoreCache<Permission>(
  147. await getPermissionCacheKey(fdCacheKeys.permission, id),
  148. );
  149.  
  150. if (permission) {
  151. return createShallowPermission(permission);
  152. } else {
  153. await savePermissionsToCache();
  154. permission = tryGetObjectFromCoreCache(await getPermissionCacheKey(fdCacheKeys.permission, id));
  155.  
  156. return permission && createShallowPermission(permission);
  157. }
  158. }
  159.  
  160. export async function addPackageToPermissions(
  161. rolesToPermissions: Map<string, string[]>,
  162. packageToPermissionList: PermissionPackageToPermission[],
  163. type: PermissionType,
  164. ) {
  165. for (const packageToPermission of packageToPermissionList) {
  166. const permission = await getPermission(packageToPermission.permissionId);
  167. if (permission?.type === type) {
  168. addListValueToDictionary(
  169. rolesToPermissions,
  170. packageToPermission.permissionPackageId,
  171. packageToPermission.permissionId,
  172. );
  173. }
  174. }
  175. }
  176.  
  177. async function createPermissionForCache(permission: {
  178. id: string;
  179. resourceId: string | null;
  180. resourcePropertyId: string | null;
  181. name: string | null;
  182. action: number | null;
  183. type: number;
  184. resource: { id: string; name: string } | null;
  185. }) {
  186. return createShallowPermission({
  187. id: permission.id,
  188. resourceId: permission.resourceId || undefined,
  189. resourcePropertyId: permission.resourcePropertyId || undefined,
  190. name: permission.name || undefined,
  191. action: permission.action ?? undefined,
  192. resource: permission.resource || undefined,
  193. type: permission.type,
  194. });
  195. }
  196.  
  197. export async function savePermissionsToCache() {
  198. const requiredColumns = {
  199. id: permissionTable.id,
  200. resourceId: permissionTable.resourceId,
  201. resourcePropertyId: permissionTable.resourcePropertyId,
  202. name: permissionTable.name,
  203. action: permissionTable.action,
  204. type: permissionTable.type,
  205. resource: getTableColumns(resourceSchema),
  206. };
  207.  
  208. const query = getQuery(permissionTable, requiredColumns);
  209. const permissions = await query.leftJoin(
  210. resourceSchema,
  211. eq(permissionTable.resourceId, resourceSchema.id),
  212. );
  213.  
  214. const cachePromises = permissions.map(async (permission) => {
  215. const cacheKey = await getPermissionCacheKey(fdCacheKeys.permission, permission.id);
  216. const permissionForCache = await createPermissionForCache(permission);
  217. return saveToMemoryCache(cacheKey, permissionForCache);
  218. });
  219.  
  220. await Promise.all(cachePromises);
  221. return true;
  222. }
  223.  
  224. export async function getRoleToPackages(ids: string[]) {
  225. const roleToPackages = new Map<string, string[]>();
  226.  
  227. for (const id of ids) {
  228. await addMapFromCache(roleToPackages, id, fdCacheKeys.roleToPackages);
  229. if (!roleToPackages.has(id)) {
  230. await saveRoleToPermissionPackagesToCache();
  231.  
  232. await addMapFromCache(roleToPackages, id, fdCacheKeys.roleToPackages);
  233. }
  234. }
  235.  
  236. return roleToPackages;
  237. }
  238.  
  239. async function addMapFromCache<T>(map: Map<string, T[]>, id: string, cacheKeyPrefix: string) {
  240. const memoryCacheKey = await getPermissionCacheKey(cacheKeyPrefix, id);
  241. const cachedValue = tryGetObjectFromCoreCache<T[]>(memoryCacheKey);
  242. if (cachedValue) {
  243. map.set(id, cachedValue);
  244. }
  245. }
  246.  
  247. async function saveRoleToPermissionsToCacheById(id: string) {
  248. const rolesToResourcePermissions: Map<string, string[]> = new Map();
  249. const rolesToDefaultPermissions: Map<string, string[]> = new Map();
  250. const rolesToPropertyPermissions: Map<string, string[]> = new Map();
  251.  
  252. const roleToPermissionList = await getRoleToPermissionList();
  253. let roleIds = [id, ...roleToPermissionList.map((x) => x.roleId)];
  254. roleIds = [...new Set(roleIds)];
  255.  
  256. await addRoleToPermissions(rolesToResourcePermissions, roleToPermissionList, permissionType.resource);
  257. await addRoleToPermissions(rolesToDefaultPermissions, roleToPermissionList, permissionType.default);
  258. await addRoleToPermissions(rolesToPropertyPermissions, roleToPermissionList, permissionType.property);
  259.  
  260. await saveToMemoryCacheByCacheKeyPrefix(
  261. rolesToResourcePermissions,
  262. fdCacheKeys.roleToResourcePermissions,
  263. );
  264. await saveToMemoryCacheByCacheKeyPrefix(rolesToDefaultPermissions, fdCacheKeys.roleToDefaultPermissions);
  265. await saveToMemoryCacheByCacheKeyPrefix(
  266. rolesToPropertyPermissions,
  267. fdCacheKeys.roleToPropertyPermissions,
  268. );
  269. }
  270.  
  271. async function addRoleToPermissions(
  272. rolesToPermissions: Map<string, string[]>,
  273. roleToPermissionList: RoleToPermission[],
  274. type: PermissionType,
  275. ) {
  276. for (const roleToPermissionItem of roleToPermissionList) {
  277. const permission = await getPermission(roleToPermissionItem.permissionId);
  278. if (permission?.type === type) {
  279. addListValueToDictionary(
  280. rolesToPermissions,
  281. roleToPermissionItem.roleId,
  282. roleToPermissionItem.permissionId,
  283. );
  284. }
  285. }
  286. }
  287.  
  288. async function applyPermissionsToPackages(
  289. permissionMap: Map<string, string[]>,
  290. permissionList: PermissionPackageToPermission[],
  291. permissionTypeParam: PermissionType,
  292. packageIds: string[],
  293. ) {
  294. await addPackageToPermissions(permissionMap, permissionList, permissionTypeParam);
  295.  
  296. if (permissionMap.size === 0) {
  297. for (const packId of packageIds) {
  298. permissionMap.set(packId, []);
  299. }
  300. }
  301. }
  302.  
  303. async function privateSavePackageToPermissionsToCache(id: string) {
  304. const packagesToResourcePermissions = new Map<string, string[]>();
  305. const packagesToDefaultPermissions = new Map<string, string[]>();
  306. const packagesToPropertyPermissions = new Map<string, string[]>();
  307.  
  308. const packageToPermissionList = await getPermissionPackageToPermissions();
  309.  
  310. let permissionPackageIds = [id];
  311.  
  312. permissionPackageIds = permissionPackageIds.concat(
  313. packageToPermissionList.map((x) => x.permissionPackageId),
  314. );
  315. permissionPackageIds = Array.from(new Set(permissionPackageIds));
  316.  
  317. await applyPermissionsToPackages(
  318. packagesToResourcePermissions,
  319. packageToPermissionList,
  320. permissionType.resource,
  321. permissionPackageIds,
  322. );
  323.  
  324. await applyPermissionsToPackages(
  325. packagesToDefaultPermissions,
  326. packageToPermissionList,
  327. permissionType.default,
  328. permissionPackageIds,
  329. );
  330.  
  331. await applyPermissionsToPackages(
  332. packagesToPropertyPermissions,
  333. packageToPermissionList,
  334. permissionType.property,
  335. permissionPackageIds,
  336. );
  337.  
  338. await saveToMemoryCacheByCacheKeyPrefix(
  339. packagesToResourcePermissions,
  340. fdCacheKeys.packagesToResourcePermissions,
  341. );
  342. await saveToMemoryCacheByCacheKeyPrefix(
  343. packagesToDefaultPermissions,
  344. fdCacheKeys.packagesToDefaultPermissions,
  345. );
  346. await saveToMemoryCacheByCacheKeyPrefix(
  347. packagesToPropertyPermissions,
  348. fdCacheKeys.packagesToPropertyPermissions,
  349. );
  350. }
  351.  
  352. async function saveRoleToPermissionPackagesToCache() {
  353. const rolesToPackages = new Map<string, string[]>();
  354.  
  355. const roleToPermissionPackageList = await getRoleToPermissionPackages();
  356.  
  357. for (const roleToPermissionPackage of roleToPermissionPackageList) {
  358. addListValueToDictionary(
  359. rolesToPackages,
  360. roleToPermissionPackage.roleId,
  361. roleToPermissionPackage.permissionPackageId,
  362. );
  363. }
  364.  
  365. await saveToMemoryCacheByCacheKeyPrefix(rolesToPackages, fdCacheKeys.roleToPackages);
  366. }
  367.  
  368. async function saveToMemoryCacheByCacheKeyPrefix(
  369. idsToPermissions: Map<string, string[]>,
  370. cacheKeyPrefix: string,
  371. ) {
  372. for (const [key, value] of idsToPermissions) {
  373. const newKey = await getPermissionCacheKey(cacheKeyPrefix, key);
  374. await saveToMemoryCache(newKey, value);
  375. }
  376. }
  377.  
  378. async function saveUserRoleIdsToRolePermissionLevelsToCache() {
  379. const userIdRoleIdsToRolePermissionLevels = await getUserRoleIdsToRoleLevels();
  380.  
  381. for (const [userId, rolePermissionLevels] of userIdRoleIdsToRolePermissionLevels.entries()) {
  382. const key = await getPermissionCacheKey(fdCacheKeys.userRolePermissionLevels, userId);
  383. await saveToMemoryCache(key, rolePermissionLevels);
  384. }
  385. }
  386.  
  387. async function saveToMemoryCache<T extends object>(key: string, value: T) {
  388. const fdMemoryCacheOptions: FdMemoryCacheOptions = {
  389. absoluteExpirationRelativeToNowSeconds: 24 * fdCacheKeys.secondsInAHour,
  390. };
  391.  
  392. setCoreCache(key, value, fdMemoryCacheOptions);
  393. }
  394.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement