def post_reauthenticated(self, params): submit_type = params.get('submittype') if submit_type == 'cancel': self.redirect(enki.libutil.get_local_url('profile')) elif submit_type == 'delete': delete_posts = False if enki.HandlerBase.account_is_active(self.enki_user.key.id()): has_posts = True if enki.libforum.fetch_EnkiPost_by_author( self.enki_user.key.id()) else False if has_posts and params.get('deleteposts') == 'on': delete_posts = True if self.enki_user.email and self.enki_user.email != 'removed': # if the user has an email, send a confirmation email self.account_deletion_request(delete_posts) if delete_posts: self.add_infomessage( 'info', MSG.INFORMATION(), MSG.ACCOUNT_AND_POSTS_DELETE_INFO_EMAIL_SENT( self.enki_user.email)) else: self.add_infomessage( 'info', MSG.INFORMATION(), MSG.ACCOUNT_DELETE_INFO_EMAIL_SENT( self.enki_user.email)) else: # otherwise just delete the account self.delete_account(delete_posts) if delete_posts: self.add_infomessage('success', MSG.SUCCESS(), MSG.ACCOUNT_AND_POSTS_DELETED()) else: self.add_infomessage('success', MSG.SUCCESS(), MSG.ACCOUNT_DELETED()) self.redirect(enki.libutil.get_local_url())
def get(self, verifytoken): tokenEntity = EnkiModelTokenVerify.get_by_token_type( xstr(verifytoken), 'emailsubscriptionconfirm') if tokenEntity: newsletter = tokenEntity.state unsubscribe_token = EnkiModelEmailSubscriptions.add_newsletter( tokenEntity.email, newsletter) self.add_infomessage(MSG.SUCCESS(), MSG.EMAIL_SUBSCRIBED(newsletter)) # send welcome email with unsubscribe link link = enki.libutil.get_local_url('emailunsubscribe', { 'unsubscribetoken': unsubscribe_token, 'newsletter': newsletter }) self.send_email( tokenEntity.email, MSG.SEND_EMAIL_EMAIL_NEWSLETTER_WELCOME_SUBJECT(newsletter), MSG.SEND_EMAIL_EMAIL_NEWSLETTER_WELCOME_BODY(newsletter, link)) self.add_infomessage( MSG.INFORMATION(), MSG.EMAIL_NEWSLETTER_WELCOME_EMAIL_SENT(newsletter)) self.redirect(enki.libutil.get_local_url('home')) tokenEntity.key.delete() else: self.add_infomessage(MSG.INFORMATION(), MSG.EMAIL_SUBSCRIPTION_FAILED()) self.redirect(enki.libutil.get_local_url('emailsubscriptions'))
def process_token_result(self, result): # select the processing function jdoc = self.process_result_as_JSON(result) if 'error' in jdoc or 'id_token' not in jdoc: # failed self.add_infomessage('info', MSG.INFORMATION(), MSG.REGISTRATION_ABORT()) self.redirect_to_relevant_page() return id_token = jdoc['id_token'] if type(id_token) == bytes: segments = id_token.split(b'.') else: segments = id_token.split(u'.') jwtencoded = segments[1] if isinstance(jwtencoded, unicode): jwtencoded = jwtencoded.encode('ascii') jwtencoded = jwtencoded + b'=' * (4 - len(jwtencoded) % 4) jwt = json.loads(base64.urlsafe_b64decode(jwtencoded).decode('utf-8')) if not self.validate_token_doc(jwt): self.add_infomessage('info', MSG.INFORMATION(), MSG.REGISTRATION_ABORT()) self.redirect_to_relevant_page() return loginInfoSettings = { 'provider_uid': 'sub', 'email': 'email', 'email_verified': 'email_verified' } loginInfo = self.process_login_info(loginInfoSettings, jwt) self.provider_authenticated_callback(loginInfo)
def post(self): self.cleanup_item() self.log_out() self.check_CSRF() token = self.session.get('tokenregisterauth') tokenEntity = EnkiModelTokenVerify.get_by_token_type(token, 'register') if tokenEntity: submit_type = self.request.get('submittype') # Log in with email and password if submit_type == 'login': email = tokenEntity.email tokenEntity.key.delete() password = self.request.get('password') if self.log_in_with_email(email, password): self.add_infomessage('success', MSG.SUCCESS(), MSG.LOGGED_IN()) self.redirect_to_relevant_page() else: error_message = MSG.WRONG_EMAIL_OR_PW() backoff_timer = self.get_backoff_timer(email) if backoff_timer != 0: error_message = MSG.TIMEOUT( enki.libutil.format_timedelta(backoff_timer)) self.render_tmpl('login.html', active_menu='login', authhandlers=settings.HANDLERS, email=email, error=error_message) elif submit_type == 'recoverpass': email = tokenEntity.email tokenEntity.key.delete() self.redirect( enki.libutil.get_local_url('passwordrecover', {'email': email})) # Create a new account using the OAuth provider but without the email elif submit_type == 'register': email = tokenEntity.email tokenEntity.email = '' tokenEntity.put() self.add_infomessage( 'info', MSG.INFORMATION(), MSG.REGISTRATION_INFO_EMAIL_CANNOT_USE(email)) self.redirect( enki.libutil.get_local_url('registeroauthconfirm')) else: tokenEntity.key.delete() self.add_infomessage('info', MSG.INFORMATION(), MSG.LOGIN_FAILED()) self.redirect(enki.libutil.get_local_url('home')) else: self.abort(404)
def post(self): self.check_CSRF() submit_type = self.request.get('submittype') email = self.request.get('email') if submit_type == 'recoverpass': result = enki.libuser.validate_email(email) error_message = '' if result == enki.libutil.ENKILIB_OK: result = self.password_change_request(email) if result == enki.libutil.ENKILIB_OK or result == enki.handlerbase.ERROR_EMAIL_NOT_EXIST: # The info displayed is identical whether the email corresponds to an existing account or not to prevent email checking. self.add_infomessage( 'info', MSG.INFORMATION(), MSG.PASSWORD_RESET_INFO_EMAIL_SENT(email)) if result == enki.handlerbase.ERROR_EMAIL_NOT_EXIST: self.add_debugmessage( 'Comment - whether the email is available or not, the feedback through the UI is identical to prevent email checking.' ) self.redirect_to_relevant_page() return elif result == enki.libuser.ERROR_EMAIL_FORMAT_INVALID: error_message = MSG.WRONG_EMAIL_FORMAT() elif result == enki.libuser.ERROR_EMAIL_MISSING: error_message = MSG.MISSING_EMAIL() self.render_tmpl('passwordrecover.html', email=email, error=error_message) elif submit_type == 'login': self.redirect(enki.libutil.get_local_url('login', {'email': email})) else: self.redirect( enki.libutil.get_local_url('register', {'email': email}))
def process_token_result(self, result): # select the processing function data = self.process_result_as_query_string(result) if not data: # failed self.add_infomessage('info', MSG.INFORMATION(), MSG.REGISTRATION_ABORT()) self.redirect_to_relevant_page() return token = data['access_token'] profile = self.get_profile(token) jdoc = self.process_result_as_JSON(profile) emailUrl = 'https://api.github.com/user/emails?' + urllib.urlencode( {'access_token': token}) emailDoc = self.urlfetch_safe(url=emailUrl) jemails = self.process_result_as_JSON(emailDoc) for item in jemails: if item.get('verified', False): jdoc.update(item) if item.get('primary', False): break # if we have a verified primary we stop and use that if jemails and not jdoc.get('email', None): jdoc.update(jemails[0]) jdoc['id'] = str(jdoc['id']) # convert id to string loginInfoSettings = { 'provider_uid': 'id', 'email': 'email', 'email_verified': 'verified' } loginInfo = self.process_login_info(loginInfoSettings, jdoc) self.provider_authenticated_callback(loginInfo)
def ensure_is_reauthenticated(self): if not self.is_reauthenticated(): self.save_user_page_data() self.add_infomessage('info', MSG.INFORMATION(), MSG.REAUTHENTICATION_NEEDED()) self.redirect(enki.libutil.get_local_url('reauthenticate')) return False return True
def get(self): email = self.request.get('email') # Get referal path to return the user to the page they were on after they've logged in if 'sessionloginrefpath' in self.session: self.add_infomessage('info', MSG.INFORMATION(), MSG.LOGIN_NEEDED()) self.session['sessionrefpath'] = self.session.pop( 'sessionloginrefpath', self.request.referrer) self.render_tmpl('login.html', active_menu='login', authhandlers=settings.HANDLERS, email=email)
def urlfetch_safe(self, *args, **kwargs): haveError = False try: result = urlfetch.fetch(*args, **kwargs) if result.status_code != 200: haveError = True except: haveError = True if haveError: self.add_infomessage(MSG.INFORMATION(), MSG.REGISTRATION_ABORT()) self.redirect_to_relevant_page(True) return result
def ensure_has_display_name(self, url=None): # user must set their display_name to continue user_display_name = EnkiModelDisplayName.get_by_user_id_current( self.user_id) if not user_display_name: if not url: url = self.request.url # get referal path to return the user to it after they've set their display name self.session['sessiondisplaynamerefpath'] = url self.add_infomessage(MSG.INFORMATION(), MSG.DISPLAYNAME_NEEDED()) self.redirect(enki.libutil.get_local_url('displayname')) return False return True
def add_infomessage(self, message_header, message_body): # reference: http://bootswatch.com/flatly/#indicators # message_type values: 'success', 'info', 'warning', 'danger' if message_header == MSG.SUCCESS(): message_type = 'success' elif message_header == MSG.INFORMATION(): message_type = 'info' elif message_header == MSG.WARNING(): message_type = 'warning' else: message_header = MSG.DANGER() message_type = 'danger' self.session['infomessage'] = self.session.pop( 'infomessage', []) + [[message_type, message_header, message_body]]
def get(self, useridnumber): if self.ensure_is_logged_in(): display_name_data = None if useridnumber.isdigit and enki.libuser.EnkiModelUser.get_by_id( int(useridnumber)): display_name_data = enki.libdisplayname.get_display_name_data( int(useridnumber)) else: self.add_infomessage('info', MSG.INFORMATION(), MSG.USER_NOT_EXIST()) self.render_tmpl('profilepublic.html', False, active_menu='home', display_name_data=display_name_data)
def post_reauthenticated(self, params): email = params.get('email') old_email_existed = True if ( self.enki_user.email and self.enki_user.email != 'removed') else False result = enki.libuser.validate_email(email) error_message = '' if result == enki.libutil.ENKILIB_OK or result == enki.libuser.ERROR_EMAIL_MISSING: result_of_change_request = self.email_change_request(email) if result_of_change_request == 'same': error_message = MSG.CURRENT_EMAIL() elif result_of_change_request == 'cannot_remove': error_message = MSG.CANNOT_DELETE_EMAIL() elif result_of_change_request == 'removed': self.add_infomessage('success', MSG.SUCCESS(), MSG.EMAIL_REMOVED()) if old_email_existed: self.add_infomessage('info', MSG.INFORMATION(), MSG.EMAIL_ROLLBACK_INFO_EMAIL_SENT()) self.redirect(enki.libutil.get_local_url('profile')) elif result_of_change_request == 'change' or result_of_change_request == enki.handlerbase.ERROR_EMAIL_IN_USE: self.add_infomessage( 'info', MSG.INFORMATION(), MSG.EMAIL_CHANGE_CONFIRM_INFO_EMAIL_SENT(email)) if self.enki_user.email and self.enki_user.email != 'removed': self.add_infomessage( 'info', MSG.INFORMATION(), MSG.EMAIL_CHANGE_UNDO_INFO_EMAIL_SENT()) self.redirect(enki.libutil.get_local_url('profile')) return elif result == enki.libuser.ERROR_EMAIL_FORMAT_INVALID: error_message = MSG.WRONG_EMAIL_FORMAT() if error_message: self.render_tmpl('emailchange.html', active_menu='profile', email=email, error=error_message)
def ensure_is_reauthenticated(self): if not self.is_reauthenticated(): self.save_user_page_data() self.add_infomessage(MSG.INFORMATION(), MSG.REAUTHENTICATION_NEEDED()) # rather than redirect to 'reauthenticate' we render here to prevent sessionrefpath being overwritten self.session['sessionrefpath'] = self.request.path_url self.render_tmpl( 'reauthenticate.html', active_menu='profile', authhandlers=self.get_user_auth_providers(), email=self.enki_user.email if (self.enki_user.email and self.enki_user.password) else None) return False return True
def post(self): if self.ensure_is_logged_in(): self.check_CSRF() submit_type = self.request.get('submittype') if submit_type == 'reset': self.redirect(enki.libutil.get_local_url('emailbatchsending')) elif submit_type == 'send' or submit_type == 'sendtest': ready_to_send = 'off' newsletter = self.request.get('newsletter') subject = self.request.get('subject') body_text = self.request.get('body_text') footer_template = self.get_mailgun_email_footer_template( newsletter) if submit_type == 'sendtest': self.send_email(self.enki_user.email, subject, body_text + footer_template) self.add_infomessage( MSG.INFORMATION(), 'Test email sent to ' + self.enki_user.email) elif submit_type == 'send': ready_to_send = self.request.get('readytosend') if ready_to_send == 'on': batches_emails, batches_emails_recipient_variables = EnkiModelEmailSubscriptions.get_mailgun_email_batches( newsletter) send_success = False for batch_emails, batch_emails_recipient_variables in zip( batches_emails, batches_emails_recipient_variables): send_success = self.send_mailgun_batch_email( batch_emails, subject, body_text, footer_template, batch_emails_recipient_variables) if send_success: self.add_infomessage(MSG.SUCCESS(), 'Batch email sent') self.redirect( enki.libutil.get_local_url( 'emailbatchsending')) return else: self.add_infomessage(MSG.WARNING(), 'Batch email sending failed') self.render_tmpl('emailbatchsending.html', newsletter=newsletter, subject=subject, body_text=body_text, footer=footer_template, ready_to_send=ready_to_send)
def post(self): self.check_CSRF() product = xstr(self.request.get('product')) quantity = xint(self.request.get('quantity')) order_type = xstr(self.request.get('order_type')) purchaser_email = xstr(self.request.get('purchaser_email')) purchaser_email = purchaser_email if purchaser_email else None purchaser_user_id = xint(self.request.get('purchaser_user_id')) purchaser_user_id = purchaser_user_id if purchaser_user_id != 0 else None info = xstr(self.request.get('info')) info = info if info else None order_id = webapp2_extras.security.generate_random_string( length=10, pool=webapp2_extras.security.DIGITS) licence_keys = EnkiModelProductKey.generate_licence_keys(quantity) licence_keys = licence_keys.replace('-', '').split() for licence_key in licence_keys: item = EnkiModelProductKey(licence_key=licence_key, order_id=order_id, product_name=product, shop_name='Generator', quantity=quantity, order_type=order_type, purchaser_email=purchaser_email, purchaser_user_id=purchaser_user_id, info=info) item.put() licence_key_display = [] for item in licence_keys: item_dash = EnkiModelProductKey.insert_dashes_5_10(item) licence_key_display.append(item_dash) self.add_infomessage( MSG.INFORMATION(), '<h3>Licence keys generated</h3>' + '<ul>' + '<li>product_name = <em>' + product + '</em></li>' + '<li>order_type = <em>' + order_type + '</em></li>' + '<li>order_id = <em>' + order_id + '</em></li>' + '<li>quantity = <em>' + xstr(quantity) + '</em></li>' + '<li>Recipient mail (purchaser_email) = <em>' + (purchaser_email if purchaser_email else 'none') + '</em></li>' + '<li>Recipient user id (purchaser_user_id) = <em>' + (xstr(purchaser_user_id) if purchaser_user_id else 'none') + '</em></li>' + '<li>info = <em>' + (info if info else 'none') + '</em></li>' + '<li>licence_key(s) = <br><em>' + '<br>'.join(licence_key_display) + '</em></li>' + '</ul>') self.redirect('licencesgeneratefree')
def process_token_result(self, result): # select the processing function data = self.process_result_as_query_string(result) if not data: # failed self.add_infomessage('info', MSG.INFORMATION(), MSG.REGISTRATION_ABORT()) self.redirect_to_relevant_page() return token = data['access_token'] profile = self.get_profile(token) jdoc = self.process_result_as_JSON(profile) loginInfoSettings = { 'provider_uid': 'id', 'email': 'email', 'email_verified': 'verified' } loginInfo = self.process_login_info(loginInfoSettings, jdoc) self.provider_authenticated_callback(loginInfo)
def process_token_result(self, result): # select the processing function data = self.process_result_as_JSON(result) if not data: # failed self.add_infomessage(MSG.INFORMATION(), MSG.REGISTRATION_ABORT()) self.redirect_to_relevant_page() return token = data['access_token'] profile = self.get_profile(token, {'fields': 'id,email'}) jdoc = self.process_result_as_JSON(profile) jdoc[ 'email_verified'] = True # Facebook emails only given if verified. loginInfoSettings = { 'provider_uid': 'id', 'email': 'email', 'email_verified': 'email_verified' } loginInfo = self.process_login_info(loginInfoSettings, jdoc) self.provider_authenticated_callback(loginInfo)
def post(self): self.check_CSRF() submit_type = self.request.get('submittype') email = self.request.get('email') if submit_type == 'register': result = self.email_set_request(email) error_message = '' if result == enki.libutil.ENKILIB_OK or result == enki.handlerbase.ERROR_EMAIL_IN_USE: # if email exists, pretend there was a registration (i.e. hide the fact that the email exists) to prevent email checking self.add_infomessage('info', MSG.INFORMATION(), MSG.REGISTRATION_INFO_EMAIL_SENT(email)) if result == enki.handlerbase.ERROR_EMAIL_IN_USE: self.add_debugmessage( 'Comment - whether the email is available or not, the feedback through the UI is identical to prevent email checking.' ) link = enki.libutil.get_local_url('passwordrecover', {'email': email}) self.send_email( email, MSG. SEND_EMAIL_REGISTER_ATTEMPT_WITH_YOUR_EMAIL_SUBJECT(), MSG.SEND_EMAIL_REGISTER_ATTEMPT_WITH_YOUR_EMAIL_BODY( link, email)) self.redirect_to_relevant_page() return else: if result == enki.libuser.ERROR_EMAIL_FORMAT_INVALID: error_message = MSG.WRONG_EMAIL_FORMAT() elif result == enki.libuser.ERROR_EMAIL_MISSING: error_message = MSG.MISSING_EMAIL() self.render_tmpl('register.html', active_menu='register', authhandlers=settings.HANDLERS, email=email, error=error_message) elif submit_type == 'login': self.redirect(enki.libutil.get_local_url('login', {'email': email})) else: self.redirect( enki.libutil.get_local_url('passwordrecover', {'email': email}))
def post(self): choice = self.request.get('choice') # Step 1 if choice == 'create' or choice == 'cancel': token = self.session.get('tokenregisterauth') tokenEntity = EnkiModelTokenVerify.get_by_token_type( token, 'register') authId = tokenEntity.auth_ids_provider provider_name, provider_uid = authId.partition(':')[::2] auth_email = tokenEntity.email if tokenEntity.email else None if choice == 'create': if auth_email: # If the email is given by the provider, it is verified. Get or ceate the account and log the user in. user = self.get_or_create_user_from_authid( authId, auth_email) if user: # login the user through auth self.log_in_session_token_create(user) self.add_infomessage('success', MSG.SUCCESS(), MSG.LOGGED_IN()) else: # user creation failed (timeout etc.) self.add_infomessage( 'warning', MSG.WARNING(), MSG.AUTH_LOGIN_FAILED(provider_name)) self.redirect_to_relevant_page() tokenEntity.key.delete() self.session.pop('tokenregisterauth') else: # If the email isn't given by the provider, use the manually entered email. self.check_CSRF() email = self.request.get('email') user = self.get_or_create_user_from_authid(authId) self.log_in_session_token_create(user) error_message = '' success = False result = enki.libuser.validate_email(email) if result == enki.libutil.ENKILIB_OK: result = self.email_change_request( email ) # send an email for verification. Since it's not verified at this point, create the account without the email. self.add_infomessage( 'info', MSG.INFORMATION(), MSG.REGISTER_AUTH_ADD_EMAIL_INFO_EMAIL_SENT(email)) if result == enki.handlerbase.ERROR_EMAIL_IN_USE: self.add_debugmessage( 'Comment - whether the email is available or not, the feedback through the UI is identical to prevent email checking.' ) success = True tokenEntity.key.delete() self.session.pop('tokenregisterauth') elif result == enki.libuser.ERROR_EMAIL_FORMAT_INVALID: error_message = MSG.WRONG_EMAIL_FORMAT() elif result == enki.libuser.ERROR_EMAIL_MISSING: error_message = MSG.MISSING_EMAIL() self.render_tmpl('registeroauthconfirm.html', active_menu='register', token=tokenEntity, provider_name=provider_name, provider_uid=str(provider_uid), error=error_message, success=success) elif choice == 'cancel': self.add_infomessage('info', MSG.INFORMATION(), MSG.REGISTRATION_ABORT()) self.redirect_to_relevant_page() tokenEntity.key.delete() self.session.pop('tokenregisterauth') # Step 2 (those choices will only be presented to the user if they successfully added an email manually). elif choice == 'continue': self.redirect_to_relevant_page() elif choice == 'profile': url = enki.libutil.get_local_url('profile') self.session['sessionrefpath'] = url self.redirect(url)
def post(self): if self.ensure_is_logged_in(): self.check_CSRF() user_id = self.enki_user.key.id() if self.get_backoff_timer(str(user_id), True) == 0: licence_key_preset = self.request.get( 'licence_key_preset').strip()[:( enki.libstore.LICENCE_KEY_DASHES_LENGTH + 4 )] # 4 allows for some leading and trailing characters licence_key_manual = self.request.get( 'licence_key_manual').strip()[:( enki.libstore.LICENCE_KEY_DASHES_LENGTH + 4)] licence_key = licence_key_manual is_manual = True if licence_key_preset and not licence_key_manual: licence_key = licence_key_preset is_manual = False if licence_key: if len(licence_key) <= ( enki.libstore.LICENCE_KEY_DASHES_LENGTH): licence_key_reduced = re.sub( r'[^\w]', '', licence_key)[:enki.libstore.LICENCE_KEY_LENGTH] item = enki.libstore.get_EnkiProductKey_by_licence_key( licence_key_reduced) if not item: if is_manual: self.session[ 'error_library'] = MSG.LICENCE_INVALID() self.session[ 'error_library_licence'] = licence_key elif item: licence_key_formatted = enki.libstore.insert_dashes_5_10( licence_key_reduced) if not item.activated_by_user: # the licence key is not activated. if enki.libstore.exist_EnkiProductKey_product_activated_by( user_id, item.product_name): # the user has already activated a key for the same product if is_manual: self.session[ 'error_library'] = MSG.LICENCE_ALREADY_ACTIVATED_GIVE( settings.product_displayname[ item.product_name]) self.session[ 'error_library_licence'] = licence_key_formatted else: # activate the licence item.activated_by_user = user_id item.put() self.remove_backoff_timer(str(user_id)) self.add_infomessage( 'success', MSG.SUCCESS(), MSG.PRODUCT_LICENCE_ACTIVATED( settings.product_displayname[ item.product_name], licence_key_formatted)) elif item.activated_by_user == user_id: # the user has already activated this specific key if is_manual: self.session[ 'error_library'] = MSG.PRODUCT_ALREADY_ACTIVATED( settings.product_displayname[ item.product_name]) self.session[ 'error_library_licence'] = licence_key_formatted else: self.add_infomessage( 'info', MSG.INFORMATION(), MSG.PRODUCT_ALREADY_ACTIVATED( settings.product_displayname[ item.product_name])) else: # another user has activated the key if is_manual: self.session[ 'error_library'] = MSG.LICENCE_ANOTHER_USER_ACTIVATED( settings.product_displayname[ item.product_name], licence_key_formatted) self.session[ 'error_library_licence'] = licence_key_formatted else: self.add_infomessage( 'info', MSG.INFORMATION(), MSG.LICENCE_ANOTHER_USER_ACTIVATED( settings.product_displayname[ item.product_name], licence_key_formatted)) else: self.session['error_library'] = MSG.LICENCE_TOO_LONG() self.session['error_library_licence'] = licence_key elif is_manual: self.session['error_library'] = MSG.LICENCE_MISSING() else: backoff_timer = self.get_backoff_timer(str(user_id)) if backoff_timer != 0: self.session['error_library'] = MSG.TIMEOUT( enki.libutil.format_timedelta(backoff_timer)) self.redirect_to_relevant_page()
def post(self): if not settings.SECRET_FASTSPRING or enki.libutil.is_debug( ) or settings.ENKI_EMULATE_STORE: self.check_CSRF() product = xstr(self.request.get('product')) quantity = xint(self.request.get('quantity')) purchase_price = xstr(self.request.get('purchase_price')) purchaser_email = xstr(self.request.get('purchaser_email')) licence_keys = 'not generated' user_id = '' emulator_order_id = 'EMULATED_' + webapp2_extras.security.generate_random_string( length=10, pool=webapp2_extras.security.DIGITS) url = enki.libutil.get_local_url('genlicencefastspring') form_fields = { 'secret': 'pretendsecret', 'quantity': str(quantity) } form_data = urllib.urlencode(form_fields) result = urlfetch.fetch(url=url, payload=form_data, method=urlfetch.POST) if result.status_code == 200: licence_keys = result.content.replace('-', '') referrer = xstr(self.request.get('referrer')) token = EnkiModelTokenVerify.get_by_token_type( referrer, 'purchasebyuser') if token: user_id = token.user_id licence_key_display = [] for item in licence_keys.split(): item_dash = enki.libstore.insert_dashes_5_10(item) licence_key_display.append(item_dash) self.add_infomessage( 'info', MSG.INFORMATION(), '<h3>FastSpring Store Emulator - Step 1</h3>' + '<h4>Emulated purchase details</h4>' + '<ul>' + '<li><EnkiModelProductKey> #{FastSpring variable} = <em><emulated value></em></li>' + '<li>product_name #{orderItem.productName} = <em>' + product + '</em></li>' + '<li>order_id #{order.id} = <em>' + emulator_order_id + '</em></li>' + '<li>quantity #{orderItem.quantity} = <em>' + xstr(quantity) + '</em></li>' + '<li>purchase_price #{orderItem.totalUSD} = <em>' + purchase_price + '</em></li>' + '<li>purchaser_email #{order.customer.email} = <em>' + purchaser_email + '</em></li>' + '<li>shop_name = <em>Emulator_FastSpring</em></li>' + '<li>licence_key #{orderItem.fulfillment.licence.licences.list} = <br><em><b>' + '<br>'.join(licence_key_display) + '</b></em></li>' + '</ul>' '<h4>Internal data - generated if the purchaser was logged in when they bought the product</h4>' + '<ul>' + '<li>EnkiModelTokenVerify.user_id = purchaser user_id = <em>' + (xstr(user_id) if user_id else 'None') + '</em></li>' + '<li>EnkiModelTokenVerify.type purchasebyuser referrer #{order.referrer} = <em>' + (xstr(referrer) if referrer else 'None') + '</em></li>' + '</ul>') url = enki.libutil.get_local_url('ordercompletefastspring') form_fields = { 'licence_key': licence_keys, 'purchase_price': purchase_price, 'order_id': emulator_order_id, 'product_name': product, 'purchaser_email': purchaser_email, 'shop_name': 'Emulator_FastSpring', 'quantity': quantity, 'referrer': referrer, 'is_test': True } form_data = urllib.urlencode(form_fields) result = urlfetch.fetch(url=url, payload=form_data, method=urlfetch.POST) if result.status_code == 200: message_view_library = '' if self.is_logged_in(): message_view_library = '<p><a href="/profile" class="alert-link">View and activate licence keys</a>.</p>' self.add_infomessage( 'info', MSG.INFORMATION(), '<h3>FastSpring Store Emulator - Step 2</h3><p>Purchase records created<p>' + message_view_library) else: self.add_infomessage( 'warning', MSG.WARNING(), '<h3>FastSpring Store Emulator - Step 2 FAILED: Purchase records not created</h3>' ) self.redirect_to_relevant_page()
def provider_authenticated_callback(self, loginInfo): # We expect the fields of the dictionary to be: # - 'provider_name' unique 'pretty' provider name (e.g. google, facebook,...) # - 'provider_uid' provider specific (a.k.a "locally unique") user Id, i.e unique to the provider (e.g. the google user id number) # - 'email' # - 'email_verified' # We IGNORE: username, gender (facebook), avatar link, etc. # get the verified email from the auth provider email = None if loginInfo['email'] and loginInfo['email_verified'] == True: email = loginInfo['email'] # get the authId from the auth provider auth_id = loginInfo['provider_name'] + ':' + loginInfo['provider_uid'] if auth_id: # Modify existing or create user # check if it's an add login method request LoginAddToken = EnkiModelTokenVerify.get_by_user_id_state_type( self.user_id, loginInfo['provider_name'], 'loginaddconfirm_1') if LoginAddToken: # Add a login method if not EnkiModelUser.exist_by_auth_id(auth_id): # store the new auth prov + id in the session LoginAddToken.state = auth_id LoginAddToken.type = 'loginaddconfirm_2' LoginAddToken.put() self.redirect( enki.libutil.get_local_url('loginaddconfirm')) else: self.add_infomessage( MSG.INFORMATION(), MSG.AUTH_PROVIDER_CANNOT_BE_ADDED(str(auth_id))) self.redirect(enki.libutil.get_local_url('accountconnect')) return else: user = self.get_user_from_authid(auth_id, email) if user: # Existing authentication method / user if self.is_logged_in() and self.user_id == user.key.id(): # Refresh the reauthenticated status self.session['reauth_time'] = datetime.datetime.now() self.add_infomessage(MSG.SUCCESS(), MSG.REAUTHENTICATED()) self.redirect_to_relevant_page() return # Login self.log_in_session_token_create(user) self.add_infomessage(MSG.SUCCESS(), MSG.LOGGED_IN()) self.redirect_to_relevant_page() else: # New authentication method register_token = EnkiModelTokenVerify.get_by_state_type( auth_id, 'register') if register_token: # If a token already exists, get the token value and update the email token = register_token.token register_token.email = email # update in case the user changed their email or modified their email access permission else: # Create a new token token = security.generate_random_string(entropy=256) register_token = EnkiModelTokenVerify(token=token, email=email, state=auth_id, type='register') register_token.put() self.session['tokenregisterauth'] = token if EnkiModelUser.exist_by_email(email): self.redirect( enki.libutil.get_local_url( 'registeroauthwithexistingemail')) else: self.redirect( enki.libutil.get_local_url('registeroauthconfirm')) else: self.redirect_to_relevant_page()
def post_reauthenticated(self, params): licence_key_preset = params.get('licence_key_preset') licence_key_manual = params.get('licence_key_manual') user_id = self.enki_user.key.id() if EnkiModelBackoffTimer.get(str(user_id), True) == 0: licence_key_preset = licence_key_preset.strip()[:( EnkiModelProductKey.LICENCE_KEY_DASHES_LENGTH + 4 )] if licence_key_preset else '' # 4 allows for some leading and trailing characters licence_key_manual = licence_key_manual.strip()[:( EnkiModelProductKey.LICENCE_KEY_DASHES_LENGTH + 4)] if licence_key_manual else '' licence_key = licence_key_manual is_manual = True if licence_key_preset and not licence_key_manual: licence_key = licence_key_preset is_manual = False if licence_key: if len(licence_key) < EnkiModelProductKey.LICENCE_KEY_LENGTH: self.session['error_library'] = MSG.LICENCE_TOO_SHORT() self.session['error_library_licence'] = licence_key elif len(licence_key) <= ( EnkiModelProductKey.LICENCE_KEY_DASHES_LENGTH): licence_key_reduced = re.sub( r'[^\w]', '', licence_key)[:EnkiModelProductKey.LICENCE_KEY_LENGTH] item = EnkiModelProductKey.get_by_licence_key( licence_key_reduced) if not item: if is_manual: self.session[ 'error_library'] = MSG.LICENCE_INVALID() self.session['error_library_licence'] = licence_key elif item: licence_key_formatted = EnkiModelProductKey.insert_dashes_5_10( licence_key_reduced) if item.activated_by_user == -1: # the licence key is not activated. if EnkiModelProductKey.exist_product_by_activator( user_id, item.product_name): # the user has already activated a key for the same product if is_manual: self.session[ 'error_library'] = MSG.LICENCE_ALREADY_ACTIVATED_GIVE( settings.product_displayname[ item.product_name]) self.session[ 'error_library_licence'] = licence_key_formatted else: # activate the licence item.activated_by_user = user_id item.put() EnkiModelBackoffTimer.remove(str(user_id)) self.add_infomessage( MSG.SUCCESS(), MSG.PRODUCT_LICENCE_ACTIVATED( settings.product_displayname[ item.product_name], licence_key_formatted)) elif item.activated_by_user == user_id: # the user has already activated this specific key if is_manual: self.session[ 'error_library'] = MSG.PRODUCT_ALREADY_ACTIVATED( settings.product_displayname[ item.product_name]) self.session[ 'error_library_licence'] = licence_key_formatted else: self.add_infomessage( MSG.INFORMATION(), MSG.PRODUCT_ALREADY_ACTIVATED( settings.product_displayname[ item.product_name])) else: # another user has activated the key if is_manual: self.session[ 'error_library'] = MSG.LICENCE_ANOTHER_USER_ACTIVATED( settings.product_displayname[ item.product_name], licence_key_formatted) self.session[ 'error_library_licence'] = licence_key_formatted else: self.add_infomessage( MSG.INFORMATION(), MSG.LICENCE_ANOTHER_USER_ACTIVATED( settings.product_displayname[ item.product_name], licence_key_formatted)) else: self.session['error_library'] = MSG.LICENCE_TOO_LONG() self.session['error_library_licence'] = licence_key elif is_manual: self.session['error_library'] = MSG.LICENCE_MISSING() else: backoff_timer = EnkiModelBackoffTimer.get(str(user_id)) if backoff_timer != 0: self.session['error_library'] = MSG.TIMEOUT( enki.libutil.format_timedelta(backoff_timer)) self.render_tmpl('library.html', active_menu='profile', data=self.get_data())
def get(self): # Galleries of images and videos media_html = '' if enki.libutil.is_debug(): with open('test\media.json', 'r') as f: json_file = f.read() f.close() media_json = json.loads(json_file) media_html = self.create_media_page(media_json) else: cache_data = memcache.get('media_html') if cache_data is not None: media_html = cache_data else: try: f = gcs.open(settings.bucket + 'media.json') json_file = f.read() f.close() media_json = json.loads(json_file) media_html = self.create_media_page(media_json) memcache.add('media_html', media_html, 300) except: pass # Display enlarged image url_image_previous = '' url_image_next = '' url_image_displayed = '' src_image_displayed = '' alt_image_displayed = '' caption_image_displayed = '' # if src_image_displayed is found, display the image. Otherwise abort. while not src_image_displayed: gallery = abs(int(self.request.get('g'))) if self.request.get( 'g').isdigit() else -1 image = abs(int(self.request.get('i'))) if self.request.get( 'i').isdigit() else -1 if gallery == -1 or image == -1: break media_json = '' if enki.libutil.is_debug(): with open('test\media.json', 'r') as f: json_file = f.read() f.close() media_json = json.loads(json_file) else: try: f = gcs.open(settings.bucket + 'media.json') json_file = f.read() f.close() media_json = json.loads(json_file) except: break if media_json and 'galleries_of_images' in media_json['media']: galleries_of_images = media_json['media'][ 'galleries_of_images'] if gallery >= len(galleries_of_images): break else: gallery_of_images = galleries_of_images[gallery]['images'] images_count = len(gallery_of_images) if image >= images_count or 'img_src' not in gallery_of_images[ image] or not gallery_of_images[image]['img_src']: break else: if image == 0: previous_image = images_count - 1 else: previous_image = image - 1 if image < images_count - 1: next_image = image + 1 else: next_image = 0 url_image_previous = enki.libutil.get_local_url( 'media', { 'g': str(gallery), 'i': str(previous_image) }) url_image_next = enki.libutil.get_local_url( 'media', { 'g': str(gallery), 'i': str(next_image) }) url_image_displayed = gallery_of_images[image][ 'a_href'] src_image_displayed = gallery_of_images[image][ 'a_href'] # use the higher resolution image alt_image_displayed = gallery_of_images[image][ 'img_alt'] caption_image_displayed = gallery_of_images[image][ 'caption'] break else: break # info on attempt to display an unavailable image if self.request.get('g') and self.request.get( 'i') and not src_image_displayed: self.add_infomessage(MSG.INFORMATION(), MSG.IMAGE_UNAVAILABLE()) self.render_tmpl('media.html', False, active_menu='media', url_image_previous=url_image_previous, url_image_next=url_image_next, url_image_displayed=url_image_displayed, src_image_displayed=src_image_displayed, alt_image_displayed=alt_image_displayed, caption_image_displayed=caption_image_displayed, media_html=media_html)
def post(self): self.check_CSRF() submit_type = self.request.get('submittype') data = self.get_email_subscriptions_data() email = '' error_message = '' if data[0]: # is_logged_in if submit_type == 'subscribe': # delete eventual verification tokens for this email and newsletter tokenEntity = EnkiModelTokenVerify.get_by_email_state_type( self.enki_user.email, settings.email_newsletter_name[0], 'emailsubscriptionconfirm') if tokenEntity: tokenEntity.key.delete() EnkiModelEmailSubscriptions.add_newsletter( self.enki_user.email, settings.email_newsletter_name[0]) self.add_infomessage( MSG.SUCCESS(), MSG.EMAIL_SUBSCRIBED(settings.email_newsletter_name[0])) data[1] = True # has_email_subscriptions elif submit_type == 'unsubscribe': EnkiModelEmailSubscriptions.remove_newsletter_by_email( self.enki_user.email, settings.email_newsletter_name[0]) self.add_infomessage( MSG.SUCCESS(), MSG.EMAIL_UNSUBSCRIBED(settings.email_newsletter_name[0])) data[ 1] = False # has_email_subscriptions - ASSUMPTION: ONLY ONE NEWSLETTER AVAILABLE if submit_type == 'subscribeemail': email_unsafe = self.request.get('email') email, result = self.validate_email(email_unsafe) if result == self.ERROR_EMAIL_FORMAT_INVALID: error_message = MSG.WRONG_EMAIL_FORMAT() elif result == self.ERROR_EMAIL_MISSING: error_message = MSG.MISSING_EMAIL() elif result == enki.libutil.ENKILIB_OK: if EnkiModelBackoffTimer.get(self.request.remote_addr, increment=True, expires=True) == 0: if not EnkiModelEmailSubscriptions.exist_by_email_newsletter( email, settings.email_newsletter_name[0]): # if not already subscribed, create a token and send email with a link to allow the user to confirm their subscription if not EnkiModelTokenVerify.get_by_email_state_type( email, settings.email_newsletter_name[0], 'emailsubscriptionconfirm'): # if a verify token already exists, skip as an email was already sent. token = security.generate_random_string( entropy=256) emailToken = EnkiModelTokenVerify( token=token, email=email, state=settings.email_newsletter_name[0], type='emailsubscriptionconfirm') emailToken.put() link = enki.libutil.get_local_url( 'emailsubscriptionconfirm', {'verifytoken': token}) self.send_email( email, MSG.SEND_EMAIL_EMAIL_SUBSCRIBE_CONFIRM_SUBJECT( ), MSG.SEND_EMAIL_EMAIL_SUBSCRIBE_CONFIRM_BODY( link, settings.email_newsletter_name[0])) self.add_infomessage( MSG.INFORMATION(), MSG.EMAIL_SUBSCRIBE_CONFIRM_EMAIL_SENT( email, settings.email_newsletter_name[0])) self.add_debugmessage( 'Comment - whether the email is sent or not, the feedback through the UI is identical to prevent email checking.' ) email = '' else: backoff_timer = EnkiModelBackoffTimer.get( self.request.remote_addr, expires=True) if backoff_timer != 0: error_message = MSG.TIMEOUT( enki.libutil.format_timedelta(backoff_timer)) if data[0]: # is_logged_in self.redirect(enki.libutil.get_local_url('profile')) else: self.render_tmpl('emailsubscriptions.html', active_menu='profile', data=data, email=email, error=error_message)