def nokia_auth(): print('First we need your Client ID, Consumer Secret, and Callback URI') print( 'You can find it here: https://account.withings.com/partner/dashboard_oauth2' ) client_id = input('client_id: ') consumer_secret = input('consumer_secret: ') callback_uri = input('callback_uri: ') auth = NokiaAuth(client_id, consumer_secret, callback_uri=callback_uri) authorize_url = auth.get_authorize_url() print( 'Now you should open this authorization URL and give the app access: ') print(authorize_url) auth_url = input('Enter the response URL: ') # We have to parse the URL to extract the code from the query string u = urlparse(auth_url) auth_code = parse_qs(u.query)['code'][0] creds = auth.get_credentials(auth_code) # Save this so we don't have to do this again save_creds(creds) # Pass back return creds
def test_get_authorize_url(self): """ Make sure the get_authorize_url function works as expected """ auth = NokiaAuth(*self.auth_args, callback_uri=self.callback_uri) # Returns the OAuth2Session.authorization_url results self.assertEqual(auth.get_authorize_url(), 'URL') OAuth2Session.authorization_url.assert_called_once_with( '{}/oauth2_user/authorize2'.format(NokiaAuth.URL))
def test_get_authorize_url(self): """ Make sure the get_authorize_url function works as expected """ auth = NokiaAuth(*self.auth_args, callback_uri=self.callback_uri) # Returns the OAuth2Session.authorization_url results self.assertEqual(auth.get_authorize_url(), 'URL') OAuth2Session.authorization_url.assert_called_once_with( '{}/oauth2_user/authorize2'.format(NokiaAuth.URL) )
def test_get_authorize_url(self): """ Make sure the get_authorize_url function works as expected """ auth = NokiaAuth(self.consumer_key, self.consumer_secret) # Returns the OAuth1Session.authorization_url results self.assertEqual(auth.get_authorize_url(), 'URL') # oauth_token and oauth_secret have now been set to the values # returned by OAuth1Session.fetch_request_token self.assertEqual(auth.oauth_token, 'fake_oauth_token') self.assertEqual(auth.oauth_secret, 'fake_oauth_token_secret')
def test_migrate_from_oauth1(self): """ Make sure the migrate_from_oauth1 fucntion works as expected """ Session.request = MagicMock() auth = NokiaAuth(*self.auth_args) token = auth.migrate_from_oauth1('at', 'ats') self.assertEqual(token, self.token) OAuth2Session.refresh_token.assert_called_once_with( '{}/oauth2/token'.format(NokiaAuth.URL), refresh_token='at:ats')
def test_migrate_from_oauth1(self): """ Make sure the migrate_from_oauth1 fucntion works as expected """ Session.request = MagicMock() auth = NokiaAuth(*self.auth_args) token = auth.migrate_from_oauth1('at', 'ats') self.assertEqual(token, self.token) OAuth2Session.refresh_token.assert_called_once_with( '{}/oauth2/token'.format(NokiaAuth.URL), refresh_token='at:ats' )
def test_get_credentials(self): """ Make sure the get_credentials function works as expected """ auth = NokiaAuth(self.consumer_key, self.consumer_secret) # Returns an authorized NokiaCredentials object creds = auth.get_credentials('FAKE_OAUTH_VERIFIER') assert isinstance(creds, NokiaCredentials) # Check that the attributes of the NokiaCredentials object are # correct. self.assertEqual(creds.access_token, 'fake_oauth_token') self.assertEqual(creds.access_token_secret, 'fake_oauth_token_secret') self.assertEqual(creds.consumer_key, self.consumer_key) self.assertEqual(creds.consumer_secret, self.consumer_secret) self.assertEqual(creds.user_id, 'FAKEID')
def test_attribute_defaults(self): """ Make sure NokiaAuth attributes have the proper defaults """ self.assertEqual(NokiaAuth.URL, 'https://developer.health.nokia.com/account') auth = NokiaAuth(self.consumer_key, self.consumer_secret) self.assertEqual(auth.oauth_token, None) self.assertEqual(auth.oauth_secret, None)
def test_get_credentials(self): """ Make sure the get_credentials function works as expected """ auth = NokiaAuth(*self.auth_args, callback_uri=self.callback_uri) # Returns an authorized NokiaCredentials object creds = auth.get_credentials('FAKE_CODE') assert isinstance(creds, NokiaCredentials) # Check that the attributes of the NokiaCredentials object are # correct. self.assertEqual(creds.access_token, 'fake_access_token') self.assertEqual(creds.token_expiry, str(int(( datetime.datetime.utcnow() - datetime.datetime(1970, 1, 1) ).total_seconds()))) self.assertEqual(creds.token_type, 'Bearer') self.assertEqual(creds.refresh_token, 'fake_refresh_token') self.assertEqual(creds.client_id, self.client_id) self.assertEqual(creds.consumer_secret, self.consumer_secret) self.assertEqual(creds.user_id, 'fake_user_id')
def test_attributes(self): """ Make sure the NokiaAuth objects have the right attributes """ assert hasattr(NokiaAuth, 'URL') auth = NokiaAuth(self.consumer_key, self.consumer_secret) assert hasattr(auth, 'consumer_key') self.assertEqual(auth.consumer_key, self.consumer_key) assert hasattr(auth, 'consumer_secret') self.assertEqual(auth.consumer_secret, self.consumer_secret)
def test_get_credentials(self): """ Make sure the get_credentials function works as expected """ auth = NokiaAuth(*self.auth_args, callback_uri=self.callback_uri) # Returns an authorized NokiaCredentials object creds = auth.get_credentials('FAKE_CODE') assert isinstance(creds, NokiaCredentials) # Check that the attributes of the NokiaCredentials object are # correct. self.assertEqual(creds.access_token, 'fake_access_token') self.assertEqual( creds.token_expiry, str( int((datetime.datetime.utcnow() - datetime.datetime(1970, 1, 1)).total_seconds()))) self.assertEqual(creds.token_type, 'Bearer') self.assertEqual(creds.refresh_token, 'fake_refresh_token') self.assertEqual(creds.client_id, self.client_id) self.assertEqual(creds.consumer_secret, self.consumer_secret) self.assertEqual(creds.user_id, 'fake_user_id')
def migrate_to_oauth2(apps, schema_editor): NokiaUser = apps.get_model("nokiaapp", "NokiaUser") auth = NokiaAuth( get_setting('NOKIA_CLIENT_ID'), get_setting('NOKIA_CONSUMER_SECRET')) for user in NokiaUser.objects.all(): try: token = auth.migrate_from_oauth1( user.access_token, user.access_token_secret ) user.access_token = token['access_token'] user.token_expiry = int(( datetime.datetime.utcnow() - datetime.datetime(1970, 1, 1) ).total_seconds()) + int(token['expires_in']) user.token_type = token['token_type'] user.refresh_token = token['refresh_token'] user.save() except: # Problem with existing token user.delete()
def check_withings_connection(): # If not connected, send to auth app page to start token request if not withings_connected(): return html.A(className='text-center col-lg-12', children=[ dbc.Button('Connect Withings', id='connect-withings-btton', color='primary', className='text-center mb-2', size='md')], href=connect_withings_link( NokiaAuth(config.get('withings', 'client_id'), config.get('withings', 'client_secret'), callback_uri=config.get('withings', 'redirect_uri')))) else: return html.H4('Withings Connected!', className='text-center col-lg-12', )
def test_attributes(self): """ Make sure the NokiaAuth objects have the right attributes """ assert hasattr(NokiaAuth, 'URL') self.assertEqual(NokiaAuth.URL, 'https://account.health.nokia.com') auth = NokiaAuth(*self.auth_args, callback_uri=self.callback_uri) assert hasattr(auth, 'client_id') self.assertEqual(auth.client_id, self.client_id) assert hasattr(auth, 'consumer_secret') self.assertEqual(auth.consumer_secret, self.consumer_secret) assert hasattr(auth, 'callback_uri') self.assertEqual(auth.callback_uri, self.callback_uri) assert hasattr(auth, 'scope') self.assertEqual(auth.scope, 'user.metrics')
def __init__(self): try: with open('personal_dashboard/nokia_data.pkl', 'rb') as pickle_file: nokia = pickle.load(pickle_file) self.measures = nokia.get_measures() measures = nokia.get_measures(limit=1) self.weight = round(float(measures[0].weight) * 2.20462, 2) pickle_file.close() except: auth = NokiaAuth(WITHINGS_KEYS['API_KEY'], WITHINGS_KEYS['API_SECRET']) authorize_url = auth.get_authorize_url() print("Go to %s allow the app and copy your oauth_verifier" % authorize_url) oauth_verifier = input('Please enter your oauth_verifier: ') creds = auth.get_credentials(oauth_verifier) client = NokiaApi(creds) with open('personal_dashboard/nokia_data.pkl', 'wb') as output: pickle.dump(client, output, pickle.HIGHEST_PROTOCOL) self.measures = client.get_measures() measures = client.get_measures(limit=1) #Convert Kg to Lbs self.weight = round(float(measures[0].weight) * 2.20462, 2)
def __init__(self, smarthome, consumer_key, consumer_secret, access_token, access_token_secret, user_id, cycle=300): self.logger = logging.getLogger(__name__) self._sh = smarthome self._consumer_key = consumer_key self._consumer_secret = consumer_secret self._access_token = access_token self._access_token_secret = access_token_secret self._auth = NokiaAuth(self._consumer_key, self._consumer_secret) self._user_id = user_id self._creds = NokiaCredentials(self._access_token, self._access_token_secret, self._consumer_key, self._consumer_secret, self._user_id) self._client = NokiaApi(self._creds) self._cycle = cycle self._items = {} if not self.init_webinterface(): self._init_complete = False
def get(self, request): """Finish OAuth callback request.""" from oauthlib.oauth2.rfc6749.errors import MismatchingStateError from oauthlib.oauth2.rfc6749.errors import MissingTokenError from nokia import NokiaAuth hass = request.app['hass'] data = request.query response_message = """Nokia Health has been successfully authorized! You can close this window now!""" result = None if data.get('code') is not None: oauth = NokiaAuth(self.config.get(ATTR_API_KEY), self.config.get(ATTR_API_SECRET)) redirect_uri = oauth.get_authorize_url() try: result = self.oauth.fetch_access_token(data.get('code'), redirect_uri) print(result) oauth_verifier = result.get('oauth_verifier') print(oauth_verifier) except MissingTokenError as error: _LOGGER.error("Missing token: %s", error) response_message = """Something went wrong when attempting authenticating with Nokia Health. The error encountered was {}. Please try again!""".format(error) except MismatchingStateError as error: _LOGGER.error("Mismatched state, CSRF error: %s", error) response_message = """Something went wrong when attempting authenticating with Nokia Health. The error encountered was {}. Please try again!""".format(error) else: _LOGGER.error("Unknown error when authing") response_message = """Something went wrong when attempting authenticating with Nokia Health. An unknown error occurred. Please try again! """ if result is None: _LOGGER.error("Unknown error when authing") response_message = """Something went wrong when attempting authenticating with Nokia Health. An unknown error occurred. Please try again! """ html_response = """<html><head><title>Nokia Health Auth</title></head> <body><h1>{}</h1></body></html>""".format(response_message) if result: config_contents = { ATTR_ACCESS_TOKEN: result.get('access_token'), ATTR_REFRESH_TOKEN: result.get('refresh_token'), ATTR_CLIENT_ID: self.oauth.client_id, ATTR_CLIENT_SECRET: self.oauth.client_secret, ATTR_LAST_SAVED_AT: int(time.time()) } save_json(hass.config.path(NOKIA_HEALTH_CONFIG_FILE), config_contents) hass.async_add_job(setup_platform, hass, self.config, self.add_devices) return html_response
class WebInterface(SmartPluginWebIf): def __init__(self, webif_dir, plugin): """ Initialization of instance of class WebInterface :param webif_dir: directory where the webinterface of the plugin resides :param plugin: instance of the plugin :type webif_dir: str :type plugin: object """ self.logger = logging.getLogger(__name__) self.webif_dir = webif_dir self.plugin = plugin self._creds = None self._auth = None self.tplenv = self.init_template_environment() def _get_callback_url(self): ip = self.plugin.mod_http.get_local_ip_address() port = self.plugin.mod_http.get_local_port() web_ifs = self.plugin.mod_http.get_webifs_for_plugin( self.plugin.get_shortname()) for web_if in web_ifs: if web_if['Instance'] == self.plugin.get_instance_name(): callback_url = "http://{}:{}{}".format(ip, port, web_if['Mount']) self.logger.debug( "Plugin '{}': WebIf found, callback is {}".format( self.plugin.get_fullname(), callback_url)) return callback_url self.logger.error( "Plugin '{}': Callback URL cannot be established.".format( self.plugin.get_fullname())) @cherrypy.expose def index(self, reload=None, state=None, code=None, error=None): """ Build index.html for cherrypy Render the template and return the html file to be delivered to the browser :return: contents of the template after beeing rendered """ if self._auth is None: self._auth = NokiaAuth( self.plugin._client_id, self.plugin._consumer_secret, callback_uri=self._get_callback_url(), scope='user.info,user.metrics,user.activity') if not reload and code: self.logger.debug("Plugin '{}': Got code as callback: {}".format( self.plugin.get_fullname(), code)) credentials = None try: credentials = self._auth.get_credentials(code) except Exception as e: self.logger.error( "Plugin '{}': An error occurred, perhaps code parameter is invalid or too old? Message: {}" .format(self.plugin.get_fullname(), str(e))) if credentials is not None: self._creds = credentials self.logger.debug( "Plugin '{}': New credentials are: access_token {}, token_expiry {}, token_type {}, refresh_token {}" .format(self.plugin.get_fullname(), self._creds.access_token, self._creds.token_expiry, self._creds.token_type, self._creds.refresh_token)) self.plugin.get_item('access_token')(self._creds.access_token) self.plugin.get_item('token_expiry')(self._creds.token_expiry) self.plugin.get_item('token_type')(self._creds.token_type) self.plugin.get_item('refresh_token')( self._creds.refresh_token) self.plugin._client = None tmpl = self.tplenv.get_template('index.html') return tmpl.render(plugin_shortname=self.plugin.get_shortname(), plugin_version=self.plugin.get_version(), interface=None, item_count=len(self.plugin.get_items()), plugin_info=self.plugin.get_info(), tabcount=2, callback_url=self._get_callback_url(), tab1title="Withings Health Items (%s)" % len(self.plugin.get_items()), tab2title="OAuth2 Data", authorize_url=self._auth.get_authorize_url(), p=self.plugin, token_expiry=datetime.datetime.fromtimestamp( self.plugin.get_item('token_expiry')(), tz=self.plugin.shtime.tzinfo()), now=self.plugin.shtime.now(), code=code, state=state, reload=reload, language=self.plugin.get_sh().get_defaultlanguage())
def index(self, reload=None, state=None, code=None, error=None): """ Build index.html for cherrypy Render the template and return the html file to be delivered to the browser :return: contents of the template after beeing rendered """ if self._auth is None: self._auth = NokiaAuth( self.plugin._client_id, self.plugin._consumer_secret, callback_uri=self._get_callback_url(), scope='user.info,user.metrics,user.activity') if not reload and code: self.logger.debug("Plugin '{}': Got code as callback: {}".format( self.plugin.get_fullname(), code)) credentials = None try: credentials = self._auth.get_credentials(code) except Exception as e: self.logger.error( "Plugin '{}': An error occurred, perhaps code parameter is invalid or too old? Message: {}" .format(self.plugin.get_fullname(), str(e))) if credentials is not None: self._creds = credentials self.logger.debug( "Plugin '{}': New credentials are: access_token {}, token_expiry {}, token_type {}, refresh_token {}" .format(self.plugin.get_fullname(), self._creds.access_token, self._creds.token_expiry, self._creds.token_type, self._creds.refresh_token)) self.plugin.get_item('access_token')(self._creds.access_token) self.plugin.get_item('token_expiry')(self._creds.token_expiry) self.plugin.get_item('token_type')(self._creds.token_type) self.plugin.get_item('refresh_token')( self._creds.refresh_token) self.plugin._client = None tmpl = self.tplenv.get_template('index.html') return tmpl.render(plugin_shortname=self.plugin.get_shortname(), plugin_version=self.plugin.get_version(), interface=None, item_count=len(self.plugin.get_items()), plugin_info=self.plugin.get_info(), tabcount=2, callback_url=self._get_callback_url(), tab1title="Withings Health Items (%s)" % len(self.plugin.get_items()), tab2title="OAuth2 Data", authorize_url=self._auth.get_authorize_url(), p=self.plugin, token_expiry=datetime.datetime.fromtimestamp( self.plugin.get_item('token_expiry')(), tz=self.plugin.shtime.tzinfo()), now=self.plugin.shtime.now(), code=code, state=state, reload=reload, language=self.plugin.get_sh().get_defaultlanguage())
from oura import OuraOAuth2Client from lib.withingsAPI import save_withings_token import configparser import re import time from nokia import NokiaAuth, NokiaApi config = configparser.ConfigParser() config.read('config.ini') client_id = config.get('withings', 'client_id') client_secret = config.get('withings', 'client_secret') redirect_uri = config.get('withings', 'redirect_uri') auth_client = NokiaAuth(client_id, client_secret, callback_uri=redirect_uri) layout = html.Div(id='withings-auth-canvas', children=[ html.Div(id='withings-token-refresh', style={'display': 'none'}), dcc.Loading(html.Div(id='withings-auth-layout')) ]) def test_withings_connection(): time.sleep(3) if not withings_connected(): return html.Div(style={'textAlign': 'center'}, className='twelve columns', children=[
from nokia import NokiaAuth, NokiaApi from ..api.sqlalchemy_declarative import db_connect, stravaSummary, ouraSleepSummary, athlete, hrvWorkoutStepLog from ..api.datapull import refresh_database from sqlalchemy import delete import pandas as pd from dateutil.relativedelta import relativedelta from datetime import datetime import operator from ..api.fitlyAPI import hrv_training_workflow from ..app import app from flask import current_app as server import re from ..utils import config strava_auth_client = get_strava_client() withings_auth_client = NokiaAuth(config.get('withings', 'client_id'), config.get('withings', 'client_secret'), callback_uri=config.get('withings', 'redirect_uri')) oura_auth_client = OuraOAuth2Client(client_id=config.get('oura', 'client_id'), client_secret=config.get('oura', 'client_secret')) def get_layout(**kwargs): return html.Div([ html.Div(id='settings-layout'), html.Div(id='clear-log-dummy', style={'display': 'none'}), html.Div(id='token-dummy', style={'display': 'none'}), dbc.Modal(id="settings-modal", centered=True, autoFocus=True, fade=False, backdrop=True, size='sm', is_open=True, children=[ dbc.ModalHeader("Enter Admin Password"), dbc.ModalBody(className='text-center', children=[ dcc.Input(id='settings-password', type='password', placeholder='Password', value='')]),
def async_setup_platform(hass, config, async_add_devices, discovery_info=None): """Authenticate to the Withings API.""" from nokia import NokiaApi, NokiaAuth, NokiaCredentials hass.http.register_view(WithingsAuthCallbackView()) client_id = config.get(CONF_CLIENT_ID) consumer_secret = config.get(CONF_CONSUMER_SECRET) config_path = hass.config.path(WITHINGS_CONFIG_PATH) @asyncio.coroutine def _read_config(): if not os.path.isfile(config_path): return None with open(config_path, 'r') as auth_file: config = json.load(auth_file) if config.get('client_id') == client_id: return config @asyncio.coroutine def _write_config(creds): with open(config_path, 'w') as auth_file: json.dump( { 'client_id': client_id, 'access_token': creds.access_token, 'refresh_token': creds.refresh_token, 'token_type': creds.token_type, 'token_expiry': creds.token_expiry, 'user_id': creds.user_id, }, auth_file) @asyncio.coroutine def _add_device(creds): client = NokiaApi(creds) withings = WithingsSensor(hass, client) yield from withings.async_update() return async_add_devices([withings]) config = yield from _read_config() if config is not None: creds = NokiaCredentials(client_id=client_id, consumer_secret=consumer_secret, access_token=config['access_token'], token_expiry=config['token_expiry'], token_type=config['token_type'], refresh_token=['refresh_token'], user_id=config['user_id']) yield from _add_device(creds) else: callback_uri = '{}{}'.format(hass.config.api.base_url, WithingsAuthCallbackView.url) auth = NokiaAuth(client_id, consumer_secret, callback_uri=callback_uri, scope='user.info,user.metrics,user.activity') authorize_url = auth.get_authorize_url() configurator = hass.components.configurator request_id = configurator.async_request_config( "Withings", description="Authorization required for Withings account.", link_name="Authorize Home Assistant", link_url=authorize_url, entity_picture='/local/images/logo_nokia_health_mate.png') @asyncio.coroutine def initialize_callback(code): """Handle OAuth callback from Withings authorization flow.""" creds = auth.get_credentials(code) yield from _write_config(creds) yield from _add_device(creds) configurator.async_request_done(request_id) hass.data[DATA_CALLBACK] = initialize_callback return True
def async_setup_platform(hass, config, async_add_devices, discovery_info=None): """Authenticate to the Nokia Health API.""" from nokia import NokiaApi, NokiaAuth, NokiaCredentials hass.http.register_view(NokiaAuthCallbackView()) consumer_key = config.get(CONF_CONSUMER_KEY) consumer_secret = config.get(CONF_CONSUMER_SECRET) config_path = hass.config.path(NOKIA_CONFIG_PATH) @asyncio.coroutine def _read_config(): if not os.path.isfile(config_path): return None with open(config_path, 'r') as auth_file: config = json.load(auth_file) if config['consumer_key'] == consumer_key: return config @asyncio.coroutine def _write_config(creds): with open(config_path, 'w') as auth_file: json.dump( { 'consumer_key': consumer_key, 'access_token': creds.access_token, 'access_token_secret': creds.access_token_secret, 'user_id': creds.user_id, }, auth_file) @asyncio.coroutine def _add_device(creds): client = NokiaApi(creds) nokia = NokiaSensor(hass, client) yield from nokia.async_update() return async_add_devices([nokia]) config = yield from _read_config() if config is not None: creds = NokiaCredentials(config['access_token'], config['access_token_secret'], consumer_key, consumer_secret, config['user_id']) yield from _add_device(creds) else: auth = NokiaAuth(consumer_key, consumer_secret) callback_uri = '{}{}'.format(hass.config.api.base_url, NokiaAuthCallbackView.url) authorize_url = auth.get_authorize_url(callback_uri=callback_uri) configurator = hass.components.configurator request_id = configurator.async_request_config( "Nokia Health", description="Authorization required for Nokia Health account.", link_name="Authorize Home Assistant", link_url=authorize_url, entity_picture='/local/images/logo_nokia_health_mate.png') @asyncio.coroutine def initialize_callback(oauth_verifier): """Handle OAuth callback from Nokia authorization flow.""" creds = auth.get_credentials(oauth_verifier) yield from _write_config(creds) yield from _add_device(creds) configurator.async_request_done(request_id) hass.data[DATA_CALLBACK] = initialize_callback return True