hola-server 0.6.5 → 0.6.7

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.
package/core/meta.js CHANGED
@@ -1,5 +1,6 @@
1
1
  const { is_undefined } = require('./validate');
2
2
  const { get_type } = require('./type');
3
+ const { is_valid_role } = require('../setting');
3
4
 
4
5
  const meta_manager = {};
5
6
  /**
@@ -20,7 +21,7 @@ const meta_manager = {};
20
21
  *
21
22
  */
22
23
  const field_attrs = ["name", "type", "required", "ref", "link", "delete", "create", "list", "search", "update", "clone", "sys", "secure", "group"];
23
- const meta_attrs = ["collection", "primary_keys", "fields", "creatable", "readable", "updatable", "deleteable", "cloneable", "after_read",
24
+ const meta_attrs = ["collection", "roles", "primary_keys", "fields", "creatable", "readable", "updatable", "deleteable", "cloneable", "after_read",
24
25
  "before_create", "after_create", "before_clone", "after_clone", "before_update", "after_update", "before_delete", "after_delete", "create", "clone", "update", "batch_update", "after_batch_update", "delete",
25
26
  "ref_label", "ref_filter", "route", "user_field"];
26
27
 
@@ -200,6 +201,7 @@ class EntityMeta {
200
201
  constructor(meta) {
201
202
  this.meta = meta;
202
203
  this.collection = this.meta.collection;
204
+ this.roles = this.meta.roles;
203
205
 
204
206
  this.creatable = is_undefined(meta.creatable) ? false : meta.creatable;
205
207
  this.readable = is_undefined(meta.readable) ? false : meta.readable;
@@ -281,6 +283,19 @@ class EntityMeta {
281
283
  });
282
284
  }
283
285
 
286
+ if (this.roles) {
287
+ if (!Array.isArray(this.roles)) {
288
+ throw new Error("roles of meta [" + this.collection + "] should be array");
289
+ }
290
+ this.roles.forEach(role => {
291
+ const role_config = role.split(":");
292
+ const role_name = role_config[0];
293
+ if (!is_valid_role(role_name)) {
294
+ throw new Error("role [" + role_name + "] not defined in setting");
295
+ }
296
+ });
297
+ }
298
+
284
299
  if (this.ref_label && !this.field_names.includes(this.ref_label)) {
285
300
  throw new Error("ref_label [" + this.ref_label + "] configured in meta:" + this.collection + " not found in field names");
286
301
  }
package/http/session.js CHANGED
@@ -1,6 +1,6 @@
1
1
  const express_session = require('express-session');
2
2
  const MongoStore = require('connect-mongo');
3
- const { get_settings } = require('../setting');
3
+ const { get_settings, is_valid_role, is_root_role } = require('../setting');
4
4
 
5
5
  const init_session = (app) => {
6
6
  const server = get_settings().server;
@@ -24,9 +24,50 @@ const get_session_userid = (req) => {
24
24
  return user ? user.id : null;
25
25
  }
26
26
 
27
+ const get_session_user_role = (req) => {
28
+ const user = req && req.session ? req.session.user : null;
29
+ return user ? user.role : null;
30
+ }
31
+
32
+ //b:batch mode, c:create, d:delete, e:export, i:import, o:clone, p:page, r: refresh, s:search, u:update
33
+ const mode_all = "bcdeiorsu";
34
+
35
+ const get_user_role_mode = (req, roles) => {
36
+ const server = get_settings().server;
37
+ if (server.check_user == false) {
38
+ return mode_all;
39
+ }
40
+
41
+ const user_role = get_session_user_role(req);
42
+ if (!user_role) {
43
+ return "";
44
+ }
45
+
46
+ if (is_root_role(user_role)) {
47
+ return mode_all;
48
+ } else if (is_valid_role(user_role)) {
49
+ for (let i = 0; i < roles.length; i++) {
50
+ const role = roles[i];
51
+ const role_settings = role.split(":");
52
+ const role_name = role_settings[0];
53
+ const role_mode = role_settings[1];
54
+ if (user_role == role_name) {
55
+ return role_mode;
56
+ }
57
+ }
58
+ }
59
+
60
+ return "";
61
+ }
62
+
63
+ const check_user_role = (req, roles, mode) => {
64
+ const role_mode = get_user_role_mode(req, roles);
65
+ return role_mode.includes(mode);
66
+ }
67
+
27
68
  const get_session_user_groups = (req) => {
28
69
  const group = req && req.session ? req.session.group : null;
29
70
  return group && Array.isArray(group) ? group : null;
30
71
  }
31
72
 
32
- module.exports = { init_session, get_session_userid, get_session_user_groups };
73
+ module.exports = { init_session, get_session_userid, get_session_user_role, get_session_user_groups, check_user_role, get_user_role_mode };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hola-server",
3
- "version": "0.6.5",
3
+ "version": "0.6.7",
4
4
  "description": "a meta programming framework used to build nodejs restful api",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -20,7 +20,7 @@
20
20
  "multer": "^1.4.5-lts.1",
21
21
  "unzipper": "^0.10.11",
22
22
  "node-cron": "^3.0.2",
23
- "wxmnode": "^1.0.5"
23
+ "wxmnode": "^1.0.5"
24
24
  },
25
25
  "devDependencies": {
26
26
  "chai": "^4.3.6",
package/router/clone.js CHANGED
@@ -1,6 +1,6 @@
1
1
  const { set_file_fields, save_file_fields_to_db } = require('../db/gridfs');
2
- const { SUCCESS, NO_PARAMS } = require('../http/code');
3
- const { get_session_userid } = require('../http/session');
2
+ const { SUCCESS, NO_PARAMS, NO_RIGHTS } = require('../http/code');
3
+ const { get_session_userid, check_user_role } = require('../http/session');
4
4
  const { wrap_http } = require('../http/error');
5
5
  const { post_params, required_post_params } = require('../http/params');
6
6
  const { has_value } = require('../core/validate');
@@ -19,6 +19,14 @@ const init_clone_router = function (router, meta) {
19
19
  const cp_upload = meta.upload_fields.length > 0 ? upload_file.fields(meta.upload_fields) : upload_file.none();
20
20
 
21
21
  router.post('/clone', cp_upload, wrap_http(async function (req, res) {
22
+ if (meta.roles) {
23
+ const has_right = check_user_role(req, meta.roles, "o");
24
+ if (!has_right) {
25
+ res.json({ code: NO_RIGHTS, err: "no rights error" });
26
+ return;
27
+ }
28
+ }
29
+
22
30
  let params = required_post_params(req, ["_id"]);
23
31
  if (params === null) {
24
32
  res.json({ code: NO_PARAMS, err: '[_id] checking params are failed!' });
package/router/create.js CHANGED
@@ -1,6 +1,6 @@
1
1
  const { set_file_fields, save_file_fields_to_db } = require('../db/gridfs');
2
- const { SUCCESS } = require('../http/code');
3
- const { get_session_userid } = require('../http/session');
2
+ const { SUCCESS, NO_RIGHTS } = require('../http/code');
3
+ const { get_session_userid, check_user_role } = require('../http/session');
4
4
  const { wrap_http } = require('../http/error');
5
5
  const { post_params } = require('../http/params');
6
6
  const { has_value } = require('../core/validate');
@@ -19,6 +19,14 @@ const init_create_router = function (router, meta) {
19
19
  const cp_upload = meta.upload_fields.length > 0 ? upload_file.fields(meta.upload_fields) : upload_file.none();
20
20
 
21
21
  router.post('/create', cp_upload, wrap_http(async function (req, res) {
22
+ if (meta.roles) {
23
+ const has_right = check_user_role(req, meta.roles, "c");
24
+ if (!has_right) {
25
+ res.json({ code: NO_RIGHTS, err: "no rights error" });
26
+ return;
27
+ }
28
+ }
29
+
22
30
  const param_obj = post_params(req, meta.field_names);
23
31
  set_file_fields(meta, req, param_obj);
24
32
 
package/router/delete.js CHANGED
@@ -1,6 +1,7 @@
1
1
  const { required_post_params } = require('../http/params');
2
2
  const { has_value } = require('../core/validate');
3
- const { NO_PARAMS } = require('../http/code');
3
+ const { NO_PARAMS, NO_RIGHTS } = require('../http/code');
4
+ const { check_user_role } = require('../http/session');
4
5
  const { wrap_http } = require('../http/error');
5
6
  const { Entity } = require('../db/entity');
6
7
 
@@ -13,6 +14,14 @@ const init_delete_router = function (router, meta) {
13
14
  const entity = new Entity(meta);
14
15
 
15
16
  router.post('/delete', wrap_http(async function (req, res) {
17
+ if (meta.roles) {
18
+ const has_right = check_user_role(req, meta.roles, "d");
19
+ if (!has_right) {
20
+ res.json({ code: NO_RIGHTS, err: "no rights error" });
21
+ return;
22
+ }
23
+ }
24
+
16
25
  const params = required_post_params(req, ["ids"]);
17
26
  if (params === null) {
18
27
  res.json({ code: NO_PARAMS, err: ["ids"] });
package/router/read.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const { required_post_params, get_params } = require('../http/params');
2
2
  const { has_value } = require('../core/validate');
3
- const { NO_PARAMS, SUCCESS } = require('../http/code');
4
- const { get_session_userid, get_session_user_groups } = require('../http/session');
3
+ const { NO_PARAMS, SUCCESS, NO_RIGHTS } = require('../http/code');
4
+ const { get_session_userid, get_session_user_groups, check_user_role, get_user_role_mode } = require('../http/session');
5
5
  const { wrap_http } = require('../http/error');
6
6
  const { Entity } = require('../db/entity');
7
7
 
@@ -14,6 +14,14 @@ const init_read_router = function (router, meta) {
14
14
  const entity = new Entity(meta);
15
15
 
16
16
  router.get('/meta', wrap_http(async function (req, res) {
17
+ if (meta.roles) {
18
+ const has_right = check_user_role(req, meta.roles, "r");
19
+ if (!has_right) {
20
+ res.json({ code: NO_RIGHTS, err: "no rights error" });
21
+ return;
22
+ }
23
+ }
24
+
17
25
  const entity_meta = {
18
26
  creatable: meta.creatable,
19
27
  readable: meta.readable,
@@ -29,7 +37,27 @@ const init_read_router = function (router, meta) {
29
37
  res.json({ code: SUCCESS, data: entity_meta });
30
38
  }));
31
39
 
40
+ router.get('/mode', wrap_http(async function (req, res) {
41
+ if (meta.roles) {
42
+ const has_right = check_user_role(req, meta.roles, "r");
43
+ if (!has_right) {
44
+ res.json({ code: NO_RIGHTS, err: "no rights error" });
45
+ return;
46
+ }
47
+ }
48
+
49
+ res.json({ code: SUCCESS, data: get_user_role_mode(req, meta.roles) });
50
+ }));
51
+
32
52
  router.get('/ref', wrap_http(async function (req, res) {
53
+ if (meta.roles) {
54
+ const has_right = check_user_role(req, meta.roles, "r");
55
+ if (!has_right) {
56
+ res.json({ code: NO_RIGHTS, err: "no rights error" });
57
+ return;
58
+ }
59
+ }
60
+
33
61
  const { ref_by_entity } = get_params(req, ["ref_by_entity"]);
34
62
  const list = await entity.get_filtered_ref_labels(ref_by_entity);
35
63
  const items = list.map(obj => ({ "text": obj[meta.ref_label], "value": obj["_id"] + "" }));
@@ -37,6 +65,14 @@ const init_read_router = function (router, meta) {
37
65
  }));
38
66
 
39
67
  router.post('/list', wrap_http(async function (req, res) {
68
+ if (meta.roles) {
69
+ const has_right = check_user_role(req, meta.roles, "r");
70
+ if (!has_right) {
71
+ res.json({ code: NO_RIGHTS, err: "no rights error" });
72
+ return;
73
+ }
74
+ }
75
+
40
76
  const query_params = required_post_params(req, ["_query"]);
41
77
  if (query_params === null) {
42
78
  res.json({ code: NO_PARAMS, err: ["_query"] });
@@ -71,6 +107,14 @@ const init_read_router = function (router, meta) {
71
107
  }));
72
108
 
73
109
  router.post('/read_entity', wrap_http(async function (req, res) {
110
+ if (meta.roles) {
111
+ const has_right = check_user_role(req, meta.roles, "r");
112
+ if (!has_right) {
113
+ res.json({ code: NO_RIGHTS, err: "no rights error" });
114
+ return;
115
+ }
116
+ }
117
+
74
118
  let params = required_post_params(req, ["_id", "attr_names"]);
75
119
  if (params === null) {
76
120
  res.json({ code: NO_PARAMS, err: '[_id,attr_names] checking params are failed!' });
@@ -86,6 +130,14 @@ const init_read_router = function (router, meta) {
86
130
  }));
87
131
 
88
132
  router.post('/read_property', wrap_http(async function (req, res) {
133
+ if (meta.roles) {
134
+ const has_right = check_user_role(req, meta.roles, "r");
135
+ if (!has_right) {
136
+ res.json({ code: NO_RIGHTS, err: "no rights error" });
137
+ return;
138
+ }
139
+ }
140
+
89
141
  let params = required_post_params(req, ["_id", "attr_names"]);
90
142
  if (params === null) {
91
143
  res.json({ code: NO_PARAMS, err: '[_id,attr_names] checking params are failed!' });
package/router/update.js CHANGED
@@ -1,6 +1,7 @@
1
1
  const { set_file_fields, save_file_fields_to_db } = require('../db/gridfs');
2
2
  const { required_post_params, post_update_params } = require('../http/params');
3
- const { SUCCESS, NO_PARAMS } = require('../http/code');
3
+ const { SUCCESS, NO_PARAMS, NO_RIGHTS } = require('../http/code');
4
+ const { check_user_role } = require('../http/session');
4
5
  const { has_value } = require('../core/validate');
5
6
  const { wrap_http } = require('../http/error');
6
7
  const { Entity } = require('../db/entity');
@@ -18,6 +19,14 @@ const init_update_router = function (router, meta) {
18
19
  const cp_upload = meta.upload_fields.length > 0 ? upload_file.fields(meta.upload_fields) : upload_file.none();
19
20
 
20
21
  router.post('/update', cp_upload, wrap_http(async function (req, res) {
22
+ if (meta.roles) {
23
+ const has_right = check_user_role(req, meta.roles, "u");
24
+ if (!has_right) {
25
+ res.json({ code: NO_RIGHTS, err: "no rights error" });
26
+ return;
27
+ }
28
+ }
29
+
21
30
  let params = required_post_params(req, ["_id"]);
22
31
  if (params === null) {
23
32
  params = required_post_params(req, meta.primary_keys);
package/setting.js CHANGED
@@ -13,6 +13,10 @@ let settings = {
13
13
  log_level: 0,
14
14
  save_db: dev_mode == false,
15
15
  },
16
+ roles: [
17
+ { name: "admin", root: true },
18
+ { name: "user" }
19
+ ],
16
20
  server: {
17
21
  service_port: 8088,
18
22
  client_web_url: ['http://localhost:8080'],
@@ -39,4 +43,26 @@ const get_settings = () => {
39
43
  return settings;
40
44
  }
41
45
 
42
- module.exports = { init_settings, get_settings };
46
+ const is_valid_role = (role_name) => {
47
+ //no role defined, then no role check
48
+ if (!settings.roles) {
49
+ return true;
50
+ }
51
+ const roles = settings.roles.filter(role => role.name == role_name);
52
+ return roles.length == 1;
53
+ }
54
+
55
+ const is_root_role = (role_name) => {
56
+ //no role defined, then every one is root
57
+ if (!settings.roles) {
58
+ return true;
59
+ }
60
+
61
+ if (!is_valid_role(role_name)) {
62
+ return false;
63
+ }
64
+
65
+ return settings.roles.filter(role => role.name == role_name)[0].root == true;
66
+ }
67
+
68
+ module.exports = { init_settings, get_settings, is_root_role, is_valid_role };