add user-related DB Storage & Manager
ref #3078
Change-Id: Idd0272f501545a9e8fa156008400b42cf0ea10ef
diff --git a/device_user_access_manager.py b/device_user_access_manager.py
index 1d14c73..4fcc0a9 100644
--- a/device_user_access_manager.py
+++ b/device_user_access_manager.py
@@ -23,18 +23,24 @@
"""
import sys
+import hmac
+from hashlib import sha256
from pyndn.name import Name
from device_profile import DeviceProfile
from device_storage import DeviceStorage
+from hmac_key import HMACKey
+from user_access_storage import UserAccessStorage
class DeviceUserAccessManager(object):
"""
Create a new DeviceUserAccessManager
"""
def __init__(self, databaseFilePath = None):
- deviceUserAccessStorage = DeviceStorage(databaseFilePath)
- self._deviceUserAccessStorage = deviceUserAccessStorage
-
+ deviceStorage = DeviceStorage(databaseFilePath)
+ self._deviceStorage = deviceStorage
+ userAccessStorage = UserAccessStorage(databaseFilePath)
+ self._userAccessStorage = userAccessStorage
+
def createDevice(self, deviceProfile, seed, configurationToken, commandList = None):
"""
Create a device in the database, including it's corresponding commands and serrvice profiles
@@ -47,7 +53,7 @@
result = False
#add device
- deviceId = self._deviceUserAccessStorage.addDevice(deviceProfile, seed, configurationToken)
+ deviceId = self._deviceStorage.addDevice(deviceProfile, seed, configurationToken)
if deviceId == 0:
raise RuntimeError("device already exists in database")
return result
@@ -58,16 +64,23 @@
#add service profile
serviceProfileList = deviceProfile.getServiceProfileList()
for serviceProfileName in serviceProfileList:
- serviceProfileId = self._deviceUserAccessStorage.addServiceProfile(deviceId, serviceProfileName)
+ serviceProfileId = self._deviceStorage.addServiceProfile(deviceId, serviceProfileName)
if serviceProfileId == 0:
raise RuntimeError("service profile: " + serviceProfileName + " already exists in database")
return result
elif serviceProfileId == -1:
raise RuntimeError("error occured during adding service profile :" + serviceProfileName)
return result
+
#add command
- for commandTuple in commandList:
- commandId = self._deviceUserAccessStorage.addCommand(deviceId, commandTuple[0], commandTuple[1])
+ for command in commandList:
+ #generate command token,firstt generate command token name
+ prefix = deviceProfile.getPrefix()
+ commandTokenName = prefix.toUri()+"/"+command+"/token/0"
+ commandTokenKey = hmac.new(seed.getKey(), commandTokenName,sha256).digest()
+ commandToken = HMACKey(0,0,commandTokenKey,commandTokenName)
+
+ commandId = self._deviceStorage.addCommand(deviceId, command, commandToken)
if commandId == 0:
raise RuntimeError("command: " + commandTuple[0] + " already exists in database")
return result
@@ -84,16 +97,16 @@
:return device profile of the device if exists, otherwise return None
:rtype: DeviceProfile
"""
- deviceProfile = self._deviceUserAccessStorage.getDeviceProfileFromDevice(prefix)
+ deviceProfile = self._deviceStorage.getDeviceProfileFromDevice(prefix)
if deviceProfile == None:
return deviceProfile
else:
# get device Id
- deviceId = self._deviceUserAccessStorage.getDeviceId(deviceProfile.getPrefix())
+ deviceId = self._deviceStorage.getDeviceId(deviceProfile.getPrefix())
if deviceId == 0:
raise RuntimeError("device doesn't exist")
- serviceProfileList = self._deviceUserAccessStorage.getServiceProfilesOfDevice(deviceId)
+ serviceProfileList = self._deviceStorage.getServiceProfilesOfDevice(deviceId)
deviceProfile.setServiceProfile(serviceProfileList)
return deviceProfile
@@ -105,7 +118,7 @@
:return seed of the device if exists, otherwise return None
:rtype: SymmetricKey
"""
- return self._deviceUserAccessStorage.getSeed(prefix)
+ return self._deviceStorage.getSeed(prefix)
def getConfigurationToken(self, prefix):
"""
@@ -114,7 +127,7 @@
:return seed of the device if exists, otherwise return None
:rtype: SymmetricKey
"""
- return self._deviceUserAccessStorage.getConfigurationToken(prefix)
+ return self._deviceStorage.getConfigurationToken(prefix)
def getCommandToken(self, prefix, commandName):
"""
@@ -124,10 +137,10 @@
:return command token if command existsm, otherwise None
:rtype SymmetricKey
"""
- deviceId = self._deviceUserAccessStorage.getDeviceId(prefix)
+ deviceId = self._deviceStorage.getDeviceId(prefix)
if deviceId == 0:
return None
- return self._deviceUserAccessStorage.getCommandToken(deviceId, commandName)
+ return self._deviceStorage.getCommandToken(deviceId, commandName)
def getCommandsOfDevice(self, prefix):
"""
@@ -135,10 +148,10 @@
:param Name prefix: the device prefix
:return command name list if any commands exist, otherwise None
"""
- deviceId = self._deviceUserAccessStorage.getDeviceId(prefix)
+ deviceId = self._deviceStorage.getDeviceId(prefix)
if deviceId == 0:
return None
- return self._deviceUserAccessStorage.getCommandsOfDevice(deviceId)
+ return self._deviceStorage.getCommandsOfDevice(deviceId)
def getServiceProfilesOfDevice(self, prefix):
"""
@@ -146,8 +159,88 @@
:param Name prefix: the device prefix
:return service profiles name list if any service profiles exist, otherwise None
"""
- deviceId = self._deviceUserAccessStorage.getDeviceId(prefix)
+ deviceId = self._deviceStorage.getDeviceId(prefix)
if deviceId == 0:
return None
- return self._deviceUserAccessStorage.getServiceProfilesOfDevice(deviceId)
-
+ return self._deviceStorage.getServiceProfilesOfDevice(deviceId)
+
+ def addUser(self, prefix, username, hash_, salt, type_):
+ """
+ Add a new user to User table, do nothing if the user already exists
+
+ :param Name prefix: the prefix of the user
+ :param str username: username
+ :param hash_:
+ :param salt:
+ :param str type: the type of user, either guest or user
+ :return the user id if it's added successfully, 0 if prefix conflict exists, -1 if username conflict exists
+ :rtype: INTEGER
+ """
+ return self._userAccessStorage.addUser(prefix, username, hash_, salt, type_)
+
+ def addAccess(self, devicePrefix, commandName, userPrefix, userDevice, accessToken):
+ """
+ Add a new access to the Access table, do nothing if the access already exists
+ :param Name devicePrefix: the device prefix
+ :param str command name : the command name
+ :param Name userPrefix: the user prefix
+ :param int userDevice: the user device
+ :param HMACKey accessToken: the access token
+ :return the access id if it's added successfully, 0 if the access already exists, otherwise -1
+ :rtype: int
+ """
+ #get device Id
+ deviceId = self._deviceStorage.getDeviceId(devicePrefix)
+ if deviceId == 0:
+ print 1
+ return -1
+
+ #get command id
+ commandId = self._deviceStorage.getCommandId(deviceId, commandName)
+ if commandId == 0:
+ print 2
+ return -1
+
+ #get user id
+ userId = self._userAccessStorage.getUserId(userPrefix)
+ if userId ==0:
+ print 3
+ return -1
+
+ return self._userAccessStorage.addAccess(commandId, userId, userDevice, accessToken)
+
+ def getAccessInfo(self, userPrefix, devicePrefix):
+ """
+ get all aceess info for pair(user, device)
+ :param Name userPrefix: the prefix of user
+ :param Name devicePrefix: the prefix of device
+ :return a list of tuples of form (str commandName,str userDevice, HmacKey accessToken). e.g. [('turn_on','laptop'. AccessToken1), ('turn_off','laptop' AccessToken2)], return None if no such access exists
+ :rtype list
+ """
+ #get device Id
+ deviceId = self._deviceStorage.getDeviceId(devicePrefix)
+
+ #get user Id
+ userId = self._userAccessStorage.getUserId(userPrefix)
+
+ if userId <= 0 or deviceId <= 0:
+ #either user or device doesn't exist in table
+ return None
+
+ #get command id list of device
+ commandIdList = self._deviceStorage.getCommandIdsOfDevice(deviceId)
+ if commandIdList == []:
+ return None
+
+ accessList =[]
+ for commandId in commandIdList:
+ doesExist = self._userAccessStorage.doesAccessExist(commandId, userId)
+ if doesExist:
+ commandName = self._deviceStorage.getCommandNameFromId(commandId)
+ userDeviceList = self._userAccessStorage.getUserDevices(commandId, userId)
+ for userDevice in userDeviceList:
+ accessToken = self._userAccessStorage.getAccessToken(commandId, userId, userDevice)
+ accessTuple = (commandName, userDevice, accessToken)
+ accessList.append(accessTuple)
+
+ return accessList