chyz 1.0.13-rc.9 → 1.1.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/BaseChyz.ts +74 -20
  2. package/Doc/Moel kullanma.md +13 -0
  3. package/Examples/Controllers/ApiController.ts +22 -22
  4. package/Examples/Controllers/BasicApiController.ts +121 -0
  5. package/Examples/Controllers/SiteController.ts +18 -8
  6. package/Examples/Models/AuthAssignment.ts +50 -0
  7. package/Examples/Models/AuthItem.ts +59 -0
  8. package/Examples/Models/AuthItemChild.ts +49 -0
  9. package/Examples/Models/Categories.ts +4 -0
  10. package/Examples/Models/KeycloakUser.ts +4 -0
  11. package/Examples/Models/User.ts +30 -2
  12. package/Examples/index.ts +22 -2
  13. package/Examples/log/app.log +14466 -0
  14. package/Examples/log/errors.log +594 -0
  15. package/Examples/package.json +5 -2
  16. package/README.md +265 -12
  17. package/base/ActionFilter.ts +1 -1
  18. package/base/BaseError.ts +4 -2
  19. package/base/DbConnection.ts +9 -5
  20. package/base/Model.ts +231 -30
  21. package/base/ModelManager.ts +6 -1
  22. package/base/RestClient.ts +4 -4
  23. package/base/ValidationHttpException.ts +1 -1
  24. package/dist/BaseChyz.js +61 -14
  25. package/dist/BaseChyz.js.map +1 -1
  26. package/dist/base/ActionFilter.js +1 -1
  27. package/dist/base/ActionFilter.js.map +1 -1
  28. package/dist/base/BaseError.js +6 -2
  29. package/dist/base/BaseError.js.map +1 -1
  30. package/dist/base/DbConnection.js +1 -0
  31. package/dist/base/DbConnection.js.map +1 -1
  32. package/dist/base/Model.js +192 -4
  33. package/dist/base/Model.js.map +1 -1
  34. package/dist/base/ModelManager.js +0 -8
  35. package/dist/base/ModelManager.js.map +1 -1
  36. package/dist/base/RestClient.js +4 -4
  37. package/dist/base/RestClient.js.map +1 -1
  38. package/dist/base/ValidationHttpException.js +1 -1
  39. package/dist/filters/AccessControl.js +15 -3
  40. package/dist/filters/AccessControl.js.map +1 -1
  41. package/dist/filters/AccessRule.js +99 -38
  42. package/dist/filters/AccessRule.js.map +1 -1
  43. package/dist/filters/auth/HttpBasicAuth.js +65 -0
  44. package/dist/filters/auth/HttpBasicAuth.js.map +1 -1
  45. package/dist/filters/auth/index.js +1 -0
  46. package/dist/filters/auth/index.js.map +1 -1
  47. package/dist/package.json +6 -4
  48. package/dist/rbac/AuthAssignment.js +45 -0
  49. package/dist/rbac/AuthAssignment.js.map +1 -0
  50. package/dist/rbac/AuthItem.js +52 -0
  51. package/dist/rbac/AuthItem.js.map +1 -0
  52. package/dist/rbac/AuthItemChild.js +44 -0
  53. package/dist/rbac/AuthItemChild.js.map +1 -0
  54. package/dist/rbac/AuthManager.js +13 -5
  55. package/dist/rbac/AuthManager.js.map +1 -1
  56. package/dist/requiments/Utils.js +5 -1
  57. package/dist/requiments/Utils.js.map +1 -1
  58. package/dist/web/WebUser.js +78 -0
  59. package/dist/web/WebUser.js.map +1 -1
  60. package/filters/AccessControl.ts +19 -6
  61. package/filters/AccessRule.ts +61 -16
  62. package/filters/auth/HttpBasicAuth.ts +68 -0
  63. package/filters/auth/index.ts +1 -0
  64. package/package.json +6 -4
  65. package/rbac/AuthAssignment.ts +50 -0
  66. package/rbac/AuthItem.ts +57 -0
  67. package/rbac/AuthItemChild.ts +50 -0
  68. package/rbac/AuthManager.ts +19 -9
  69. package/requiments/Utils.ts +6 -0
  70. package/web/IdentityInterface.ts +7 -1
  71. package/web/WebUser.ts +88 -1
