diff --git a/server/oauth/hep_client.py b/server/oauth/hep_client.py index 46d9cec0..37a91052 100644 --- a/server/oauth/hep_client.py +++ b/server/oauth/hep_client.py @@ -12,10 +12,11 @@ from core.logger import get_logger logger = get_logger(__name__) -VALID_PRODUCT_STATES = ['waiting', 'paid', 'completed', 'shipped'] +VALID_PRODUCT_STATES = ["waiting", "paid", "completed", "shipped"] licenses = get_license_dict() + class HepClientException(Exception): pass @@ -29,16 +30,16 @@ class HepClientNoTokenException(Exception): class HepClient: - - def _call(self, url, token_dict, method='get', data=None): - + def _call(self, url, token_dict, method="get", data=None): headers = {"accept": "application/json"} - if method == 'post': + if method == "post": response = oauth.hep.post(url, json=data, token=token_dict, headers=headers) - elif method == 'get': - response = oauth.hep.get(url, params=data, token=token_dict, headers=headers) - elif method == 'put': + elif method == "get": + response = oauth.hep.get( + url, params=data, token=token_dict, headers=headers + ) + elif method == "put": response = oauth.hep.put(url, data=data, token=token_dict, headers=headers) return self._handle_response(response) @@ -47,7 +48,9 @@ class HepClient: if response.status_code == 401: raise HepClientUnauthorizedException(response.status_code, response.json()) elif response.status_code != 200: - logger.warning(f'Hepclient error: Received {response.status_code} {response.json()}') + logger.warning( + f"Hepclient error: Received {response.status_code} {response.json()}" + ) raise HepClientException(response.status_code, response.json()) return response @@ -57,13 +60,15 @@ class HepClient: raise HepClientNoTokenException if not token_dict: - token_dict = fetch_token('', request) + token_dict = fetch_token("", request) if not token_dict: raise HepClientNoTokenException if OAuth2Token.is_dict_expired(token_dict): refresh_data = self._refresh_token(token_dict) - token, refresh_success = OAuth2Token.update_dict_with_refresh_data(refresh_data, token_dict['access_token']) + token, refresh_success = OAuth2Token.update_dict_with_refresh_data( + refresh_data, token_dict["access_token"] + ) if not refresh_success: raise HepClientUnauthorizedException @@ -72,38 +77,40 @@ class HepClient: return token_dict def _refresh_token(self, token_dict): - data = { - 'grant_type': 'refresh_token', - 'refresh_token': token_dict['refresh_token'], - 'client_id': settings.AUTHLIB_OAUTH_CLIENTS['hep']['client_id'], - 'client_secret': settings.AUTHLIB_OAUTH_CLIENTS['hep']['client_secret'], - 'scope': '' - } + "grant_type": "refresh_token", + "refresh_token": token_dict["refresh_token"], + "client_id": settings.AUTHLIB_OAUTH_CLIENTS["hep"]["client_id"], + "client_secret": settings.AUTHLIB_OAUTH_CLIENTS["hep"]["client_secret"], + "scope": "", + } - response = requests.post(f'{settings.AUTHLIB_OAUTH_CLIENTS["hep"]["api_base_url"]}/oauth/token', json=data) + response = requests.post( + f'{settings.AUTHLIB_OAUTH_CLIENTS["hep"]["api_base_url"]}/oauth/token', + json=data, + ) return self._handle_response(response).json() def is_email_verified(self, user_data): - return user_data['email_verified_at'] is not None + return user_data["email_verified_at"] is not None def user_details(self, request=None, token_dict=None): token_dict = self._get_valid_token(request, token_dict) - response = self._call('api/auth/user', token_dict) - return response.json()['data'] + response = self._call("api/auth/user", token_dict) + return response.json()["data"] def logout(self, request=None, token_dict=None): token_dict = self._get_valid_token(request, token_dict) - self._call('api/auth/logout', token_dict, method='post') + self._call("api/auth/logout", token_dict, method="post") return True def fetch_eorders(self, request=None, token_dict=None): token_dict = self._get_valid_token(request, token_dict) data = { - 'filters[product_type]': 'eLehrmittel', + "filters[product_type]": "eLehrmittel", } - response = self._call('api/partners/users/orders/search', token_dict, data=data) - return response.json()['data'] + response = self._call("api/partners/users/orders/search", token_dict, data=data) + return response.json()["data"] def active_myskillbox_product_for_customer(self, request=None, token_dict=None): eorders = self.fetch_eorders(request=request, token_dict=token_dict) @@ -118,9 +125,14 @@ class HepClient: def redeem_coupon(self, coupon_code, customer_id, request=None, token_dict=None): token_dict = self._get_valid_token(request, token_dict) try: - response = self._call(f'api/partners/users/{customer_id}/coupons/redeem', token_dict, method='post', - data={'code': coupon_code}) + response = self._call( + f"api/partners/users/{customer_id}/coupons/redeem", + token_dict, + method="post", + data={"code": coupon_code}, + ) except HepClientException: + logger.warning("could not redeem") return None response_data = response.json() @@ -130,14 +142,15 @@ class HepClient: products = [] for eorder in eorders: - - if 'items' not in eorder: + if "items" not in eorder: continue - status = eorder.get('status', '') + status = eorder.get("status", "") - for entry in eorder['items']: - product = self.entry_to_product(entry, self._get_item_activation(eorder), status) + for entry in eorder["items"]: + product = self.entry_to_product( + entry, self._get_item_activation(eorder), status + ) if product: products.append(product) @@ -145,35 +158,35 @@ class HepClient: return products def entry_to_product(self, entry, activation_date, status): - isbn = entry['isbn'] + isbn = entry["isbn"] if is_myskillbox_product(isbn) and activation_date: return { - 'raw': entry, - 'activated': activation_date, - 'status': status, - 'order_id': entry['id'], - 'license': licenses[isbn], - 'isbn': entry['isbn'] - } + "raw": entry, + "activated": activation_date, + "status": status, + "order_id": entry["id"], + "license": licenses[isbn], + "isbn": entry["isbn"], + } return None def _get_item_activation(self, eorder): - if 'created_at' in eorder: - return parse_datetime(eorder['created_at']) + if "created_at" in eorder: + return parse_datetime(eorder["created_at"]) else: return None def _get_active_product(self, products): - def filter_valid_products(product): - - if product['status'] not in VALID_PRODUCT_STATES: + if product["status"] not in VALID_PRODUCT_STATES: return False - expiry_delta = product['activated'] + timedelta(product['license']['duration']) + expiry_delta = product["activated"] + timedelta( + product["license"]["duration"] + ) - return License.is_product_active(expiry_delta, product['isbn']) + return License.is_product_active(expiry_delta, product["isbn"]) active_products = list(filter(filter_valid_products, products)) @@ -185,10 +198,9 @@ class HepClient: return self._select_from_teacher_products(active_products) def _select_from_teacher_products(self, active_products): - # select first teacher product, as they are all valid it does not matter which one for product in active_products: - if product['license']['edition'] == TEACHER_KEY: + if product["license"]["edition"] == TEACHER_KEY: return product # select a student product, as they are all valid it does not matter which one diff --git a/server/oauth/mutations.py b/server/oauth/mutations.py index 55ab14d5..f199c06e 100644 --- a/server/oauth/mutations.py +++ b/server/oauth/mutations.py @@ -2,6 +2,7 @@ import graphene from django.contrib.auth import logout from django.utils.timezone import now from graphene import relay +from core.logger import get_logger from oauth.hep_client import HepClient, HepClientException from oauth.models import OAuth2Token @@ -9,6 +10,8 @@ from oauth.types import InvalidCouponFailure, RedeemCouponResult, RedeemCouponSu from oauth.user_signup_login_handler import create_role_for_user from users.models import License +logger = get_logger(__name__) + class Coupon(relay.ClientIDMutation): class Input: @@ -20,6 +23,7 @@ class Coupon(relay.ClientIDMutation): def mutate_and_get_payload(cls, root, info, **kwargs): coupon_code = kwargs.get("coupon_code").strip() hep_client = HepClient() + logger.info("redeeming coupon") try: hep_id = info.context.user.hep_id @@ -31,7 +35,8 @@ class Coupon(relay.ClientIDMutation): response = hep_client.redeem_coupon( coupon_code, hep_id, request=info.context ) - except HepClientException: + except HepClientException as e: + logger.warning(e) raise Exception("unknown_error") if not response: @@ -40,8 +45,10 @@ class Coupon(relay.ClientIDMutation): product = hep_client.entry_to_product(response["data"], now(), "coupon") if not product: + logger.info("no myskillbox-product found") raise Exception("non_myskillbox_product") + logger.info("creating license") license = License.objects.create_license_for_role( info.context.user, product["activated"], @@ -51,6 +58,7 @@ class Coupon(relay.ClientIDMutation): product["isbn"], ) + logger.info("creating role for user") create_role_for_user(info.context.user, license.for_role.key) return cls(result=RedeemCouponSuccess) diff --git a/server/oauth/user_signup_login_handler.py b/server/oauth/user_signup_login_handler.py index e7a964e7..ba43145b 100644 --- a/server/oauth/user_signup_login_handler.py +++ b/server/oauth/user_signup_login_handler.py @@ -30,7 +30,7 @@ def handle_user_and_verify_products(user_data, token): license, error_msg = check_and_create_licenses(hep_client, user, token) if error_msg: - logger.warn(error_msg) + logger.warning(error_msg) return user, error_msg logger.info("creating role")