Applying requested changes

pull/47/head
Matheus Lima 2019-02-20 19:13:04 -03:00
parent f978ca5239
commit af83a190db
3 changed files with 68 additions and 40 deletions

View File

@ -1,10 +1,19 @@
import json
from http import HTTPStatus
from schematics import Model
from schematics.types import StringType, UUIDType
from selene.api import SeleneEndpoint
from selene.data.device import DeviceRepository
from selene.util.db import get_db_connection
from selene.util.cache import SeleneCache
from flask_restful import http_status_message
class AddDevice(Model):
name = StringType(required=True)
wake_word_id = UUIDType(required=True)
text_to_speech_id = UUIDType(required=True)
class AccountDeviceEndpoint(SeleneEndpoint):
@ -16,27 +25,32 @@ class AccountDeviceEndpoint(SeleneEndpoint):
self.device_pairing_time = 86400
def post(self, account_id):
device = json.loads(self.request.data)
if device:
name = device['name']
wake_word_id = device['wake_word_id']
text_to_speech_id = device['text_to_speech_id']
code = self.request.args['code']
# Checking if there's one pairing session for the pairing code
pairing_json = self.cache.get('pairing.code:{}'.format(code))
if pairing_json:
pairing = json.loads(pairing_json)
# Removing the pairing code from the cache
self.cache.delete('pairing.code:{}'.format(code))
# Finishing the pairing process
device_id = self._pair(account_id, name, wake_word_id, text_to_speech_id, pairing)
return device_id, http_status_message(200)
return http_status_message(204)
return http_status_message(204)
payload = json.loads(self.request.data)
device = AddDevice(payload)
device.validate()
code = self.request.args['code']
# Checking if there's one pairing session for the pairing code
pairing_json = self.cache.get('pairing.code:{}'.format(code))
if pairing_json:
device_id = self._finish_pairing(account_id, code, device, pairing_json)
response = device_id, HTTPStatus.OK
else:
response = '', HTTPStatus.NO_CONTENT
return response
@staticmethod
def _code_key(code):
return 'pairing.code:{}'.format(code)
def _finish_pairing(self, account_id, code, device, pairing_json):
pairing = json.loads(pairing_json)
# Removing the pairing code from the cache
self.cache.delete('pairing.code:{}'.format(code))
# Finishing the pairing process
device_id = self._pair(
account_id,
str(device.name),
str(device.wake_word_id),
str(device.text_to_speech_id),
pairing
)
return device_id
def _pair(self, account_id: str, name: str, wake_word_id: str, text_to_speech_id: str, pairing: dict):
"""Creates a device and associate it to a pairing session"""

View File

@ -1,14 +1,25 @@
import hashlib
import json
import uuid
from http import HTTPStatus
from schematics import Model
from schematics.types import StringType
from flask_restful import http_status_message
from selene.api import SeleneEndpoint
from selene.data.device import DeviceRepository
from selene.util.cache import SeleneCache
from selene.util.db import get_db_connection
class DeviceActivate(Model):
token = StringType(required=True)
state = StringType(required=True)
platform = StringType(default='unknown')
core_version = StringType(default='unknown')
enclosure_version = StringType(default='unknown')
class DeviceActivateEndpoint(SeleneEndpoint):
"""Endpoint to activate a device and finish the pairing process"""
@ -20,30 +31,33 @@ class DeviceActivateEndpoint(SeleneEndpoint):
self.sha512 = hashlib.sha512()
def post(self):
device_activate = json.loads(self.request.data)
payload = json.loads(self.request.data)
device_activate = DeviceActivate(payload)
if device_activate:
pairing = self._get_pairing_session(device_activate)
if pairing:
device_activate['uuid'] = pairing['uuid']
device_id = pairing['uuid']
self._activate(
pairing['uuid'],
device_activate.get('platform', 'unknown'),
device_activate.get('enclosure_version', 'unknown'),
device_activate.get('core_version', 'unknown')
device_id,
str(device_activate.platform),
str(device_activate.enclosure_version),
str(device_activate.core_version)
)
return self._generate_login(device_activate['uuid'])
return http_status_message(204)
return http_status_message(204)
response = self._generate_login(device_id), HTTPStatus.OK
else:
response = '', HTTPStatus.NO_CONTENT
else:
response = '', HTTPStatus.NO_CONTENT
return response
def _get_pairing_session(self, device_activate: dict):
def _get_pairing_session(self, device_activate: DeviceActivate):
"""Get the pairing session from the cache if device_activate has the same state that
the state stored in the pairing session"""
assert ('token' in device_activate and 'state' in device_activate)
token = device_activate['token']
token = str(device_activate.token)
pairing = self.cache.get(self._token_key(token))
if pairing:
pairing = json.loads(pairing)
if device_activate['state'] == pairing['state']:
if str(device_activate.state) == pairing['state']:
self.cache.delete(self._token_key(token))
return pairing

View File

@ -44,8 +44,8 @@ def activate_device(context):
def validate_response(context):
assert_that(context.pairing['state'], equal_to(context.state))
login = json.loads(context.activate_device_response.data)
assert_that(has_key(equal_to('uuid')))
assert_that(has_key(equal_to('accessToken')))
assert_that(has_key(equal_to('refreshToken')))
assert_that(has_key(equal_to('expiration')))
assert_that(context.device_id, equal_to(login['uuid']))
assert_that(login, has_key(equal_to('uuid')))
assert_that(login, has_key(equal_to('accessToken')))
assert_that(login, has_key(equal_to('refreshToken')))
assert_that(login, has_key(equal_to('expiration')))
assert_that(login, context.device_id, equal_to(login['uuid']))