@@ -5,3 +5,71 @@
5
5
  * Github:https://github.com/cihan53/
6
6
  */
7
7
 
8
+ import {HttpHeaderAuth} from "./HttpHeaderAuth";
9
+ import {Request, Response} from "express";
10
+ import {WebUser} from "../../web/WebUser";
11
+ import Utils from "../../requiments/Utils";
12
+ import {AuthMethod} from "./AuthMethod";
13
+ import {InvalidConfigException} from "../../base";
14
+ import BaseChyz from "../../BaseChyz";
15
+
16
+ export class HttpBasicAuth extends AuthMethod {
17
+
18
+ /**
19
+ * @var string the HTTP header name
20
+ */
21
+ public header = 'Authorization';
22
+
23
+
24
+ /**
25
+ * @var string a pattern to use to extract the HTTP authentication value
26
+ */
27
+
28
+ public pattern = /^Basic\s+(.*?)$/;
29
+
30
+
31
+ /**
32
+ * @throws InvalidConfigException
33
+ */
34
+ public init(): void {
35
+ super.init();
36
+
37
+ if (!this.pattern) {
38
+ throw new InvalidConfigException('You must provide pattern to use to extract the HTTP authentication value!');
39
+ }
40
+
41
+ this.user = BaseChyz.getComponent("user") ?? null;
42
+ }
43
+
44
+
45
+ async authenticate(user: WebUser, request:Request, response:Response) {
46
+
47
+
48
+ let autHeader = this.getHeaderByKey(request.headers, this.header)
49
+ if (autHeader == null || (autHeader = this.patternCheck(autHeader, this.pattern)) == null) {
50
+ return null;
51
+ }
52
+
53
+ let basicauth = autHeader[1].split(":")
54
+
55
+ let identity = await user.loginByAccessToken(basicauth, "HttpBasicAuth");
56
+ if (identity === null) {
57
+ this.challenge(response);
58
+ this.handleFailure(response);
59
+ }
60
+
61
+ return identity;
62
+
63
+
64
+ return null;
65
+ }
66
+
67
+
68
+ /**
69
+ * @throws UnauthorizedHttpException
70
+ */
71
+ public fail(response:Response): void {
72
+ this.challenge(response)
73
+ this.handleFailure(response);
74
+ }
75
+ }
@@ -1,3 +1,4 @@
1
1
  export * from "./JwtHttpBearerAuth"
2
2
  export * from "./HttpBearerAuth"
3
3
  export * from "./HttpHeaderAuth"
4
+ export * from "./HttpBasicAuth"
package/package.json CHANGED
@@ -1,13 +1,11 @@
1
1
  {
2
2
  "name": "chyz",
3
- "version": " 1.0.13-rc.9",
3
+ "version": "1.1.0-rc.2",
4
4
  "description": "Nodejs Micro service Framework",
5
- "main": "dist/index.js",
6
5
  "scripts": {
7
6
  "dev": "nodemon -t --trace-warnings index.ts",
8
7
  "debug": "ts-node index.ts",
9
8
  "build": "rmdir /S /Q .\\dist && npx tsc && xcopy .\\log .\\dist\\log /e /i /h /Y && copy .\\package.json .\\dist\\package.json",
10
- "publish": "cd dist && npm publish",
11
9
  "test": "echo \"Error: no test specified\" && exit 1",
12
10
  "postversion": "git push && git push --tags"
13
11
  },
@@ -39,6 +37,7 @@
39
37
  "pg-hstore": "^2.3.4",
40
38
  "reflect-metadata": "^0.1.13",
41
39
  "sequelize": "^6.6.5",
40
+ "sequelize-transparent-cache": "^2.3.0",
42
41
  "validate.js": "^0.13.1"
43
42
  },
44
43
  "devDependencies": {
@@ -52,6 +51,9 @@
52
51
  "keywords": [
53
52
  "Framework",
54
53
  "RespAPI",
55
- "microservice"
54
+ "microservice",
55
+ "micro service",
56
+ "easy configuration",
57
+ "Rbac support"
56
58
  ]
57
59
  }
