LDAPSchema.ts 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import { findSourceMap } from "node:module";
  2. import { markAsUntransferable } from "node:worker_threads";
  3. import { LDAPAttribute } from "./ConfigLoader";
  4. export enum ClassType {
  5. eUnknown,
  6. eAbstract,
  7. eStructural,
  8. eAuxiliary
  9. }
  10. abstract class LDAPSchemaItem {
  11. public constructor(def: string) {
  12. this.fDefinition = def;
  13. this.fName = def.match(/NAME[\s\(]+'([^']+)'/)?.pop() || "";
  14. this.fDescription = def.match(/DESC\s+'([^']+)'/)?.pop() || "";
  15. this.fAliases = (def.match(/NAME\s*\(\s*([^\)]+)\)/)?.pop() || "").split(/\s+/).map(i => i.startsWith("'") ? i.substr(1, i.length - 2) : i).filter(i => i.length);
  16. if (this.fAliases.indexOf(this.fName) === -1)
  17. this.fAliases.push(this.fName);
  18. }
  19. public GetName(): string {
  20. return this.fName;
  21. }
  22. public GetDescription(): string {
  23. return this.fDescription;
  24. }
  25. public Match(str: string): boolean {
  26. for (let i of this.fAliases)
  27. if (i.toLowerCase() == str)
  28. return true;
  29. return false;
  30. }
  31. protected readonly fDefinition: string;
  32. private fName: string;
  33. private fAliases: Array<string>;
  34. private fDescription: string;
  35. }
  36. function Find(key: string, arr: Iterable<LDAPSchemaItem>): LDAPSchemaItem | null {
  37. key = key.toLowerCase();
  38. for (let i of arr)
  39. if (i.Match(key))
  40. return i;
  41. return null;
  42. }
  43. export class LDAPSchemaAttribute extends LDAPSchemaItem{
  44. public constructor(def: string) {
  45. super(def);
  46. this.fSyntax = def.match(/SYNTAX\s+([0-9\.]+)/)?.pop() || null;
  47. }
  48. private fSyntax: string|null;
  49. }
  50. export class LDAPSchemaObjectClass extends LDAPSchemaItem {
  51. public constructor(def: string, attributeDic: Map<string, LDAPSchemaAttribute>) {
  52. super(def);
  53. const abstract = /\s+ABSTRACT\s+/.test(def) ? 1 : 0;
  54. const aux = /\s+AUXILIARY\s+/.test(def) ? 1 : 0;
  55. const structural = /\s+STRUCTURAL\s+/.test(def) ? 1 : 0;
  56. if (abstract + aux + structural !== 1)
  57. this.fType = ClassType.eUnknown;
  58. else if (abstract)
  59. this.fType = ClassType.eAbstract;
  60. else if (aux)
  61. this.fType = ClassType.eAuxiliary;
  62. else if (structural)
  63. this.fType = ClassType.eStructural;
  64. else
  65. this.fType = ClassType.eUnknown;
  66. this.fParent = def.match(/\s+SUP\s+([^\s]+)\s/)?.pop() || null;
  67. }
  68. private defToAttributes(type: string): string[] {
  69. const reg = type === "MUST" ? /\s+MUST\s+(\w+|\([^\)]+\))/ : /\s+MAY\s+(\w+|\([^\)]+\))/;
  70. const res = (this.fDefinition.match(reg) || [])[1];
  71. if (!res)
  72. return new Array();
  73. let result = new Array();
  74. if (!res.startsWith('(')) {
  75. result.push(res.trim());
  76. return result;
  77. }
  78. for (let i of res.substr(1, res.length -2).split("$"))
  79. result.push(i.trim());
  80. return result;
  81. }
  82. public Consolidate(classes: Map<string, LDAPSchemaObjectClass>, attributes: Map<string, LDAPSchemaAttribute>) {
  83. if (this.fFinalized)
  84. return;
  85. this.fFinalized = true;
  86. let parent = this.fParent ? (Find(this.fParent, classes.values()) as LDAPSchemaObjectClass|null) : null;
  87. if (parent) {
  88. parent.Consolidate(classes, attributes);
  89. for (let [key, attr] of parent.fMayAttributes) {
  90. if (!this.fMustAttributes.has(key))
  91. this.fMayAttributes.set(key, attr);
  92. }
  93. for (let [key, attr] of parent.fMustAttributes) {
  94. this.fMustAttributes.set(key, attr);
  95. if (this.fMayAttributes.has(key))
  96. this.fMayAttributes.delete(key);
  97. }
  98. }
  99. for (let mustAttr of this.defToAttributes("MUST")) {
  100. if (this.fMustAttributes.has(mustAttr))
  101. continue;
  102. if (this.fMayAttributes.has(mustAttr))
  103. this.fMayAttributes.delete(mustAttr);
  104. let attr = Find(mustAttr, attributes.values()) as LDAPSchemaAttribute|null;
  105. attr && this.fMustAttributes.set(mustAttr, attr);
  106. }
  107. for (let mayAttr of this.defToAttributes("MAY")) {
  108. if (this.fMayAttributes.has(mayAttr) || this.fMustAttributes.has(mayAttr))
  109. continue;
  110. let attr = Find(mayAttr, attributes.values()) as LDAPSchemaAttribute | null;
  111. attr && this.fMayAttributes.set(mayAttr, attr);
  112. }
  113. return;
  114. }
  115. public HasAttribute(key: string): boolean {
  116. return !!(Find(key, this.fMayAttributes.values()) || Find(key, this.fMustAttributes.values()));
  117. }
  118. public HasMust(attr: string): boolean {
  119. return this.fMustAttributes.has(attr);
  120. }
  121. public ListDescriptions(): Map<string, string> {
  122. let result = new Map();
  123. for (let [key, data] of this.fMayAttributes) result.set(key, data.GetDescription());
  124. for (let [key, data] of this.fMustAttributes) result.set(key, data.GetDescription());
  125. return result;
  126. }
  127. public ListMayAttributes(): string[] {
  128. let result = new Array();
  129. for (let [key, _] of this.fMayAttributes) result.push(key);
  130. return result;
  131. }
  132. public ListMustAttributes(): string[] {
  133. let result = new Array();
  134. for (let [key, _] of this.fMustAttributes) result.push(key);
  135. return result;
  136. }
  137. public ListAttributes(): string[] {
  138. let result = new Array();
  139. for (let [key, _] of this.fMustAttributes) result.push(key);
  140. for (let [key, _] of this.fMayAttributes) result.push(key);
  141. return result;
  142. }
  143. public GetType(): ClassType {
  144. return this.fType;
  145. }
  146. private fParent: string|null;
  147. private fType: ClassType;
  148. private fFinalized: boolean = false;
  149. private fMayAttributes: Map<string, LDAPSchemaAttribute> = new Map();
  150. private fMustAttributes: Map<string, LDAPSchemaAttribute> = new Map();
  151. }