def lookupToken(self, token, expected_type, return_expired=False): if "_" not in token: return None checkfield = "security_check" if expected_type == "Refresh" and token.startswith("R_"): checkfield = "refresh_security_check" token = token[len("R_") :] token_id, security_check = token.split("_", 1) data = self.get_unique_data("token", token_id) if len(data) < 1: return None datum = data[token_id] if not constant_time_string_comparison(security_check, datum[checkfield]): return None if not return_expired and datum["expires_at"] <= int(time.time()): return None if expected_type and expected_type != "Refresh" and datum["type"] != expected_type: return None datum["scope"] = json.loads(datum["scope"]) datum["token_id"] = token_id return datum
def _handle_client_authentication(self, auth_method, client_id, client_secret): self.debug('Trying client auth for %s with method %s' % (client_id, auth_method)) if not client_id: self.error('Client authentication without client_id') raise APIError(400, 'invalid_client', 'client authentication error') client = self.cfg.datastore.getClient(client_id) if not client: self.error('Client authentication with invalid client ID') raise APIError(400, 'invalid_client', 'client authentication error') if client['client_secret_expires_at'] != 0 and \ client['client_secret_expires_at'] <= int(time.time()): self.error('Client authentication with expired secret') raise APIError(400, 'invalid_client', 'client authentication error') if client['token_endpoint_auth_method'] != auth_method: self.error('Client authentication with invalid auth method: %s' % auth_method) raise APIError(400, 'invalid_client', 'client authentication error') if auth_method == 'none': self.api_client_authenticated_no_secret = True elif not constant_time_string_comparison(client['client_secret'], client_secret): self.error('Client authentication with invalid secret: %s' % client_secret) raise APIError(400, 'invalid_client', 'client authentication error') self.api_client_authenticated = True self.api_client_id = client_id self.api_client = client
def refreshToken(self, refresh_token, client_id): token = self.lookupToken(refresh_token, "Refresh", True) if not token: return None if not constant_time_string_comparison(token["client_id"], client_id): return None if token["type"] != "Bearer": # Only Bearer tokens are supported return None if not token["refreshable"]: return None if token["refreshable_until"] and token["refreshable_until"] >= int(time.time()): return None token_security_check = generate_random_secure_string() refresh_security_check = generate_random_secure_string(128) expires_in = 3600 # TODO: Figure out values for this refreshable_until = None token["security_check"] = token_security_check token["refresh_security_check"] = refresh_security_check token["expires_at"] = int(time.time()) + expires_in token["refreshable_until"] = refreshable_until self.update_token(token) token = "%s_%s" % (token["token_id"], token_security_check) refresh_token = "R_%s_%s" % (token["token_id"], refresh_security_check) return {"access_token": token, "refresh_token": refresh_token, "expires_in": expires_in}