|
|
@@ -87,7 +87,8 @@ app.config.update({
|
|
|
os.getenv('FREEPBX_CDRDBNAME', None)),
|
|
|
'EXTRA_API_URL': os.getenv('APP_EXTRA_API_URL', None)})
|
|
|
|
|
|
-app.cache = {'devices':[],
|
|
|
+app.cache = {'devices':{},
|
|
|
+ 'usermap':{},
|
|
|
'ustates':{},
|
|
|
'pstates':{},
|
|
|
'queues':{}}
|
|
|
@@ -106,6 +107,9 @@ manager = Manager(
|
|
|
def authRequired(func):
|
|
|
@wraps(func)
|
|
|
async def authWrapper(*args, **kwargs):
|
|
|
+ request.user = None
|
|
|
+ request.device = None
|
|
|
+ request.admin = False
|
|
|
auth = request.authorization
|
|
|
headers = request.headers
|
|
|
if ((auth is not None) and
|
|
|
@@ -113,9 +117,12 @@ def authRequired(func):
|
|
|
(auth.username in current_app.cache['devices']) and
|
|
|
(compare_digest(auth.password, current_app.cache['devices'][auth.username]))):
|
|
|
request.device = auth.username
|
|
|
+ if request.device in current_app.cache['usermap']:
|
|
|
+ request.user = current_app.cache[request.device]
|
|
|
return await func(*args, **kwargs)
|
|
|
elif ((current_app.config['AUTH_HEADER'].lower() in headers) and
|
|
|
(headers[current_app.config['AUTH_HEADER'].lower()] == current_app.config['AUTH_SECRET'])):
|
|
|
+ request.admin = True
|
|
|
return await func(*args, **kwargs)
|
|
|
else:
|
|
|
abort(401)
|
|
|
@@ -260,14 +267,11 @@ async def ui():
|
|
|
js_url=app.config['SWAGGER_JS_URL'],
|
|
|
css_url=app.config['SWAGGER_CSS_URL'])
|
|
|
|
|
|
-
|
|
|
-# @app.route('/ami/action', methods=['POST'])
|
|
|
async def action():
|
|
|
_payload = await request.get_data()
|
|
|
reply = await manager.send_action(json.loads(_payload))
|
|
|
return str(reply)
|
|
|
|
|
|
-# @app.route('/ami/getvar/<string:variable>')
|
|
|
async def amiGetVar(variable):
|
|
|
'''AMI GetVar
|
|
|
Returns value of requested variable using AMI action GetVar in background.
|
|
|
@@ -286,11 +290,15 @@ async def amiGetVar(variable):
|
|
|
@authRequired
|
|
|
@app.route('/ami/auths')
|
|
|
async def amiPJSIPShowAuths():
|
|
|
+ if not request.admin:
|
|
|
+ abort(401)
|
|
|
return successReply(app.cache['devices'])
|
|
|
|
|
|
@authRequired
|
|
|
@app.route('/ami/aors')
|
|
|
async def amiPJSIPShowAors():
|
|
|
+ if not request.admin:
|
|
|
+ abort(401)
|
|
|
aors = {}
|
|
|
reply = await manager.send_action({'Action':'PJSIPShowAors'})
|
|
|
if len(reply) >= 2:
|
|
|
@@ -619,6 +627,7 @@ async def refreshQueuesCache():
|
|
|
return len(app.cache['queues'])
|
|
|
|
|
|
async def rebindLostDevices():
|
|
|
+ app.cache['usermap'] = {}
|
|
|
ast = await getGlobalVars()
|
|
|
for device in app.cache['devices']:
|
|
|
user = await getDeviceUser(device)
|
|
|
@@ -631,6 +640,8 @@ async def rebindLostDevices():
|
|
|
await setUserHint(user, dial, ast) # Set hints for user on new device
|
|
|
await setUserDeviceStates(user, device, ast) # Set device states for users device
|
|
|
await setUserDevice(user, device) # Bind device to user
|
|
|
+ app.cache['usermap'][device] = user
|
|
|
+ app.logger.warning(pformat(app.cache['usermap']))
|
|
|
|
|
|
async def userStateChangeCallback(user, state, prevState = None):
|
|
|
reply = None
|
|
|
@@ -753,6 +764,8 @@ class UsersStates(Resource):
|
|
|
'''Returns all users with their combined states.
|
|
|
Possible states are: available, away, dnd, inuse, busy, unavailable, ringing
|
|
|
'''
|
|
|
+ if not request.admin:
|
|
|
+ abort(401)
|
|
|
#app.logger.warning('request device: {}'.format(request.device))
|
|
|
usersCount = await refreshStatesCache()
|
|
|
if usersCount == 0:
|
|
|
@@ -819,8 +832,7 @@ class UsersDevices(Resource):
|
|
|
@app.response(HTTPStatus.OK, 'JSON reply with user:device map or error message')
|
|
|
@app.response(HTTPStatus.UNAUTHORIZED, 'Authorization required')
|
|
|
async def get(self):
|
|
|
- '''Returns all users with their combined states.
|
|
|
- Possible states are: available, away, dnd, inuse, busy, unavailable, ringing
|
|
|
+ '''Returns users to device maping.
|
|
|
'''
|
|
|
data = {}
|
|
|
for user in app.cache['ustates']:
|
|
|
@@ -869,6 +881,7 @@ class UserDeviceBind(Resource):
|
|
|
await setUserDeviceStates(user, device, ast) # Set device states for users new device
|
|
|
if not (await setUserDevice(user, device)): # Bind device to user
|
|
|
return bindError(user, device)
|
|
|
+ app.cache['usermap'][device] = user
|
|
|
return successfullyBound(user, device)
|
|
|
|
|
|
@app.route('/device/<device>/off')
|
|
|
@@ -894,6 +907,7 @@ class DeviceUnBind(Resource):
|
|
|
await setQueueStates(currentUser, device, 'NOT_INUSE')
|
|
|
await setUserHint(currentUser, None, ast) # set hints for current user
|
|
|
await setDeviceUser(device, 'none') # Unbind user from device
|
|
|
+ del app.cache['usermap'][device]
|
|
|
return successfullyUnbound(currentUser, device)
|
|
|
|
|
|
@app.route('/cdr')
|