entity.ts 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /*
  2. * GET users listing.
  3. */
  4. import express = require('express');
  5. const router = express.Router();
  6. import Security from '../src/Security';
  7. import RouterUtils from '../src/RouterUtils';
  8. import { ILDAPManager } from '../src/ldapInterface';
  9. import { LDAPSchemaObjectClass, ClassType } from '../src/LDAPSchema';
  10. import ConfigManager from '../src/ConfigLoader';
  11. function LDAPEntryToAttributes(entry: Map<string, Array<string>>): any {
  12. let result: any = [];
  13. for (let [key, val] of entry)
  14. val.forEach(v => result.push({ key: key, val: v }));
  15. return result;
  16. }
  17. function getType(schema: Map<string, LDAPSchemaObjectClass>, klass: string): string {
  18. switch (schema.get(klass)?.GetType()) {
  19. case ClassType.eAbstract:
  20. return "abstract";
  21. case ClassType.eAuxiliary:
  22. return "auxiliary";
  23. case ClassType.eStructural:
  24. return "structural";
  25. }
  26. return "Unknown";
  27. }
  28. function StructifySchema(schema: Map<string, LDAPSchemaObjectClass>): any {
  29. let result: any = {};
  30. for (let [key, oc] of schema) {
  31. if (oc.GetType() === ClassType.eAbstract)
  32. continue;
  33. let description: any = {};
  34. for (let [key, val] of oc.ListDescriptions())
  35. description[key] = val;
  36. let obj = {
  37. may: oc.ListMayAttributes().filter(i => i.toLowerCase() !== 'objectclass'),
  38. must: oc.ListMustAttributes().filter(i => i.toLowerCase() !== 'objectclass'),
  39. structural: oc.GetType() === ClassType.eStructural,
  40. auxiliary: oc.GetType() === ClassType.eAuxiliary,
  41. descriptions: description,
  42. type: getType(schema, key)
  43. };
  44. result[key] = obj;
  45. }
  46. return result;
  47. }
  48. class AttributesByClasses {
  49. public constructor(entry: Map<string, string[]>, classes: Map<string, LDAPSchemaObjectClass>) {
  50. for (let eClass of entry.get("objectClass") || []) {
  51. this.fEntries.set(eClass, new Map());
  52. let cl = classes.get(eClass);
  53. cl && this.fObjectClasses.push(cl);
  54. }
  55. for (let [i, j] of entry) {
  56. if (i.toLowerCase() == 'objectclass')
  57. continue;
  58. let found = false;
  59. for (let oc of this.fObjectClasses) {
  60. if (oc.HasAttribute(i)) {
  61. this.fEntries.get(oc.GetName())?.set(i, j);
  62. found = true;
  63. }
  64. }
  65. if (!found)
  66. this.fUnmapped.set(i, j);
  67. }
  68. for (let klass of this.fObjectClasses) {
  69. let className = klass.GetName();
  70. let classContent = this.fEntries.get(className);
  71. if (!classContent) {
  72. classContent = new Map<string, string[]>();
  73. this.fEntries.set(className, classContent);
  74. }
  75. for (let attr of klass.ListAttributes())
  76. !classContent.has(attr) && !entry.has(attr) && classContent.set(attr, new Array());
  77. this.fEntries.set(className, classContent);
  78. }
  79. }
  80. public IsMandatoryAttr(attr: string): boolean {
  81. for (let klass of this.fObjectClasses)
  82. if (klass.HasMust(attr))
  83. return true;
  84. return false;
  85. }
  86. public ToMap(): any {
  87. let result: any = {};
  88. let classContent: any = {};
  89. result.members = { memberOf: this.fUnmapped?.get("memberOf") || [] };
  90. if (!result.members.memberOf.length)
  91. result = {};
  92. for (let [ocKey, vals] of this.fEntries) {
  93. classContent = {};
  94. for (let [i, j] of vals)
  95. classContent[i] = j.length ? j : [""];
  96. result[ocKey] = classContent;
  97. }
  98. return result;
  99. }
  100. public GetObjectClasses(): any {
  101. let result: any = [];
  102. for (let [ocKey, _] of this.fEntries)
  103. result.push(ocKey);
  104. result.sort();
  105. if (this.fUnmapped?.has("memberOf"))
  106. result.unshift('members');
  107. return result;
  108. }
  109. public ClassExists(className: string): boolean {
  110. return this.fEntries.has(className);
  111. }
  112. private fObjectClasses: LDAPSchemaObjectClass[] = new Array();
  113. private fEntries: Map<string, Map<string, string[]>> = new Map();
  114. private fUnmapped: Map<string, string[]> = new Map();
  115. }
  116. function StructifyEditLinks(input:Map<string, Array<string>>):any {
  117. const result:any = {};
  118. for (let i of input.keys())
  119. result[i] = input.get(i);
  120. return result;
  121. }
  122. router.get('/:dn', (req: express.Request, res: express.Response) => {
  123. if (!req.isUserLogged)
  124. return RouterUtils.Redirect(res, "/login");
  125. let ldapManager: ILDAPManager;
  126. let entry: Map<string, string[]>;
  127. req.ldapManager.GetInstance()
  128. .then(_ldapManager => { ldapManager = _ldapManager; return ldapManager.GetEntry(req.params.dn); })
  129. .then(_entry => { entry = _entry; return ldapManager.GetSchema() }).then(schema => {
  130. let classes: AttributesByClasses = new AttributesByClasses(entry, schema);
  131. let dn = (entry.get("dn") || [])[0];
  132. res.render('entity', {
  133. dn: dn || req.params.dn,
  134. attributes: classes.ToMap(),
  135. classes: classes.GetObjectClasses(),
  136. getType: (klass: string) => getType(schema, klass),
  137. isMandatory: (attr: string): boolean => classes.IsMandatoryAttr(attr),
  138. schema: StructifySchema(schema),
  139. editLinks: StructifyEditLinks(ConfigManager.GetInstance().GetLDAPEditLinks()),
  140. getUnusedClass: (): string[] => {
  141. let result = [];
  142. for (let [key, klass] of schema) {
  143. if (!classes.ClassExists(key) && klass.GetType() !== ClassType.eAbstract)
  144. result.push({ key: key, klass: klass });
  145. }
  146. return result.sort((a, b) => {
  147. if (a.klass.GetType() === ClassType.eStructural && b.klass.GetType() === ClassType.eAuxiliary)
  148. return -1;
  149. if (a.klass.GetType() === ClassType.eAuxiliary && b.klass.GetType() === ClassType.eStructural)
  150. return 1;
  151. return a.key.localeCompare(b.key);
  152. }).map(a => a.key);
  153. }
  154. });
  155. });
  156. });
  157. router.delete('/', (req: express.Request, res: express.Response) => {
  158. const session = Security.GetSession(req);
  159. if (!req.query["csrf"] || !req.query["dn"] || Array.isArray(req.query["csrf"]) || Array.isArray(req.query["dn"])) {
  160. res.sendStatus(400);
  161. return;
  162. }
  163. if (!session || !req.query["csrf"] || req.query["csrf"] !== session.GetCSRFToken()) {
  164. res.sendStatus(403);
  165. return;
  166. }
  167. req.ldapManager.GetInstance().then((ldap: ILDAPManager): void => {
  168. ldap.Remove(req.query["dn"]?.toString() || "")
  169. .then(() => {
  170. res.sendStatus(203);
  171. })
  172. .catch(err => {
  173. res.statusCode = 500;
  174. res.statusMessage = err;
  175. res.send();
  176. });
  177. });
  178. });
  179. export default router;