def add_item_to_plan(self): if not current_user.is_authenticated(): raise RequestException("access denied") user_id = current_user.id params = self._get_json_func_params( requiredParams=["plan_uid", "item_uid", "food_data_source_type", "servings"], optionalParams=["food_id", "food_uid", "food_weight_id"]) food_data_source_type = int(params["food_data_source_type"]) plan = DayPlan.by_user_and_uid(user_id, params["plan_uid"]) if not plan: raise RequestException("plan not found") item_params = { 'servings': params["servings"], 'food_data_source_type': food_data_source_type, 'day_plan_id': plan.id, 'uid': params["item_uid"] } if food_data_source_type == DayPlanItem.FOOD_DATA_SOURCE_TYPE_DEFAULT: item_params['chosen_default_food_id'] = params["food_id"] or 0 item_params['chosen_default_food_weight_id'] = params["food_weight_id"] or 0 elif food_data_source_type == DayPlanItem.FOOD_DATA_SOURCE_TYPE_CUSTOM: if (params["food_uid"]): custom_food = CustomFood.by_user_and_uid(user_id, params["food_uid"]) if custom_food is None: raise RequestException("food not found") item_params['chosen_custom_food_id'] = custom_food.id else: #only allow access to custom foods the user owns raise RequestException("access forbidden") else: raise RequestException('Unrecognized food_data_source_type') new_item = DayPlanItem(**item_params) db.session.add(new_item) db.session.commit() return True
def register_user(self): if current_user.is_authenticated(): raise RequestException("you're already logged in") params = self._get_json_func_params( requiredParams=["email", "password", "password_confirm", "recaptcha_challenge_field", "recaptcha_response_field", "initial_workout_plan_uid", "initial_rest_plan_uid"]) form_class = app.extensions['security'].confirm_register_form form_data = MultiDict(params) form = form_class(form_data) if form.validate_on_submit(): user = flask_security_register_user(**form.to_dict()) user.create_profile() user.create_default_meal_plans( initial_workout_plan_uid=params["initial_workout_plan_uid"], initial_rest_plan_uid=params["initial_rest_plan_uid"]) form.user = user db.session.commit() flask_security_login_user(user) has_errors = len(form.errors) > 0 #this doesnt currently fit well with simpleapi's success variable and can definitely be improved if has_errors: response = { 'code': 400, 'errors': form.errors } else: response = { 'code': 200, 'app_context': AppContext.make_json_encodable_context() } return response
def load_user(): if current_user.is_authenticated(): g.user = current_user if 'lti_course' in session: g.course = Course.by_id(session['lti_course']) else: g.user = None
def make_json_encodable_context(): context = { 'logged_in': False, 'user_id': 0, 'custom_foods': [], 'day_plans': [], 'profile': {} } if current_user.is_authenticated(): user_id = current_user.id day_plans = DayPlan.get_plans_by_user(user_id) custom_foods = CustomFood.get_foods_by_user(user_id) #sort custom foods by name to make them easier to find in the list sorted_custom_foods = sorted(custom_foods, key=lambda food: food.name) user_profile = current_user.profile context.update({ 'logged_in': True, 'user_id': user_id, 'day_plans': day_plans, 'custom_foods': sorted_custom_foods, 'profile': user_profile }) return to_json_encodable_datatypes(context)
def application(application_id): client = docker.get_client() application = applications.get_application(application_id) if not application: flask.abort(404) application_status = None application_domain = None application_version = None application_image_version = docker.get_application_image_version(client, application) form = None if current_user.is_authenticated(): form = forms.ApplicationForm() if form.validate_on_submit(): if form.start.data: docker.create_application(client, current_user, application) if form.stop.data: docker.delete_application(client, current_user, application) return flask.redirect(flask.url_for('application', application_id=application_id)) application_status = docker.get_application_status(client, current_user, application) application_domain = applications.get_application_domain(current_user, application) application_version = docker.get_application_version(client, current_user, application) return flask.render_template('application.html', application=application, application_status=application_status, application_domain=application_domain, application_version=application_version, application_image_version=application_image_version, form=form)
def delete(self, id): if current_user.is_authenticated(): result = models.Story.query.get(id) result.watchers.remove(current_user) db.session.commit() return current_user else: return unauthorized()
def patch(self): if current_user.is_authenticated(): for key, val in parser.parse_args().items(): setattr(current_user, key, val) db.session.commit() return current_user else: return unauthorized()
def post(self, id): if current_user.is_authenticated(): result = models.Story.query.get(id) result.watchers.append(current_user) db.session.commit() return '', 201 else: return unauthorized()
def front(): try: related_videos = Videos.query.order_by(Videos.rating) return render_template('index.html', logged_in=current_user.is_authenticated(), videos=related_videos) except Exception as e: print e.message
def delete(self, id): if current_user.is_authenticated(): result = models.Story.query.get(id) result.watchers.remove(current_user) db.session.commit() return '', 204 else: return unauthorized()
def logout_user(self): if not current_user.is_authenticated(): raise RequestException("you're not logged in") flask_security_logout_user() response = { 'code': 200, 'app_context': AppContext.make_json_encodable_context() } return response
def other_account(username): requested_user = User.query.filter_by(email=username).first() videos = video_handler.get_videos(requested_user.email) user = None twitter_conn = None facebook_conn = None if current_user.is_authenticated(): if current_user.email == requested_user.email: user = current_user twitter_conn = video_handler.social.twitter.get_connection() facebook_conn = video_handler.social.facebook.get_connection() return render_template('account.html', logged_in=current_user.is_authenticated(), requested_user=requested_user, user=user, videos=videos, twitter_conn=twitter_conn, facebook_conn=facebook_conn)
def account(): videos = video_handler.get_videos(current_user.email) return render_template('account.html', logged_in=current_user.is_authenticated(), user=current_user, requested_user=current_user, videos=videos, twitter_conn=video_handler.social.twitter.get_connection(), facebook_conn=video_handler.social.facebook.get_connection())
def account(): videos = video_handler.get_videos(current_user.email) return render_template( 'account.html', logged_in=current_user.is_authenticated(), user=current_user, requested_user=current_user, videos=videos, twitter_conn=video_handler.social.twitter.get_connection(), facebook_conn=video_handler.social.facebook.get_connection())
def index_page(): if( current_user.is_authenticated() ): return redirect( "/rider" ) accountForm = AccountForm() ret = registerValidation( accountForm ) if ret: return ret else: return render_template( "index/index.html", form=accountForm )
def update_profile(self): if not current_user.is_authenticated(): raise RequestException("access denied") params = self._get_json_func_params(requiredParams=["profile"]) mutable_settings = ['gender', 'height', 'weight', 'activity_multiplier', 'units', 'weekly_weight_loss', 'caloric_split', 'age', 'rest_day_liss_cardio'] for setting in mutable_settings: if setting in params['profile']: setattr(current_user.profile, setting, params['profile'][setting]) db.session.commit() return True
def delete_custom_food(self): if not current_user.is_authenticated(): raise RequestException("access denied") user_id = current_user.id params = self._get_json_func_params(requiredParams=["food_uid"]) custom_food = CustomFood.by_user_and_uid(user_id, params["food_uid"]) if custom_food is None: raise RequestException("food not found") #delete items using custom food DayPlanItem.query.filter(DayPlanItem.chosen_custom_food_id == custom_food.id).delete() db.session.delete(custom_food) db.session.commit() return True
def bulk_call(self): if not current_user.is_authenticated(): raise RequestException("access denied") user_id = current_user.id params = self._get_json_func_params(requiredParams=["calls"]) calls = params["calls"] for call in calls: function_name = call["fn"] fn = getattr(self, function_name, None) if not fn or not fn.published: raise RequestException("function not found " + function_name) self.current_fn_params = call["data"] fn() return True
def video(video): try: video_url = uploader.videos.url(video) video = Videos.query.filter_by(url=video_url).first() video.views += 1; video_handler.db.session.commit() username = video.user other_videos = video_handler.get_videos(username) return render_template('video.html', video=video, logged_in=current_user.is_authenticated(), videos=other_videos) except Exception as e: print e.message
def video(video): try: video_url = uploader.videos.url(video) video = Videos.query.filter_by(url=video_url).first() video.views += 1 video_handler.db.session.commit() username = video.user other_videos = video_handler.get_videos(username) return render_template('video.html', video=video, logged_in=current_user.is_authenticated(), videos=other_videos) except Exception as e: print e.message
def remove_item_from_plan(self): if not current_user.is_authenticated(): raise RequestException("access denied") user_id = current_user.id params = self._get_json_func_params(requiredParams=["plan_uid", "item_uid"]) plan = DayPlan.by_user_and_uid(user_id, params["plan_uid"]) if not plan: raise RequestException("plan not found") if params["item_uid"] not in plan.items: raise RequestException("item not found") item = plan.items[params["item_uid"]] db.session.delete(item) db.session.commit() return True
def modify_custom_food(self): if not current_user.is_authenticated(): raise RequestException("access denied") user_id = current_user.id params = self._get_json_func_params(requiredParams=["food_uid", "name", "serving_size", "protein", "carbs", "fat", "calories"]) custom_food = CustomFood.by_user_and_uid(user_id, params["food_uid"]) if custom_food is None: raise RequestException("food not found") custom_food.name = params["name"] custom_food.serving_size = params["serving_size"] custom_food.protein = params["protein"] custom_food.carbs = params["carbs"] custom_food.fat = params["fat"] custom_food.calories = params["calories"] db.session.commit() return True
def client(): if not current_user.is_authenticated(): return redirect('/') client = Client( client_id=gen_salt(40), client_secret=gen_salt(50), _redirect_uris='http://localhost:5000/authorized', _default_scopes='userinfo', _allowed_grant_types='authorization_code refresh_token', user_id=current_user.id, ) db.session.add(client) db.session.commit() return jsonify( client_id=client.client_id, client_secret=client.client_secret, )
def create_custom_food(self): if not current_user.is_authenticated(): raise RequestException("access denied") user_id = current_user.id params = self._get_json_func_params(requiredParams=["food_uid", "name", "serving_size", "protein", "carbs", "fat", "calories"]) item_params = { 'name': params["name"], 'user_id': user_id, 'uid': params["food_uid"], 'serving_size': params["serving_size"], 'protein': params["protein"], 'carbs': params["carbs"], 'fat': params["fat"], 'calories': params["calories"] } new_food = CustomFood(**item_params) db.session.add(new_food) db.session.commit() return True
def modify_plan_item(self): if not current_user.is_authenticated(): raise RequestException("access denied") user_id = current_user.id params = self._get_json_func_params( requiredParams=["plan_uid", "item_uid"], optionalParams=["food_weight_id", "servings"]) plan = DayPlan.by_user_and_uid(user_id, params["plan_uid"]) if not plan: raise RequestException("plan not found") if params["item_uid"] not in plan.items: raise RequestException("item not found") item = plan.items[params["item_uid"]] if params["food_weight_id"]: if item.food_data_source_type == DayPlanItem.FOOD_DATA_SOURCE_TYPE_DEFAULT: item.chosen_default_food_weight_id = params["food_weight_id"] else: raise RequestException("custom foods do not have weight id specifiers") if params["servings"]: item.servings = params["servings"] db.session.commit() return True
def login_user(self): if current_user.is_authenticated(): raise RequestException("you're already logged in") params = self._get_json_func_params( requiredParams=["email", "password"]) form_class = app.extensions['security'].login_form form = form_class(MultiDict(params)) if form.validate_on_submit(): flask_security_login_user(form.user) db.session.commit() has_errors = len(form.errors) > 0 #this doesnt currently fit well with simpleapi's success variable and can definitely be improved if has_errors: response = { 'code': 400, 'errors': form.errors } else: response = { 'code': 200, 'app_context': AppContext.make_json_encodable_context() } return response
def application(application_id): client = get_client() application = get_application(application_id) application_status = None application_domain = None application_version = None application_image_version = get_application_image_version( client, application) form = None if current_user.is_authenticated(): form = ApplicationForm() if form.validate_on_submit(): if form.start.data: create_application(client, current_user, application) if form.stop.data: delete_application(client, current_user, application) return redirect( url_for('application', application_id=application_id)) application_status = get_application_status(client, current_user, application) application_domain = get_application_domain(current_user, application) application_version = get_application_version(client, current_user, application) return render_template('application.html', application=application, application_status=application_status, application_domain=application_domain, application_version=application_version, application_image_version=application_image_version, form=form)
def application(application_id): application_status = None application_domain = None form = None if current_user.is_authenticated(): application = get_application(application_id) client = get_client() form = ApplicationForm() if form.validate_on_submit(): if form.start.data: create_application(client, current_user, application) if form.stop.data: delete_application(client, current_user, application) return redirect(url_for('application', application_id=application_id)) application_status = get_application_status(client, current_user, application) application_domain = get_application_domain(current_user, application) return render_template('application.html', application=get_application(application_id), application_status=application_status, application_domain=application_domain, form=form)
def listings(): pay = request.form.to_dict() query = pay['query'] return render_template('listings.html', query=query, logged_in=current_user.is_authenticated())
def authorize(*args, **kwargs): """ Authorization endpoint for OAuth2. Successful interaction with this endpoint yields an access token for the requesting client. Please note that I am not very confident of this current approach's security; it involves a shaky workaround to implement the resource owner password credentials (ROPC) OAuth2 flow for the official mobile app. Mobile applications are considered "public" clients because their client credentials (client id and client secret) cannot reliably be kept secure, since if they are bundled with the application they are potentially accessible to anyone who has the app on their phone. But the ROPC flow works like this: * User opens the mobile app and is greated with a native login view. * User enters their credentials and hits "Login". * POST to `/oauth/authorize?client_id=<CLIENT_ID>&response_type=code&grant_type=resource_owner_credentials&scope=userinfo&redirect_uri=<your redirect uri>`, with data: `{"email": <user email>, "password": <user password>}` * Server finds client with the specified client id, checks that the client is allowed the ROPC grant type, and if so, authenticates the user with the provided credentials. * If successful, the server responds with the header `Location: <your redirect uri>/?code=<your authorization code>` * In the mobile app, you can extract the authorization code and exchange it for the access token by sending a GET request to `/oauth/token?code=<your authorization code>&grant_type=authorization_code&client_id=<your client_id>&redirect_uri=<your redirect uri>` * If successful, the server responds with something like: `{"refresh_token": "Z9QAolFevdLXjO7OR1ImJ1pkqc248j", "scope": "userinfo", "access_token": "wvjTny7CXEVEQSfyxC1MSP11NEPnlj", "token_type": "Bearer"}` Clearly this is not the ideal flow and not really according to OAuth2 specifications. Anyone can discover and use the client id to imitate the official client since there is no (and cannot be any) verification of client authenticity with a client secret. Unless the provider server is secured with SSL/HTTPS, passwords are sent out in the open. It is only a temporary solution. A potential long-term solution is to use OAuth2's "client credentials" flow and consider each *installation* of the mobile application as a *separate* client. Thus each installation has its own unique client id and client secret, relevant only for that particular user. This still may not be very good (haven't thought it all the way through). For some more info see: * https://stackoverflow.com/questions/14574846/client-authentication-on-public-client * https://stackoverflow.com/questions/6190381/how-to-keep-the-client-credentials-confidential-while-using-oauth2s-resource-o """ # NB: request.values refers to values from both # the response body and the url parameters. client_id = request.values.get('client_id') client = Client.query.get(client_id) grant_type = request.values.get('grant_type') # Check to see if the requested scope(s) are permitted # for this client. # Since this is a workaround (see below), this looks a bit weird. # But if the expected kwargs isn't processed (flask_oauthlib only processes them # if it is a GET request), collect the scope information another way. # GET POST scopes = kwargs.get('scopes') or request.values.get('scope').split() client.validate_scopes(scopes) # Check to see if the requested grant type is permitted # for this client. client.validate_grant_type(grant_type) if request.method == 'GET': kwargs['client'] = client if grant_type == 'authorization_code': # The user must authenticate herself, # if not already authenticated. if not current_user.is_authenticated(): return redirect(url_for('security.login', next=url_for('authorize'))) kwargs['user'] = current_user return render_template('authorize.html', **kwargs) response = jsonify({'message': 'Invalid grant type for this request. Perhaps you mean a grant_type of `authorization_code`?'}) response.status_code = 400 return response elif request.method == 'POST': # Authenticate on behalf of the user. # ONLY TRUSTED CLIENTS should be allowed this grant type. # i.e. only official clients, all others should be using # grant type of `authorization_code`. # This is enforced since clients are by default restrited to only # the `authorization_code` grant type, unless explicitly set otherwise. # Note: this is a workaround since flask_oauthlib does not support the "password" # grant type at the moment (which is equivalent to "resource_owner_credentials"). if grant_type == 'resource_owner_credentials': form = LoginForm(request.form, csrf_enabled=False) if form.validate_on_submit(): login_user(form.user) return True else: print(form.errors) return False # Otherwise, assume this request is coming from # the authorization_code's authorize form. else: confirm = request.form.get('confirm', 'no') return confirm == 'yes'
def get(self): if current_user.is_authenticated(): return current_user else: return unauthorized()
def load_user(): if current_user.is_authenticated(): g.user = current_user else: g.user = None
def authorize(*args, **kwargs): """ Authorization endpoint for OAuth2. Successful interaction with this endpoint yields an access token for the requesting client. Please note that I am not very confident of this current approach's security; it involves a shaky workaround to implement the resource owner password credentials (ROPC) OAuth2 flow for the official mobile app. Mobile applications are considered "public" clients because their client credentials (client id and client secret) cannot reliably be kept secure, since if they are bundled with the application they are potentially accessible to anyone who has the app on their phone. But the ROPC flow works like this: * User opens the mobile app and is greated with a native login view. * User enters their credentials and hits "Login". * POST to `/oauth/authorize?client_id=<CLIENT_ID>&response_type=code&grant_type=resource_owner_credentials&scope=userinfo&redirect_uri=<your redirect uri>`, with data: `{"email": <user email>, "password": <user password>}` * Server finds client with the specified client id, checks that the client is allowed the ROPC grant type, and if so, authenticates the user with the provided credentials. * If successful, the server responds with the header `Location: <your redirect uri>/?code=<your authorization code>` * In the mobile app, you can extract the authorization code and exchange it for the access token by sending a GET request to `/oauth/token?code=<your authorization code>&grant_type=authorization_code&client_id=<your client_id>&redirect_uri=<your redirect uri>` * If successful, the server responds with something like: `{"refresh_token": "Z9QAolFevdLXjO7OR1ImJ1pkqc248j", "scope": "userinfo", "access_token": "wvjTny7CXEVEQSfyxC1MSP11NEPnlj", "token_type": "Bearer"}` Clearly this is not the ideal flow and not really according to OAuth2 specifications. Anyone can discover and use the client id to imitate the official client since there is no (and cannot be any) verification of client authenticity with a client secret. Unless the provider server is secured with SSL/HTTPS, passwords are sent out in the open. It is only a temporary solution. A potential long-term solution is to use OAuth2's "client credentials" flow and consider each *installation* of the mobile application as a *separate* client. Thus each installation has its own unique client id and client secret, relevant only for that particular user. This still may not be very good (haven't thought it all the way through). For some more info see: * https://stackoverflow.com/questions/14574846/client-authentication-on-public-client * https://stackoverflow.com/questions/6190381/how-to-keep-the-client-credentials-confidential-while-using-oauth2s-resource-o """ # NB: request.values refers to values from both # the response body and the url parameters. client_id = request.values.get('client_id') client = Client.query.get(client_id) grant_type = request.values.get('grant_type') # Check to see if the requested scope(s) are permitted # for this client. # Since this is a workaround (see below), this looks a bit weird. # But if the expected kwargs isn't processed (flask_oauthlib only processes them # if it is a GET request), collect the scope information another way. # GET POST scopes = kwargs.get('scopes') or request.values.get('scope').split() client.validate_scopes(scopes) # Check to see if the requested grant type is permitted # for this client. client.validate_grant_type(grant_type) if request.method == 'GET': kwargs['client'] = client if grant_type == 'authorization_code': # The user must authenticate herself, # if not already authenticated. if not current_user.is_authenticated(): return redirect( url_for('security.login', next=url_for('authorize'))) kwargs['user'] = current_user return render_template('authorize.html', **kwargs) response = jsonify({ 'message': 'Invalid grant type for this request. Perhaps you mean a grant_type of `authorization_code`?' }) response.status_code = 400 return response elif request.method == 'POST': # Authenticate on behalf of the user. # ONLY TRUSTED CLIENTS should be allowed this grant type. # i.e. only official clients, all others should be using # grant type of `authorization_code`. # This is enforced since clients are by default restrited to only # the `authorization_code` grant type, unless explicitly set otherwise. # Note: this is a workaround since flask_oauthlib does not support the "password" # grant type at the moment (which is equivalent to "resource_owner_credentials"). if grant_type == 'resource_owner_credentials': form = LoginForm(request.form, csrf_enabled=False) if form.validate_on_submit(): login_user(form.user) return True else: print(form.errors) return False # Otherwise, assume this request is coming from # the authorization_code's authorize form. else: confirm = request.form.get('confirm', 'no') return confirm == 'yes'
def is_accessible(self): return (current_user.is_authenticated() and current_user.has_role('Admin'))