added access control to actions of user in api
parent
72484ea920
commit
dd279ba548
|
|
@ -46,7 +46,8 @@ app.controller('UserController', function ($scope,
|
|||
}
|
||||
});
|
||||
modalInstance.result.then(function (user) {
|
||||
UserService.addUser(user, function (response) {
|
||||
let headers = { "User-UUID": $scope.cur_user.uuid, "Token": $scope.cur_user.token };
|
||||
UserService.addUser(user, headers, function (response) {
|
||||
if (angular.isDefined(response.status) && response.status === 201) {
|
||||
toaster.pop({
|
||||
type: "success",
|
||||
|
|
@ -85,7 +86,8 @@ app.controller('UserController', function ($scope,
|
|||
});
|
||||
|
||||
modalInstance.result.then(function (modifiedUser) {
|
||||
UserService.editUser(modifiedUser, function (response) {
|
||||
let headers = { "User-UUID": $scope.cur_user.uuid, "Token": $scope.cur_user.token };
|
||||
UserService.editUser(modifiedUser, headers, function (response) {
|
||||
if (angular.isDefined(response.status) && response.status === 200) {
|
||||
toaster.pop({
|
||||
type: "success",
|
||||
|
|
@ -123,12 +125,8 @@ app.controller('UserController', function ($scope,
|
|||
});
|
||||
|
||||
modalInstance.result.then(function (modifiedUser) {
|
||||
let data = {
|
||||
name: modifiedUser.name,
|
||||
password: modifiedUser.password };
|
||||
|
||||
let data = {name: modifiedUser.name, password: modifiedUser.password };
|
||||
let headers = { "User-UUID": $scope.cur_user.uuid, "Token": $scope.cur_user.token };
|
||||
|
||||
UserService.resetPassword(data, headers, function (response) {
|
||||
if (angular.isDefined(response.status) && response.status === 200) {
|
||||
toaster.pop({
|
||||
|
|
@ -166,7 +164,8 @@ app.controller('UserController', function ($scope,
|
|||
},
|
||||
function (isConfirm) {
|
||||
if (isConfirm) {
|
||||
UserService.deleteUser(user, function (response) {
|
||||
let headers = { "User-UUID": $scope.cur_user.uuid, "Token": $scope.cur_user.token };
|
||||
UserService.deleteUser(user, headers, function (response) {
|
||||
if (angular.isDefined(response.status) && response.status === 204) {
|
||||
toaster.pop({
|
||||
type: "success",
|
||||
|
|
|
|||
|
|
@ -17,16 +17,16 @@ app.factory('UserService', function($http) {
|
|||
callback(response);
|
||||
});
|
||||
},
|
||||
addUser: function(user, callback) {
|
||||
$http.post(getAPI()+'users',{data:user})
|
||||
addUser: function(user, headers, callback) {
|
||||
$http.post(getAPI()+'users', {data:user}, {headers})
|
||||
.then(function (response) {
|
||||
callback(response);
|
||||
}, function (response) {
|
||||
callback(response);
|
||||
});
|
||||
},
|
||||
editUser: function(user, callback) {
|
||||
$http.put(getAPI()+'users/'+user.id,{data:user})
|
||||
editUser: function(user, headers, callback) {
|
||||
$http.put(getAPI()+'users/'+user.id, {data:user}, {headers})
|
||||
.then(function (response) {
|
||||
callback(response);
|
||||
}, function (response) {
|
||||
|
|
@ -49,16 +49,16 @@ app.factory('UserService', function($http) {
|
|||
callback(response);
|
||||
});
|
||||
},
|
||||
deleteUser: function(user, callback) {
|
||||
$http.delete(getAPI()+'users/'+user.id)
|
||||
deleteUser: function(user, headers, callback) {
|
||||
$http.delete(getAPI()+'users/'+user.id, {headers})
|
||||
.then(function (response) {
|
||||
callback(response);
|
||||
}, function (response) {
|
||||
callback(response);
|
||||
});
|
||||
},
|
||||
getUser: function(id, callback) {
|
||||
$http.get(getAPI()+'users/'+id)
|
||||
getUser: function(id, headers, callback) {
|
||||
$http.get(getAPI()+'users/'+id, {headers})
|
||||
.then(function (response) {
|
||||
callback(response);
|
||||
}, function (response) {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import simplejson as json
|
|||
import mysql.connector
|
||||
import config
|
||||
import uuid
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class CombinedEquipmentCollection:
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import mysql.connector
|
|||
import config
|
||||
import uuid
|
||||
import re
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class ContactCollection:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import simplejson as json
|
|||
import mysql.connector
|
||||
import config
|
||||
import uuid
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class CostCenterCollection:
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import config
|
|||
import uuid
|
||||
from datetime import datetime, timezone, timedelta
|
||||
import os
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class CostFileCollection:
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import mysql.connector
|
|||
import config
|
||||
import uuid
|
||||
from datetime import datetime, timezone, timedelta
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class DataSourceCollection:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import simplejson as json
|
|||
import mysql.connector
|
||||
import config
|
||||
import uuid
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class DistributionCircuitCollection:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import simplejson as json
|
|||
import mysql.connector
|
||||
import config
|
||||
import uuid
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class DistributionSystemCollection:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import json
|
|||
import mysql.connector
|
||||
import config
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class EmailMessageCollection:
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import mysql.connector
|
|||
import config
|
||||
import base64
|
||||
import re
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class EmailServerCollection:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import simplejson as json
|
|||
import mysql.connector
|
||||
import config
|
||||
import uuid
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class EnergyCategoryCollection:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import simplejson as json
|
|||
import mysql.connector
|
||||
import config
|
||||
import uuid
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class EnergyFlowDiagramCollection:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import simplejson as json
|
|||
import mysql.connector
|
||||
import config
|
||||
import uuid
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class EnergyItemCollection:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import simplejson as json
|
|||
import mysql.connector
|
||||
import config
|
||||
import uuid
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class EquipmentCollection:
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import mysql.connector
|
|||
import config
|
||||
import uuid
|
||||
from datetime import datetime, timezone, timedelta
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class GatewayCollection:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from datetime import datetime, timezone, timedelta
|
|||
import os
|
||||
import base64
|
||||
import sys
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class KnowledgeFileCollection:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import falcon
|
|||
import simplejson as json
|
||||
import mysql.connector
|
||||
import config
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class MenuCollection:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import simplejson as json
|
|||
import mysql.connector
|
||||
import config
|
||||
import uuid
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class MeterCollection:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import json
|
|||
import mysql.connector
|
||||
import config
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class NotificationCollection:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import simplejson as json
|
|||
import mysql.connector
|
||||
import config
|
||||
import uuid
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class OfflineMeterCollection:
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import config
|
|||
import uuid
|
||||
from datetime import datetime, timezone, timedelta
|
||||
import os
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class OfflineMeterFileCollection:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import falcon
|
|||
import simplejson as json
|
||||
import mysql.connector
|
||||
import config
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class PointCollection:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import falcon
|
|||
import simplejson as json
|
||||
import mysql.connector
|
||||
import config
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class PrivilegeCollection:
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import mysql.connector
|
|||
import uuid
|
||||
from datetime import datetime, timezone, timedelta
|
||||
import config
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class RuleCollection:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import simplejson as json
|
|||
import mysql.connector
|
||||
import config
|
||||
import uuid
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class SensorCollection:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import simplejson as json
|
|||
import mysql.connector
|
||||
import config
|
||||
import uuid
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class ShopfloorCollection:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import uuid
|
|||
from datetime import datetime
|
||||
from anytree import AnyNode
|
||||
from anytree.exporter import JsonExporter
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class SpaceCollection:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import simplejson as json
|
|||
import mysql.connector
|
||||
import config
|
||||
import uuid
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class StoreCollection:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import simplejson as json
|
|||
import mysql.connector
|
||||
import config
|
||||
import uuid
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class StoreTypeCollection:
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import mysql.connector
|
|||
import config
|
||||
import uuid
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class TariffCollection:
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import mysql.connector
|
|||
import config
|
||||
import uuid
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class TenantCollection:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import simplejson as json
|
|||
import mysql.connector
|
||||
import config
|
||||
import uuid
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class TenantTypeCollection:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import json
|
|||
import mysql.connector
|
||||
import config
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class TextMessageCollection:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import falcon
|
|||
import simplejson as json
|
||||
import mysql.connector
|
||||
import config
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class TimezoneCollection:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import hashlib
|
|||
import re
|
||||
import os
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from core.userlogger import user_logger, write_log
|
||||
from core.useractivity import user_logger, write_log, access_control
|
||||
|
||||
|
||||
class UserCollection:
|
||||
|
|
@ -22,52 +22,9 @@ class UserCollection:
|
|||
|
||||
@staticmethod
|
||||
def on_get(req, resp):
|
||||
if 'USER-UUID' not in req.headers or \
|
||||
not isinstance(req.headers['USER-UUID'], str) or \
|
||||
len(str.strip(req.headers['USER-UUID'])) == 0:
|
||||
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
|
||||
description='API.INVALID_USER_UUID')
|
||||
admin_user_uuid = str.strip(req.headers['USER-UUID'])
|
||||
|
||||
if 'TOKEN' not in req.headers or \
|
||||
not isinstance(req.headers['TOKEN'], str) or \
|
||||
len(str.strip(req.headers['TOKEN'])) == 0:
|
||||
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
|
||||
description='API.INVALID_TOKEN')
|
||||
admin_token = str.strip(req.headers['TOKEN'])
|
||||
|
||||
# Check administrator privilege
|
||||
access_control(req)
|
||||
cnx = mysql.connector.connect(**config.myems_user_db)
|
||||
cursor = cnx.cursor()
|
||||
query = (" SELECT utc_expires "
|
||||
" FROM tbl_sessions "
|
||||
" WHERE user_uuid = %s AND token = %s")
|
||||
cursor.execute(query, (admin_user_uuid, admin_token,))
|
||||
row = cursor.fetchone()
|
||||
|
||||
if row is None:
|
||||
cursor.close()
|
||||
cnx.disconnect()
|
||||
raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
|
||||
description='API.ADMINISTRATOR_SESSION_NOT_FOUND')
|
||||
else:
|
||||
utc_expires = row[0]
|
||||
if datetime.utcnow() > utc_expires:
|
||||
cursor.close()
|
||||
cnx.disconnect()
|
||||
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
|
||||
description='API.ADMINISTRATOR_SESSION_TIMEOUT')
|
||||
|
||||
query = (" SELECT name "
|
||||
" FROM tbl_users "
|
||||
" WHERE uuid = %s AND is_admin = true ")
|
||||
cursor.execute(query, (admin_user_uuid,))
|
||||
row = cursor.fetchone()
|
||||
if row is None:
|
||||
cursor.close()
|
||||
cnx.disconnect()
|
||||
raise falcon.HTTPError(falcon.HTTP_400, 'API.BAD_REQUEST', 'API.INVALID_PRIVILEGE')
|
||||
|
||||
query = (" SELECT u.id, u.name, u.display_name, u.uuid, "
|
||||
" u.email, u.is_admin, p.id, p.name, "
|
||||
" u.account_expiration_datetime_utc, u.password_expiration_datetime_utc "
|
||||
|
|
@ -110,7 +67,7 @@ class UserCollection:
|
|||
@staticmethod
|
||||
def on_post(req, resp):
|
||||
"""Handles POST requests"""
|
||||
# todo: add access control
|
||||
access_control(req)
|
||||
# todo: add user log
|
||||
try:
|
||||
raw_json = req.stream.read().decode('utf-8')
|
||||
|
|
@ -246,7 +203,7 @@ class UserItem:
|
|||
|
||||
@staticmethod
|
||||
def on_get(req, resp, id_):
|
||||
# todo: add access control
|
||||
access_control(req)
|
||||
if not id_.isdigit() or int(id_) <= 0:
|
||||
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
|
||||
description='API.INVALID_USER_ID')
|
||||
|
|
@ -291,6 +248,7 @@ class UserItem:
|
|||
@staticmethod
|
||||
@user_logger
|
||||
def on_delete(req, resp, id_):
|
||||
access_control(req)
|
||||
if not id_.isdigit() or int(id_) <= 0:
|
||||
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
|
||||
description='API.INVALID_USER_ID')
|
||||
|
|
@ -320,6 +278,7 @@ class UserItem:
|
|||
@user_logger
|
||||
def on_put(req, resp, id_):
|
||||
"""Handles PUT requests"""
|
||||
access_control(req)
|
||||
try:
|
||||
raw_json = req.stream.read().decode('utf-8')
|
||||
except Exception as ex:
|
||||
|
|
|
|||
|
|
@ -9,6 +9,58 @@ import simplejson as json
|
|||
import falcon
|
||||
|
||||
|
||||
def access_control(req):
|
||||
"""
|
||||
Check administrator privilege in request headers to protect resources from invalid access
|
||||
:param req: HTTP request
|
||||
:return: HTTPError if invalid else None
|
||||
"""
|
||||
if 'USER-UUID' not in req.headers or \
|
||||
not isinstance(req.headers['USER-UUID'], str) or \
|
||||
len(str.strip(req.headers['USER-UUID'])) == 0:
|
||||
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
|
||||
description='API.INVALID_USER_UUID')
|
||||
admin_user_uuid = str.strip(req.headers['USER-UUID'])
|
||||
|
||||
if 'TOKEN' not in req.headers or \
|
||||
not isinstance(req.headers['TOKEN'], str) or \
|
||||
len(str.strip(req.headers['TOKEN'])) == 0:
|
||||
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
|
||||
description='API.INVALID_TOKEN')
|
||||
admin_token = str.strip(req.headers['TOKEN'])
|
||||
|
||||
# Check administrator privilege
|
||||
cnx = mysql.connector.connect(**config.myems_user_db)
|
||||
cursor = cnx.cursor()
|
||||
query = (" SELECT utc_expires "
|
||||
" FROM tbl_sessions "
|
||||
" WHERE user_uuid = %s AND token = %s")
|
||||
cursor.execute(query, (admin_user_uuid, admin_token,))
|
||||
row = cursor.fetchone()
|
||||
|
||||
if row is None:
|
||||
cursor.close()
|
||||
cnx.disconnect()
|
||||
raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
|
||||
description='API.ADMINISTRATOR_SESSION_NOT_FOUND')
|
||||
else:
|
||||
utc_expires = row[0]
|
||||
if datetime.utcnow() > utc_expires:
|
||||
cursor.close()
|
||||
cnx.disconnect()
|
||||
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
|
||||
description='API.ADMINISTRATOR_SESSION_TIMEOUT')
|
||||
query = (" SELECT name "
|
||||
" FROM tbl_users "
|
||||
" WHERE uuid = %s AND is_admin = true ")
|
||||
cursor.execute(query, (admin_user_uuid,))
|
||||
row = cursor.fetchone()
|
||||
cursor.close()
|
||||
cnx.disconnect()
|
||||
if row is None:
|
||||
raise falcon.HTTPError(falcon.HTTP_400, 'API.BAD_REQUEST', 'API.INVALID_PRIVILEGE')
|
||||
|
||||
|
||||
def write_log(user_uuid, request_method, resource_type, resource_id, request_body):
|
||||
"""
|
||||
:param user_uuid: user_uuid
|
||||
|
|
@ -43,6 +95,11 @@ def write_log(user_uuid, request_method, resource_type, resource_id, request_bod
|
|||
|
||||
|
||||
def user_logger(func):
|
||||
"""
|
||||
Decorator for logging user activities
|
||||
:param func: the decorated function
|
||||
:return: the decorator
|
||||
"""
|
||||
@wraps(func)
|
||||
def logger(*args, **kwargs):
|
||||
qualified_name = func.__qualname__
|
||||
|
|
@ -3,7 +3,7 @@ import simplejson as json
|
|||
import mysql.connector
|
||||
import config
|
||||
import uuid
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class VirtualMeterCollection:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import json
|
|||
import mysql.connector
|
||||
import config
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class WebMessageCollection:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import json
|
|||
import mysql.connector
|
||||
import config
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from core.userlogger import user_logger
|
||||
from core.useractivity import user_logger
|
||||
|
||||
|
||||
class WechatMessageCollection(object):
|
||||
|
|
|
|||
Loading…
Reference in New Issue