diff --git a/shared/selene/api/__init__.py b/shared/selene/api/__init__.py index 85e9e266..f3a38531 100644 --- a/shared/selene/api/__init__.py +++ b/shared/selene/api/__init__.py @@ -1,5 +1,3 @@ -from .account_endpoint import AccountEndpoint -from .agreements_endpoint import AgreementsEndpoint from .base_endpoint import APIError, SeleneEndpoint from .base_config import get_base_config from .response_data_formatter import JSON_MIMETYPE, output_json diff --git a/shared/selene/api/endpoints/__init__.py b/shared/selene/api/endpoints/__init__.py new file mode 100644 index 00000000..9c7f4ac2 --- /dev/null +++ b/shared/selene/api/endpoints/__init__.py @@ -0,0 +1,2 @@ +from .account import AccountEndpoint +from .agreements import AgreementsEndpoint diff --git a/shared/selene/api/account_endpoint.py b/shared/selene/api/endpoints/account.py similarity index 64% rename from shared/selene/api/account_endpoint.py rename to shared/selene/api/endpoints/account.py index 5a94be63..b67c0617 100644 --- a/shared/selene/api/account_endpoint.py +++ b/shared/selene/api/endpoints/account.py @@ -17,7 +17,7 @@ from selene.data.account import ( TERMS_OF_USE ) from selene.util.db import get_db_connection -from .base_endpoint import SeleneEndpoint +from ..base_endpoint import SeleneEndpoint def is_valid_membership(value): @@ -36,17 +36,31 @@ class Login(Model): user_entered_email = EmailType() password = StringType() + def validate_user_entered_email(self, data, value): + if data['federated_email'] is None: + if value is None: + raise ValidationError( + 'either a federated login or an email address is required' + ) + + def validate_password(self, data, value): + if data['user_entered_email'] is not None: + if value is None: + raise ValidationError( + 'email address must be accompanied by a password' + ) + class Support(Model): open_dataset = BooleanType(required=True) membership = StringType(required=True, validators=[is_valid_membership]) stripe_customer_id = StringType() - def validate_stripe_customer_id(self, data, value): - if data['membership'] != 'Maybe Later': - if not data['stripe_customer_id']: - raise ValidationError('Membership requires a stripe ID') - return value + # def validate_stripe_customer_id(self, data, value): + # if data['membership'] != 'Maybe Later': + # if not data['stripe_customer_id']: + # raise ValidationError('Membership requires a stripe ID') + # return value class AddAccountRequest(Model): @@ -69,7 +83,7 @@ class AccountEndpoint(SeleneEndpoint): if self.authenticated: response_data = asdict(self.account) del (response_data['refresh_tokens']) - self.response = (response_data, HTTPStatus.OK) + self.response = response_data, HTTPStatus.OK return self.response @@ -79,43 +93,39 @@ class AccountEndpoint(SeleneEndpoint): email_address, password = self._determine_login_method() self._add_account(email_address, password) + return 'Account added successfully', HTTPStatus.OK + def _validate_request(self): - try: - add_request = AddAccountRequest( - display_name=self.request.form['displayName'], - privacy_policy=self.request.form['privacyPolicy'], - terms_of_use=self.request.form['termsOfUse'], - login=self._build_login_schematic(), - support=self._build_support_schematic() - ) - add_request.validate() - except KeyError as ke: - error_msg = ( - 'post request missing an attribute necessary to create ' - 'an account' + str(ke) - ) - self.response = dict(error=error_msg), HTTPStatus.BAD_REQUEST - except ValidationError as ve: - error_msg = ve.messages - self.response = dict(error=error_msg), HTTPStatus.BAD_REQUEST + add_request = AddAccountRequest(dict( + display_name=self.request_data.get('displayName'), + privacy_policy=self.request_data.get('privacyPolicy'), + terms_of_use=self.request_data.get('termsOfUse'), + login=self._build_login_schematic(), + support=self._build_support_schematic() + )) + add_request.validate() def _build_login_schematic(self) -> Login: + login = None login_data = self.request_data['login'] - login = Login( - federated_email=login_data['federatedEmail'], - user_entered_email=login_data['userEnteredEmail'], - password=login_data['password'] - ) + if login_data is not None: + login = Login(dict( + federated_email=login_data.get('federatedEmail'), + user_entered_email=login_data.get('userEnteredEmail'), + password=login_data.get('password') + )) return login def _build_support_schematic(self): - support_data = self.request_data['support'] - support = Support( - open_dataset=support_data['openDataset'], - membership=support_data['membership'], - stripe_customer_id=support_data['stripeCustomId'] - ) + support = None + support_data = self.request_data.get('support') + if support_data is not None: + support = Support(dict( + open_dataset=support_data.get('openDataset'), + membership=support_data.get('membership'), + stripe_customer_id=support_data.get('stripeCustomerId') + )) return support diff --git a/shared/selene/api/agreements_endpoint.py b/shared/selene/api/endpoints/agreements.py similarity index 77% rename from shared/selene/api/agreements_endpoint.py rename to shared/selene/api/endpoints/agreements.py index d85e6276..c85cb202 100644 --- a/shared/selene/api/agreements_endpoint.py +++ b/shared/selene/api/endpoints/agreements.py @@ -4,7 +4,7 @@ from http import HTTPStatus from selene.data.account import AgreementRepository from selene.util.db import get_db_connection -from .base_endpoint import SeleneEndpoint +from ..base_endpoint import SeleneEndpoint class AgreementsEndpoint(SeleneEndpoint): @@ -21,8 +21,9 @@ class AgreementsEndpoint(SeleneEndpoint): agreement = agreement_repository.get_active_for_type( self.agreement_types[agreement_type] ) - agreement = asdict(agreement) - del(agreement['effective_date']) - self.response = (agreement, HTTPStatus.OK) + if agreement is not None: + agreement = asdict(agreement) + del(agreement['effective_date']) + self.response = agreement, HTTPStatus.OK return self.response