@@ -0,0 +1,50 @@
1
+ /*
2
+ * Copyright (c) 2021. Chy Bilgisayar Bilisim
3
+ * Author: Cihan Ozturk
4
+ * E-mail: cihan@chy.com.tr
5
+ * Github:https://github.com/cihan53/
6
+ */
7
+
8
+ import {DataTypes, Model, ModelManager, Relation} from "../base";
9
+
10
+ export class AuthAssignmentClass extends Model {
11
+ [x: string]: any;
12
+
13
+ tableName() {
14
+ return 'auth_assignment';
15
+ }
16
+ attributes() {
17
+ return {
18
+
19
+ // Model attributes are defined here
20
+ item_name: {
21
+ type: DataTypes.STRING,
22
+ primaryKey:true,
23
+ allowNull: false
24
+ },
25
+ user_id : {
26
+ type: DataTypes.STRING,
27
+ allowNull: false
28
+ }
29
+
30
+ }
31
+ }
32
+
33
+ init(){
34
+ super.init();
35
+ this.model().removeAttribute('id')
36
+ }
37
+
38
+ relations(): Relation[] {
39
+ return [
40
+ {
41
+ type: "hasMany",
42
+ foreignKey: "name",
43
+ sourceKey:'item_name',
44
+ model: ModelManager.AuthItem.model()
45
+ }
46
+ ]
47
+ }
48
+
49
+ }
50
+
@@ -0,0 +1,57 @@
1
+ /*
2
+ * Copyright (c) 2021. Chy Bilgisayar Bilisim
3
+ * Author: Cihan Ozturk
4
+ * E-mail: cihan@chy.com.tr
5
+ * Github:https://github.com/cihan53/
6
+ */
7
+
8
+ import {DataTypes, Model, ModelManager, Relation} from "../base";
9
+
10
+ export class AuthItemClass extends Model {
11
+ [x: string]: any;
12
+
13
+ tableName() {
14
+ return 'auth_item';
15
+ }
16
+
17
+ attributes() {
18
+ return {
19
+ // Model attributes are defined here
20
+ name: {
21
+ type: DataTypes.STRING,
22
+ primaryKey:true,
23
+ allowNull: false
24
+ },
25
+ type: {
26
+ type: DataTypes.INTEGER,
27
+ allowNull: false
28
+ },
29
+ description: {
30
+ type: DataTypes.STRING,
31
+ allowNull: false
32
+ },
33
+ rule_name: {
34
+ type: DataTypes.STRING,
35
+ allowNull: false
36
+ }
37
+
38
+ }
39
+ }
40
+
41
+ init() {
42
+ super.init();
43
+ this.model().removeAttribute('id')
44
+ }
45
+
46
+ relations(): Relation[] {
47
+ return [
48
+ {
49
+ type: "hasOne",
50
+ foreignKey: "item_name",
51
+ model: ModelManager.AuthAssignment.model()
52
+ }
53
+ ]
54
+ }
55
+
56
+ }
57
+
@@ -0,0 +1,50 @@
1
+ /*
2
+ * Copyright (c) 2021. Chy Bilgisayar Bilisim
3
+ * Author: Cihan Ozturk
4
+ * E-mail: cihan@chy.com.tr
5
+ * Github:https://github.com/cihan53/
6
+ */
7
+
8
+
9
+
10
+ import {DataTypes, Model, ModelManager, Relation} from "../base";
11
+
12
+ export class AuthItemChildClass extends Model {
13
+ [x: string]: any;
14
+
15
+ tableName() {
16
+ return 'auth_item_child';
17
+ }
18
+
19
+ attributes() {
20
+ return {
21
+ // Model attributes are defined here
22
+ parent: {
23
+ type: DataTypes.STRING,
24
+ primaryKey:true,
25
+ allowNull: false
26
+ },
27
+ child: {
28
+ type: DataTypes.STRING,
29
+ allowNull: false
30
+ }
31
+ }
32
+ }
33
+
34
+ init() {
35
+ super.init();
36
+ this.model().removeAttribute('id')
37
+ }
38
+
39
+ relations(): Relation[] {
40
+ return [
41
+ {
42
+ type: "hasOne",
43
+ foreignKey: "item_name",
44
+ model: ModelManager.AuthAssignment.model()
45
+ }
46
+ ]
47
+ }
48
+
49
+ }
50
+
@@ -1,4 +1,4 @@
1
- import {Component, ModelManager} from "../base";
1
+ import {Component, DataErrorDbException, InvalidConfigException, ModelManager, UnauthorizedHttpException} from "../base";
2
2
  import {BaseChyz, InvalidArgumentException} from "../index";
