def upload_welcome_pdf(dropbox_id): user = User.query.filter_by(dropbox_id=dropbox_id, active=True).first() if user is None: return False # If we've already sent the welcome PDF before, Dropbox webhook went # trigger, so do it here. if user.uploaded_welcome_pdf: return kindlebox(dropbox_id) analytics.track(str(user.id), 'Sent welcome pdf') client = DropboxClient(user.access_token) try: with open('app/static/bookdrop_welcome.pdf', 'rb') as f: response = client.put_file('Welcome to BookDrop.pdf', f, overwrite=True) if response: log.info(u"Welcome PDF sent to user ID {0}.".format(user.id)) else: raise Exception("No response received after sending welcome PDF") user.set_uploaded_welcome_pdf() db.session.commit() except: log.error((u"Welcome PDF failed for user ID " "{0}.").format(user.id), exc_info=True) return False return True
def deactivate(user): if user.active: user.kindle_names.delete() user.set_active(False) db.session.commit() analytics.track(str(user.id), 'Deactivated account') return jsonify({ 'success': True, })
def activate(): dropbox_id = session.get('dropbox_id') if dropbox_id is None: log.warn("Error activating, user with dropbox id {0} wasn't logged " "in".format(dropbox_id)) abort(400) user = User.query.filter_by(dropbox_id=dropbox_id).first() if user is None: log.warn("Error activating, user with dropbox id {0} doesn't " "exist".format(dropbox_id)) abort(400) if not user.active: if 'kindle_names' not in request.form: log.warn("Error activating, user with dropbox id {0} submitted " "no kindle names".format(dropbox_id)) abort(400) # Add all the Kindle usernames. form_kindle_names = request.form.get('kindle_names') try: kindle_names = json.loads(form_kindle_names) except json.JSONDecodeError: log.warn("Error activating, user with dropbox id {dropbox_id} " "submitted invalid kindle names " "{kindle_names}".format(dropbox_id=dropbox_id, kindle_names=form_kindle_names)) abort(400) if type(kindle_names) != list: log.warn("Error activating, user with dropbox id {dropbox_id} did " "not submit list of kindle names " "{kindle_names}".format(dropbox_id=dropbox_id, kindle_names=kindle_names)) abort(400) log.info("User with dropbox id {dropbox_id} submitting list of kindle " "names {kindle_names}".format(dropbox_id=dropbox_id, kindle_names=kindle_names)) for kindle_name in kindle_names: kindle_name = validate_kindle_name(kindle_name) if kindle_name is None: continue kindle_name_row = KindleName(user.id, kindle_name) db.session.add(kindle_name_row) db.session.flush() # TODO: Return an error to the client if user.kindle_names.first() is None: log.warn("Error activating, user with dropbox id {0} submitted " "invalid kindle names".format(dropbox_id)) abort(400) user.set_active(True) db.session.commit() try: upload_welcome_pdf.delay(user.dropbox_id) except: log.error("Unable to add upload welcome PDF task for dropbox id " "{0}".format(user.dropbox_id), exc_info=True) pass analytics.track(str(user.id), 'Activated account') return redirect(url_for('home'))
if dropbox_id is None: return redirect(url_for('home')) user = User.query.filter_by(dropbox_id=dropbox_id).first() new_user = user is None if user is None: user = User(dropbox_id) user.set_new_emailer() db.session.add(user) user.access_token = access_token (user.name, user.email) = get_dropbox_name_email(access_token) db.session.commit() if new_user: analytics.track(str(user.id), 'Registered') analytics.track(str(user.id), 'Logged in') session['dropbox_id'] = user.dropbox_id return redirect(url_for('home')) @app.route('/dropbox-unlink') def dropbox_unlink(): dropbox_id = session.get('dropbox_id') if dropbox_id is None: abort(403) user = User.query.filter_by(dropbox_id=dropbox_id).first() for attribute in ['active', 'access_token', 'cursor']:
if dropbox_id is None: return redirect(url_for('home')) user = User.query.filter_by(dropbox_id=dropbox_id).first() new_user = user is None if user is None: user = User(dropbox_id) user.set_new_emailer() db.session.add(user) user.access_token = access_token (user.name, user.email) = get_dropbox_name_email(access_token) db.session.commit() if new_user: analytics.track(str(user.id), 'Registered') analytics.track(str(user.id), 'Logged in') session['dropbox_id'] = user.dropbox_id return redirect(url_for('home')) @app.route('/dropbox-unlink') def dropbox_unlink(): dropbox_id = session.get('dropbox_id') if dropbox_id is None: abort(403) user = User.query.filter_by(dropbox_id=dropbox_id).first() for attribute in ['active', 'access_token', 'cursor']:
def _conduct_oauth_login(auth_system, login_service, lid, lusername, lemail, metadata=None, captcha_verified=False): """ Conducts login from the result of an OAuth service's login flow and returns the status of the login, as well as the followup step. """ service_id = login_service.service_id() service_name = login_service.service_name() # Check for an existing account *bound to this service*. If found, conduct login of that account # and redirect. user_obj = model.user.verify_federated_login(service_id, lid) if user_obj is not None: return _oauthresult(user_obj=user_obj, service_name=service_name) # If the login service has a bound field name, and we have a defined internal auth type that is # not the database, then search for an existing account with that matching field. This allows # users to setup SSO while also being backed by something like LDAP. bound_field_name = login_service.login_binding_field() if auth_system.federated_service is not None and bound_field_name is not None: # Perform lookup. logger.debug('Got oauth bind field name of "%s"', bound_field_name) lookup_value = None if bound_field_name == "sub": lookup_value = lid elif bound_field_name == "username": lookup_value = lusername elif bound_field_name == "email": lookup_value = lemail if lookup_value is None: logger.error("Missing lookup value for OAuth login") return _oauthresult( service_name=service_name, error_message="Configuration error in this provider") (user_obj, err) = auth_system.link_user(lookup_value) if err is not None: logger.debug("%s %s not found: %s", bound_field_name, lookup_value, err) msg = "%s %s not found in backing auth system" % (bound_field_name, lookup_value) return _oauthresult(service_name=service_name, error_message=msg) # Found an existing user. Bind their internal auth account to this service as well. result = _attach_service(login_service, user_obj, lid, lusername) if result.error_message is not None: return result return _oauthresult(user_obj=user_obj, service_name=service_name) # Otherwise, we need to create a new user account. blacklisted_domains = app.config.get("BLACKLISTED_EMAIL_DOMAINS", []) if not can_create_user(lemail, blacklisted_domains=blacklisted_domains): error_message = "User creation is disabled. Please contact your administrator" return _oauthresult(service_name=service_name, error_message=error_message) if features.RECAPTCHA and not captcha_verified: return _oauthresult(service_name=service_name, requires_verification=True) # Try to create the user try: # Generate a valid username. new_username = None for valid in generate_valid_usernames(lusername): if model.user.get_user_or_org(valid): continue new_username = valid break requires_password = auth_system.requires_distinct_cli_password prompts = model.user.get_default_user_prompts(features) user_obj = model.user.create_federated_user( new_username, lemail, service_id, lid, set_password_notification=requires_password, metadata=metadata or {}, confirm_username=features.USERNAME_CONFIRMATION, prompts=prompts, email_required=features.MAILING, ) # Success, tell analytics analytics.track(user_obj.username, "register", {"service": service_name.lower()}) return _oauthresult(user_obj=user_obj, service_name=service_name) except model.InvalidEmailAddressException: message = ("The e-mail address {0} is already associated " "with an existing {1} account. \n" "Please log in with your username and password and " "associate your {2} account to use it in the future.") message = message.format(lemail, app.config["REGISTRY_TITLE_SHORT"], service_name) return _oauthresult(service_name=service_name, error_message=message, register_redirect=True) except model.DataModelException as ex: return _oauthresult(service_name=service_name, error_message=str(ex))