Implemented server side user group permissions query.

Ylian Saint-Hilaire committed Jan 4, 2020 at 12:44 UTC a85dc11ba3da6945a33cd44bbbc3c9225760486a
2 files changed +121 -14
translate/translate.js
+1 -1
@@ -475,7 +475,7 @@ function translateFromHtml(lang, file, createSubDir) {
475 var data = fs.readFileSync(file);
476 var { JSDOM } = jsdom;
477 const dom = new JSDOM(data, { includeNodeLocations: true });
478 - console.log("Translating HTML: " + path.basename(file));
478 + console.log("Translating HTML (" + lang + "): " + path.basename(file));
479 translateStrings(path.basename(file), dom.window.document.querySelector('body'));
480 var out = dom.serialize();
481
webserver.js
+120 -13
@@ -3923,9 +3923,32 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3923 // Check that we have permissions for this node.
3924 db.Get(nodeid, function (err, nodes) {
3925 if ((nodes == null) || (nodes.length != 1)) { func(null, 0, false); return; } // No such nodeid
3926 - var rights = user.links[nodes[0].meshid];
3927 - if (rights == null) { func(null, 0, false); return; } // No rights to this mesh
3928 - func(nodes[0], rights.rights, true);
3926 +
3927 + // Check direct link
3928 + var rights = 0, visible = false, r = user.links[nodes[0].meshid];
3929 + if (r != null) {
3930 + rights = r.rights;
3931 + visible = true;
3932 + if (rights == 0xFFFFFFFF) { func(nodes[0], rights, true); return; } // User has full rights thru a direct link, stop here.
3933 + }
3934 +
3935 + // Check user group links
3936 + for (var i in user.links) {
3937 + if (i.startsWith('ugrp/')) {
3938 + const g = obj.userGroups[i];
3939 + if (g && (g.links != null)) {
3940 + r = g.links[nodes[0].meshid];
3941 + if (r != null) {
3942 + if (r.rights == 0xFFFFFFFF) { func(nodes[0], r.rights, true); return; } // User has full rights thru a user group link, stop here.
3943 + rights |= r.rights; // TODO: Deal with reverse rights
3944 + visible = true;
3945 + }
3946 + }
3947 + }
3948 + }
3949 +
3950 + // Return the rights we found
3951 + func(nodes[0], rights, visible);
3952 });
3953 }
3954
@@ -3934,7 +3957,28 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3957 if (typeof user == 'string') { user = obj.users[user]; }
3958 if ((user == null) || (user.links == null)) { return []; }
3959 var r = [];
3937 - for (var i in user.links) { const m = obj.meshes[i]; if ((m) && (m.deleted == null) && ((rights == null) || ((m.rights & rights) != 0))) { r.push(m); } }
3960 + for (var i in user.links) {
3961 + if (i.startsWith('mesh/')) {
3962 + // Grant access to a device group thru a direct link
3963 + const m = obj.meshes[i];
3964 + if ((m) && (m.deleted == null) && ((rights == null) || ((m.rights & rights) != 0))) {
3965 + if (r.indexOf(m) == -1) { r.push(m); }
3966 + }
3967 + } else if (i.startsWith('ugrp/')) {
3968 + // Grant access to a device group thru a user group
3969 + const g = obj.userGroups[i];
3970 + if (g && (g.links != null) && ((rights == null) || ((g.rights & rights) != 0))) {
3971 + for (var j in g.links) {
3972 + if (j.startsWith('mesh/')) {
3973 + const m = obj.meshes[j];
3974 + if ((m) && (m.deleted == null)) {
3975 + if (r.indexOf(m) == -1) { r.push(m); }
3976 + }
3977 + }
3978 + }
3979 + }
3980 + }
3981 + }
3982 return r;
3983 }
3984
@@ -3943,7 +3987,28 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3987 if (typeof user == 'string') { user = obj.users[user]; }
3988 if ((user == null) || (user.links == null)) { return []; }
3989 var r = [];
3946 - for (var i in user.links) { const m = obj.meshes[i]; if ((m) && (m.deleted == null) && ((rights == null) || ((m.rights & rights) != 0))) { r.push(m._id); } }
3990 + for (var i in user.links) {
3991 + if (i.startsWith('mesh/')) {
3992 + // Grant access to a device group thru a direct link
3993 + const m = obj.meshes[i];
3994 + if ((m) && (m.deleted == null) && ((rights == null) || ((m.rights & rights) != 0))) {
3995 + if (r.indexOf(m._id) == -1) { r.push(m._id); }
3996 + }
3997 + } else if (i.startsWith('ugrp/')) {
3998 + // Grant access to a device group thru a user group
3999 + const g = obj.userGroups[i];
4000 + if (g && (g.links != null) && ((rights == null) || ((g.rights & rights) != 0))) {
4001 + for (var j in g.links) {
4002 + if (j.startsWith('mesh/')) {
4003 + const m = obj.meshes[j];
4004 + if ((m) && (m.deleted == null)) {
4005 + if (r.indexOf(m._id) == -1) { r.push(m._id); }
4006 + }
4007 + }
4008 + }
4009 + }
4010 + }
4011 + }
4012 return r;
4013 }
4014
@@ -3952,10 +4017,37 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4017 if ((user == null) || (mesh == null)) { return 0; }
4018 if (typeof user == 'string') { user = obj.users[user]; }
4019 if ((user == null) || (user.links == null)) { return 0; }
3955 - var r = 0;
3956 - if (typeof mesh == 'string') { r = user.links[mesh]; } else { r = user.links[mesh._id]; }
3957 - if (r == null) { return 0; }
3958 - return r.rights;
4020 + var r, meshid;
4021 + if (typeof mesh == 'string') {
4022 + meshid = mesh;
4023 + } else if ((typeof mesh == 'object') && (typeof mesh._id == 'string')) {
4024 + meshid = mesh._id;
4025 + } else return 0;
4026 +
4027 + // Check direct user to device group permissions
4028 + r = user.links[meshid];
4029 + if ((r != null) && (r.rights == 0xFFFFFFFF)) { return r.rights; } // If the user has full access thru direct link, stop here.
4030 + var rights = r.rights;
4031 +
4032 + // Check if we are part of any user groups that would give this user more access.
4033 + for (var i in user.links) {
4034 + if (i.startsWith('ugrp')) {
4035 + const g = obj.usersGroups[i];
4036 + if (g) {
4037 + r = g.links[meshid];
4038 + if (r != null) {
4039 + if (r.rights == 0xFFFFFFFF) {
4040 + return r.rights; // If the user hash full access thru a user group link, stop here.
4041 + } else {
4042 + rights |= r.rights; // Add to existing rights (TODO: Deal with reverse rights)
4043 + }
4044 + }
4045 + }
4046 +
4047 + }
4048 + }
4049 +
4050 + return rights;
4051 }
4052
4053 // Returns true if the user can view the given device group
@@ -3963,10 +4055,25 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4055 if ((user == null) || (mesh == null)) { return false; }
4056 if (typeof user == 'string') { user = obj.users[user]; }
4057 if ((user == null) || (user.links == null)) { return false; }
3966 - var r = 0;
3967 - if (typeof mesh == 'string') { r = user.links[mesh]; } else { r = user.links[mesh._id]; }
3968 - if (r == null) { return false; }
3969 - return true;
4058 + var meshid;
4059 + if (typeof mesh == 'string') {
4060 + meshid = mesh;
4061 + } else if ((typeof mesh == 'object') && (typeof mesh._id == 'string')) {
4062 + meshid = mesh._id;
4063 + } else return false;
4064 +
4065 + // Check direct user to device group permissions
4066 + if (user.links[meshid] != null) { return true; } // If the user has a direct link, stop here.
4067 +
4068 + // Check if we are part of any user groups that would give this user visibility to this device group.
4069 + for (var i in user.links) {
4070 + if (i.startsWith('ugrp')) {
4071 + const g = obj.usersGroups[i];
4072 + if (g && (g.links[meshid] != null)) { return true; } // If the user has a user group link, stop here.
4073 + }
4074 + }
4075 +
4076 + return false;
4077 }
4078
4079 // Clone a safe version of a user object, remove everything that is secret.