3
3
  import Utils from "../requiments/Utils";
4
4
 
@@ -9,6 +9,7 @@ interface Role {
9
9
  description: string;
10
10
  ruleName: string;
11
11
  data: string;
12
+ params: string;
12
13
  }
13
14
 
14
15
  interface Permission {
@@ -17,6 +18,7 @@ interface Permission {
17
18
  description: string;
18
19
  ruleName: string;
19
20
  data: string;
21
+ params: string;
20
22
  }
21
23
 
22
24
 
@@ -40,7 +42,7 @@ export class AuthManager extends Component {
40
42
  *
41
43
  */
42
44
 
43
- public async checkAccess(userId: number, permissionName: string, params: any[] = []) {
45
+ public async checkAccess(userId: number, permissionName: string, params: any[] = []): Promise<boolean> {
44
46
  let assignments: any;
45
47
  if (!this.checkAccessAssignments[userId.toString()]) {
46
48
  assignments = await this.getAssignments(userId);
@@ -64,7 +66,7 @@ export class AuthManager extends Component {
64
66
 
65
67
  }
66
68
 
67
- public async checkAccessRecursive(user: string | number, itemname: string, params: any[], assignments: any[]) {
69
+ public async checkAccessRecursive(user: string | number, itemname: string, params: any[], assignments: any): Promise<boolean> {
68
70
  let item: any = await this.getItem(itemname);
69
71
  if (!item) return false;
70
72
 
@@ -73,12 +75,16 @@ export class AuthManager extends Component {
73
75
  * Rule test edilmeli
74
76
  */
75
77
 
78
+ if (assignments[itemname] || Utils.find(this.defaultRoles, itemname)) {
79
+ return true;
80
+ }
81
+
76
82
  /**
77
83
  * item child
78
84
  */
79
- let parents = await ModelManager.AuthItemChild.findAll({where: {child: itemname}});
85
+ let parents = await ModelManager.AuthItemChild.findAll({attributes:["parent"], where: {child: itemname}});
80
86
  for (const parent of parents) {
81
- let r = await this.checkAccessRecursive(user, parent, params, assignments);
87
+ let r = await this.checkAccessRecursive(user, parent.parent, params, assignments);
82
88
  if (r) {
83
89
  return true;
84
90
  }
@@ -342,11 +348,15 @@ export class AuthManager extends Component {
342
348
  }
343
349
 
344
350
  let assignments: any = {};
345
- let as = await ModelManager.AuthAssignment.findAll({where: {user_id: userId.toString()}});
346
- for (const a of as) {
347
- assignments[a["item_name"]] = a;
348
- }
351
+ try {
349
352
 
353
+ let as = await ModelManager.AuthAssignment.findAll({where: {user_id: userId.toString()}});
354
+ for (const a of as) {
355
+ assignments[a["item_name"]] = a;
356
+ }
357
+ } catch (e) {
358
+ throw new InvalidConfigException('The user application component must be available to specify roles in AccessRule.');
359
+ }
350
360
  return assignments;
351
361
  }
352
362
 
@@ -48,7 +48,13 @@ function wildTest(wildcard: string, str: string) {
48
48
  const matchWildcard = (pattern: string, string: string, options: any = {}) => {
49
49
  return wildTest(pattern, string)
50
50
  }
51
+
52
+ const t = function (text: string) {
53
+ return text;
54
+ }
55
+
51
56
  export default {
57
+ t,
52
58
  createObject,
53
59
  findKeyValue,
54
60
  sleep,
@@ -59,4 +59,10 @@ export interface IdentityInterface {
59
59
  */
60
60
  validateAuthKey(authKey: string): (boolean | null);
61
61
 
62
- }
62
+
63
+ /**
64
+ *
65
+ */
66
+ can(permissionName:string, params: any[] , allowCaching: boolean ): (boolean | null);
67
+
68
+ }
package/web/WebUser.ts CHANGED
@@ -9,6 +9,8 @@ import {Component} from "../base/Component";
9
9
  import {ForbiddenHttpException} from "../base/ForbiddenHttpException";
10
10
  import {InvalidConfigException} from "../base/InvalidConfigException";
11
11
  import {IdentityInterface} from "./IdentityInterface";
12
+ import Utils from "../requiments/Utils";
13
+ import {AuthManager} from "../rbac/AuthManager";
12
14
 
13
15
  export class WebUser extends Component {
14
16
 
@@ -17,6 +19,13 @@ export class WebUser extends Component {
17
19
  */
18
20
  public identityClass: any;
19
21
  private _identity: any;
22
+ /**
23
+ * @var CheckAccessInterface|string|array The access checker object to use for checking access or the application
24
+ * component ID of the access checker.
25
+ * If not set the application auth manager will be used.
26
+ * @since 2.0.9
27
+ */
28
+ public accessChecker: any = null;
20
29
 
21
30
 
22
31
  get identity() {
@@ -75,7 +84,7 @@ export class WebUser extends Component {
75
84
  if (this.identity && this.login(this.identity)) {
76
85
  return this.identity;
77
86
  }
78
- }else{
87
+ } else {
79
88
  BaseChyz.error("WebUser::findIdentityByAccessToken undefined")
80
89
  }
81
90
  return null;
@@ -97,4 +106,82 @@ export class WebUser extends Component {
97
106
  public afterLogin() {
98
107
 
99
108
  }
109
+
110
+ public getId() {
111
+ let identity = this.getIdentity();
112
+ return identity !== null ? identity.id : null;
113
+ }
114
+
115
+ /**
116
+ * Checks if the user can perform the operation as specified by the given permission.
117
+ *
118
+ * Note that you must configure "authManager" application component in order to use this method.
119
+ * Otherwise it will always return false.
120
+ *
121
+ * @param string $permissionName the name of the permission (e.g. "edit post") that needs access check.
122
+ * @param array $params name-value pairs that would be passed to the rules associated
123
+ * with the roles and permissions assigned to the user.
124
+ * @param bool $allowCaching whether to allow caching the result of access check.
125
+ * When this parameter is true (default), if the access check of an operation was performed
126
+ * before, its result will be directly returned when calling this method to check the same
127
+ * operation. If this parameter is false, this method will always call
128
+ * [[\yii\rbac\CheckAccessInterface::checkAccess()]] to obtain the up-to-date access result. Note that this
129
+ * caching is effective only within the same request and only works when `$params = []`.
130
+ * @return bool whether the user can perform the operation as specified by the given permission.
131
+ */
132
+ // public function can($permissionName, $params = [], $allowCaching = true)
133
+ // {
134
+ // if ($allowCaching && empty($params) && isset($this->_access[$permissionName])) {
135
+ // return $this->_access[$permissionName];
136
+ // }
137
+ // if (($accessChecker = $this->getAccessChecker()) === null) {
138
+ // return false;
139
+ // }
140
+ // $access = $accessChecker->checkAccess($this->getId(), $permissionName, $params);
141
+ // if ($allowCaching && empty($params)) {
142
+ // $this->_access[$permissionName] = $access;
143
+ // }
144
+ //
145
+ // return $access;
146
+ // }
147
+
148
+ public async can(permissionName: string, params = [], allowCaching = true) {
149
+
150
+ let access;
151
+ let accessChecker: AuthManager;
152
+ if ((accessChecker = this.getAccessChecker()) == null)
153
+ return false;
154
+
155
+
156
+ access = await accessChecker.checkAccess(this.getId(), permissionName, params);
157
+
158
+ if (allowCaching && Utils.isEmpty(params)) {
159
+ // this._access[$permissionName] = $access;
160
+ }
161
+
162
+ return access;
163
+
164
+ }
165
+
166
+ /**
167
+ * Returns auth manager associated with the user component.
168
+ *
169
+ * By default this is the `authManager` application component.
170
+ * You may override this method to return a different auth manager instance if needed.
171
+ * @return \yii\rbac\ManagerInterface
172
+ * @since 2.0.6
173
+ */
174
+ protected getAuthManager(): AuthManager {
175
+ return BaseChyz.getComponent('authManager');
176
+ }
177
+
178
+ /**
179
+ * Returns the access checker used for checking access.
180
+ * @return CheckAccessInterface
181
+ */
182
+ protected getAccessChecker():AuthManager {
183
+ return this.accessChecker !== null ? this.accessChecker : this.getAuthManager();
184
+ }
185
+
186
+
100
187
  }