Authentication ============== Lego uses CORS to deny requests from other domains than the once we control. OAuth2 authorization is required if you want to create an app that consumes information from the Lego API. JSON Web Tokens --------------- To authenticate using JWT, post to ``/api/token-auth/`` with a username and password. This will return a token, which can later be used with the following header: ``Authorization: JWT ``. To refresh a token, post to ``/api/token-auth/refresh`` with the token in the body. Both these endpoints can be used with JSON and regular forms. The webapp uses this authentication flow, third party apps should use OAuth2. OAuth2 ------ Lego has support for OAuth2 authentication using the ``authorization-code`` method. Everyone with a valid user and the right permissions is able to create an OAuth2 application. This works in the same way as ``Login with GitHub`` or any other OAuth2 system. You should never expose the ``client_secret`` to the public. Never implement the OAuth2 authorization flow in a browser. The snippet below can be used together with ``python-social-auth`` to authenticate with Lego as the user directory. We currently have two scopes. - ``user`` - This scope gives read access access to basic user information: Name, username, profile picture, email and the users memberships. This information can be found in ``/api/v1/users/oauth2_userdata/`` - ``all`` - This scope gives full read & write access to everything. Including password change. :: from six.moves.urllib.parse import urljoin from social_core.backends.oauth import BaseOAuth2 class LegoOAuth2(BaseOAuth2): name = 'lego' ACCESS_TOKEN_METHOD = 'POST' SCOPE_SEPARATOR = ',' EXTRA_DATA = [ ('id', 'id'), ('expires_in', 'expires_in'), ] def api_url(self): api_url = self.setting('API_URL') if not api_url: raise ValueError('Please set the LEGO_API_URL setting.') return api_url def get_scope(self): return ['user'] # Only use ['all'] when necessary (aka. never) def authorization_url(self): return urljoin(self.api_url(), '/authorization/oauth2/authorize/') def access_token_url(self): return urljoin(self.api_url(), '/authorization/oauth2/token/') def get_user_details(self, response): """Return user details from Lego account""" fullname, first_name, last_name = self.get_user_names( response.get('fullName'), response.get('firstName'), response.get('lastName') ) return {'username': response.get('username'), 'email': response.get('email') or '', 'fullname': fullname, 'first_name': first_name, 'last_name': last_name} def user_data(self, access_token, *args, **kwargs): return self._user_data(access_token) def _user_data(self, access_token): url = urljoin(self.api_url(), 'api/v1/users/me/') return self.get_json(url, headers={'AUTHORIZATION': 'Bearer %s' % access_token})