def delete(self,faq_id): """ To delete the FAQ based on specific faq_id """ #check if user has admin privileges user_status,user = has_admin_privileges() if user_status == "no_auth_token": return (bad_request,400,headers) if user_status == "not_logged_in": return (unauthorized,401,headers) if user_status in ["director","organizer"]: try: faq_to_delete = g.session.query(g.Base.classes.faqs).get(faq_id) if faq_to_delete: #this makes sure that at least one faq matches faq_id g.session.query(g.Base.classes.faqs).filter(g.Base.classes.faqs.id == faq_id).delete() return ("",204,headers) else: return (not_found,404,headers) except Exception as err: print(type(err)) print(err) return (internal_server_error,500,headers) else: return (forbidden,403,headers)
def get(self, application_id): """ GET the application details based on specific application_id """ #using get instead of filter and it is marginally faster than filter #check for multiple entries need to be done at POST and not during GET or PUT or DELETE user_status, calling_user = has_admin_privileges() if user_status == "no_auth_token": return (bad_request, 400, headers) if user_status == "not_logged_in": return (unauthorized, 401, headers) # getting the application. Assuming the application exists. Case of application not existing is checked below try: application = g.session.query( g.Base.classes.applications).get(application_id) except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers) # *Only allow directors, organizers and the user making the request to access his own user id to access this resource # *Compare user_id rather than complete user objects because it's faster if application: if user_status in ["director", "organizer" ] or calling_user.id == application.user_id: ret = Application_Schema().dump(application).data return (ret, 200, headers) else: return (forbidden, 403, headers) else: return (not_found, 404, headers)
def put(self): """ Update user. Required data: email, first_name, last_name, password, confirmation_password PUT is allowed only by users on their own objects. """ #check if data from request is serializable try: data = request.get_json(force=True) except BadRequest: return (bad_request, 400, headers) user_status, calling_user = has_admin_privileges() if user_status == "no_auth_token": return (bad_request, 400, headers) if user_status == "not_logged_in": return (unauthorized, 401, headers) # *request data validation. Check for empty fields will be done by frontend validation = User_Input_Schema().validate(data) if validation: unprocessable_entity["error_list"] = validation["_schema"][0] return (unprocessable_entity, 422, headers) # *Only allow user making the request to access their own user id to access this resource # *The original email, first_name and last_name to be provided in the request. Just updated value setting will be implemented in PATCH which would be in API 2.0 try: calling_user.email = data["email"] calling_user.first_name = data["first_name"] calling_user.last_name = data["last_name"] return (User_Schema().dump(calling_user).data, 200, headers) except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers)
def delete(self,schedule_id): """ DELETE request to delete hardware based on specific hardware_id. This is new from the old api. """ user_status,user = has_admin_privileges() if user_status == "no_auth_token": return (bad_request,400,headers) if user_status == "not_logged_in": return (unauthorized,401,headers) if user_status in ["director","organizer"]: try: #this makes sure that at least one hardware matches hardware id schedule_item_to_delete = g.session.query(g.Base.classes.schedules).get(schedule_id) if schedule_item_to_delete: g.session.query(g.Base.classes.schedules).filter(g.Base.classes.schedules.id == schedule_id).delete() return ("",204,headers) else: return (not_found,404,headers) except Exception as err: print(type(err)) print(err) return (internal_server_error,500,headers) else: return (forbidden,403,headers)
def get(self): """ GET all the users at a time. Application_id and rsvp_id is not gonna be returned when GET is called on all the users. Because getting the application_id and rsvp_id makes db calls and making calls for application_id and rsvp_id on hundreds of users is costly. """ user_status, calling_user = has_admin_privileges() if user_status == "no_auth_token": return (bad_request, 400, headers) if user_status == "not_logged_in": return (unauthorized, 401, headers) # *Only allow directors, organizers to make GET on all users (I don't really see the need for this tbh!)maybe for accepting applications if user_status in ["director", "organizer", "volunteer"]: try: all_users = g.session.query(g.Base.classes.users).all() ret = User_Schema(many=True).dump(all_users).data return (ret, 200, headers) except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers) else: forbidden["error_list"] = { "Authorization error": "You do not privileges to access this resource. Contact one of the organizers if you think require access." } return (forbidden, 403, headers)
def get(self, user_id): """ GET the rsvp details based on specific user_id """ #using get instead of filter and it is marginally faster than filter #check for multiple entries need to be done at POST and not during GET or PUT or DELETE user_status, calling_user = has_admin_privileges() if user_status == "no_auth_token": return (bad_request, 400, headers) if user_status == "not_logged_in": return (unauthorized, 401, headers) # getting the rsvp. Assuming the rsvp exists. Case of application not existing is checked below try: rsvp = g.session.query(g.Base.classes.rsvps).filter( g.Base.classes.rsvps.user_id == user_id).first() except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers) if rsvp: if user_status in ["director", "organizer" ] or calling_user.id == rsvp.user_id: ret = RSVP_Schema().dump(rsvp).data return (ret, 200, headers) else: return (forbidden, 403, headers) else: return (not_found, 404, headers)
def delete(self, sponsor_id): """ For DELETE request for specific sponsor id """ # *Check for user status user_status, user = has_admin_privileges() if user_status == "no_auth_token": return (bad_request, 400, headers) if user_status == "not_logged_in": return (unauthorized, 401, headers) if user_status in ["director", "organizer"]: try: # *get the sponsor matching sponsor id if not return 404 sponsor_to_delete = g.session.query( g.Base.classes.sponsors).get(sponsor_id) if sponsor_to_delete: g.session.query(g.Base.classes.sponsors).filter( g.Base.classes.sponsors.id == sponsor_id).delete() return ("", 204, headers) else: return (not_found, 404, headers) except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers) else: # *sponsor deletion only limited to directors and organizers return (forbidden, 403, headers)
def post(self): """ For POST request. Checks for bad JSON from request, checks if data types in request JSON are correct, Checks user auth status and if he's logged in. """ try: data = request.get_json(force=True) except BadRequest: return (bad_request, 400, headers) #data validation if Sponsor_Schema().validate(data): return (unprocessable_entity, 422, headers) #check if user has admin privileges user_status, user = has_admin_privileges() if user_status == "no_auth_token": return (bad_request, 400, headers) if user_status == "not_logged_in": return (unauthorized, 401, headers) # *checking if hardware with same name and url already exists. To manage duplicate entries try: exist_check = g.session.query(exists().where( and_(g.Base.classes.sponsors.name == data["name"], g.Base.classes.sponsors.url == data["url"]))).scalar() if exist_check: return (conflict, 409, headers) except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers) if user_status in ["director", "organizer"]: Sponsors = g.Base.classes.sponsors try: new_sponsor = Sponsors(name=data["name"], url=data["url"], level=data["level"], logo_svg_light=data["logo_svg_light"], logo_png_light=data["logo_png_light"], updated_at=datetime.now(), created_at=datetime.now()) if data.get("logo_svg_dark"): new_sponsor.logo_svg_dark = data["logo_svg_dark"] if data.get("logo_png_dark"): new_sponsor.logo_png_dark = data["logo_png_dark"] g.session.add(new_sponsor) g.session.commit() ret = g.session.query(g.Base.classes.sponsors).filter( g.Base.classes.sponsors.name == data["name"]).one() return (Sponsor_Schema().dump(ret).data, 201, headers) except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers) else: return (forbidden, 403, headers)
def post(self): """ Only method needed """ user_status, calling_user = has_admin_privileges() if user_status == "no_auth_token": return (bad_request, 400, headers) if user_status == "not_logged_in": return (unauthorized, 401, headers) try: data = request.get_json(force=True) except BadRequest: return (bad_request, 400, headers) # *request data validation validation = User_Change_Role_Schema().validate(data) if validation: unprocessable_entity["error_list"] = validation["_schema"][0] return (unprocessable_entity, 422, headers) # getting the user. Assuming the user exists. Case of user not existing is checked below try: user = g.session.query(g.Base.classes.users).filter( g.Base.classes.users.email == data["email"]).one() except NoResultFound: # *If no user with that email is found with that token then you send 422 error not_found["error_list"]["email"] = "No user found with that email" return (not_found, 404, headers) except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers) # *Only directors have the ability to change user roles try: if user_status in [ "director" ] and data["role_change_password"] == app.config[ "ROLE_CHANGE_PASS_DEV"]: user.role = 2**([ "director", "judge", "mentor", "sponsor", "organizer", "volunteer", "hacker" ].index(data["role"])) return (User_Schema().dump(user).data, 200, headers) else: forbidden["error_list"] = { "Authorization error": "You do not privileges to access this resource. Contact one of the organizers if you think require access." } return (forbidden, 403, headers) except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers)
def post(self): #request validation try: data = request.get_json(force=True) except BadRequest: return (bad_request,400,headers) #data validation if Faq_Schema().validate(data): return (unprocessable_entity,422,headers) #check if user has admin privileges user_status,user = has_admin_privileges() if user_status == "no_auth_token": return (bad_request,400,headers) if user_status == "not_logged_in": return (unauthorized,401,headers) #checking if faq with same questions and answer already exists. To manage duplicate entries. Check out SQLAlchemy documentation to learn how exists work try: exist_check = g.session.query(exists().where(and_(g.Base.classes.faqs.question == data["question"],g.Base.classes.faqs.answer == data["answer"]))).scalar() if exist_check: return (conflict,409,headers) except Exception as err: print(type(err)) print(err) return (internal_server_error,500,headers) if user_status in ["director","organizer"]: try: Faqs = g.Base.classes.faqs new_faq = Faqs( question = data["question"], answer = data["answer"], user_id = user.id, created_at = datetime.now(), updated_at = datetime.now(), display = data["display"], priority = data["priority"], placement = data["placement"] ) g.session.add(new_faq) g.session.commit() #first() or one() shouldn't matter because we already checked if an faq without same question and answer exits new_faq = g.session.query(g.Base.classes.faqs).filter(g.Base.classes.faqs.question == data["question"]).one() return (Faq_Schema().dump(new_faq).data,201,headers) except Exception as err: print(type(err)) print(err) return (internal_server_error,500,headers) else: return(forbidden,403,headers)
def post(self): """ Create new hardware. Required data: item,lender, quantity """ try: data = request.get_json(force=True) except BadRequest: return (bad_request, 400, headers) #data validation if Hardware_Schema().validate(data): return (unprocessable_entity, 422, headers) #check if user has admin privileges user_status, user = has_admin_privileges() if user_status == "no_auth_token": return (bad_request, 400, headers) if user_status == "not_logged_in": return (unauthorized, 401, headers) try: exist_check = g.session.query(exists().where( and_(g.Base.classes.hardware.item == data["item"], g.Base.classes.hardware.lender == data["lender"]))).scalar() if exist_check: return (conflict, 409, headers) except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers) if user_status in ["director", "organizer"]: Hardware = g.Base.classes.hardware try: new_hardware = Hardware(item=data["item"], lender=data["lender"], quantity=data["quantity"], updated_at=datetime.now(), created_at=datetime.now()) g.session.add(new_hardware) g.session.commit() ret = g.session.query(g.Base.classes.hardware).filter( g.Base.classes.hardware.item == data["item"]).one() return (Hardware_Schema().dump(ret).data, 201, headers) except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers) else: return (forbidden, 403, headers)
def get(self, user_id): """ GET the user details based on specific user_id We are considering user and application separate entities. Previously, a user submitted the application details at the time of user account creation. Now, the user creates an account and then logs in to submit the application. Compared to old API we are not returning the application and rsvp details with the user details, rather we are returning the application_id and rsvp_id to help the front-end make GET request on application and rsvp endpoint in a separate requests. """ #using get instead of query and it is marginally faster than filter #check for multiple entries need to be done at POST and not during GET or PUT or DELETE user_status, calling_user = has_admin_privileges() if user_status == "no_auth_token": return (bad_request, 400, headers) if user_status == "not_logged_in": return (unauthorized, 401, headers) # getting the user. Assuming the user exists. Case of user not existing is checked below try: user = g.session.query(g.Base.classes.users).get(user_id) except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers) # *Only allow directors, organizers and the user making the request to access his own user id to access this resource # *Compare user_id rather than complete user objects because it's faster if user: if user_status in ["director", "organizer" ] or calling_user.id == user.id: ret = User_Schema().dump(user).data # *<class_name>_collection is way by which SQLAlchemy stores relationships. # *The collection object contains one related object in one-to-one relationship and more than one object in one-to-many relationships # *set application_id if application object is found in the applications_collection i.e. if the user has submitted the application # *This is different than old API in the sense that a user does not necessarily have a application at the time of account creation. User has the option of submitting the application later on. ret["application_id"] = user.applications_collection[ 0].id if user.applications_collection else None # *set rsvp_id if rsvp object is found in the rsvps_collection i.e. if the user has rsvped ret["rsvp_id"] = user.rsvps_collection[ 0].id if user.rsvps_collection else None return (ret, 200, headers) else: forbidden["error_list"] = { "Authorization error": "You do not privileges to access this resource. Contact one of the organizers if you think require access." } return (forbidden, 403, headers) else: return (not_found, 404, headers)
def post(self): """ Only method needed """ user_status, calling_user = has_admin_privileges() if user_status == "no_auth_token": return (bad_request, 400, headers) if user_status == "not_logged_in": return (unauthorized, 401, headers) try: data = request.get_json(force=True) except BadRequest: return (bad_request, 400, headers) # *request data validation. Check for empty fields will be done by frontend validation = User_Reset_Password_Schema().validate(data) if validation: if not data.get("current_password"): unprocessable_entity["error_list"][ "current_password"] = "******" unprocessable_entity["error_list"] = validation["_schema"][0] return (unprocessable_entity, 422, headers) # *change password of user through normal account login try: # *proceed only if user exists if calling_user: # *proceed only if current_password is correct if verify_pass(data["current_password"], calling_user.encrypted_password): calling_user.encrypted_password = encrypt_pass( data["password"]) calling_user.updated_at = datetime.now() else: forbidden["error_list"][ "current_password"] = "******" return (forbidden, 403, headers) return (User_Schema().dump(calling_user).data, 200, headers) else: return (not_found, 404, headers) except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers)
def put(self,faq_id): """ For updating the faq based on specific faq_id. Required data: question, answer, display, priority, placement """ #check if data from request is serializable try: data = request.get_json(force=True) except BadRequest: return (bad_request,400,headers) #data validation if Faq_Schema().validate(data): return (unprocessable_entity,422,headers) #check if user has admin privileges user_status,user = has_admin_privileges() if user_status == "no_auth_token": return (bad_request,400,headers) if user_status == "not_logged_in": return (unauthorized,401,headers) if user_status in ["director","organizer"]: try: faq_object = g.session.query(g.Base.classes.faqs).get(faq_id) if faq_object: faq_object.question = data["question"] faq_object.answer = data["answer"] faq_object.display = data["display"] faq_object.priority = data["priority"] faq_object.placement = data["placement"] faq_object.user_id = user.id faq_object.updated_at = datetime.now() ret = Faq_Schema().dump(faq_object).data return (ret,200,headers) else: return (not_found,404,headers) except Exception as err: print(type(err)) print(err) return (internal_server_error,500,headers) else: return (forbidden,403,headers)
def put(self,schedule_id): """ Update the hardware. Required data: title, description, time, location """ #check if data from request is serializable try: data = request.get_json(force=True) except BadRequest: return (bad_request,400,headers) #data validation if Schedule_Schema().validate(data): return (unprocessable_entity,422,headers) #check if user has admin privileges user_status,user = has_admin_privileges() if user_status == "no_auth_token": return (bad_request,400,headers) if user_status == "not_logged_in": return (unauthorized,401,headers) if user_status in ["director","organizer"]: try: schedule_item = g.session.query(g.Base.classes.schedules).get(schedule_id) if schedule_item: schedule_item.title = data["title"] schedule_item.description = data["description"] schedule_item.time = data["time"] schedule_item.location = data["location"] schedule_item.updated_at = datetime.now() ret = Schedule_Schema().dump(schedule_item).data return (ret,200,headers) else: return (not_found,404,headers) except Exception as err: print(type(err)) print(err) return (internal_server_error,500,headers) else: return (forbidden,403,headers)
def put(self, hardware_id): """ update the hardware. Required data: item, lender, quantity """ #check if data from request is serializable try: data = request.get_json(force=True) except BadRequest: return (bad_request, 400, headers) #data validation if Hardware_Schema().validate(data): return (unprocessable_entity, 422, headers) #check if user has admin privileges user_status, user = has_admin_privileges() if user_status == "no_auth_token": return (bad_request, 400, headers) if user_status == "not_logged_in": return (unauthorized, 401, headers) if user_status in ["director", "organizer"]: try: hardware_item = g.session.query( g.Base.classes.hardware).get(hardware_id) if hardware_item: hardware_item.item = data["item"] hardware_item.lender = data["lender"] hardware_item.quantity = data["quantity"] hardware_item.updated_at = datetime.now() ret = Hardware_Schema().dump(hardware_item).data return (ret, 200, headers) else: return (not_found, 404, headers) except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers) else: return (forbidden, 403, headers)
def get(self): """ GET all the rsvps at a time. """ user_status, calling_user = has_admin_privileges() if user_status == "no_auth_token": return (bad_request, 400, headers) if user_status == "not_logged_in": return (unauthorized, 401, headers) if user_status in ["director", "organizer"]: try: all_rsvps = g.session.query(g.Base.classes.rsvps).all() ret = RSVP_Schema(many=True).dump(all_rsvps).data return (ret, 200, headers) except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers) else: return (forbidden, 403, headers)
def delete(self, application_id): """ Delete the application. Required data: application_id """ user_status, calling_user = has_admin_privileges() if user_status == "no_auth_token": return (bad_request, 400, headers) if user_status == "not_logged_in": return (unauthorized, 401, headers) # getting the application. Assuming the application exists. Case of application not existing is checked below try: application = g.session.query( g.Base.classes.applications).get(application_id) except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers) # *Only allow directors, organizers and the user making the request to access his own user id to access this resource # *Compare user_id rather than complete user objects because it's faster if application: try: if user_status in ["director", "organizer" ] or calling_user.id == application.user_id: g.session.delete( g.session.query( g.Base.classes.applications).get(application_id)) return ("", 204, headers) else: return (forbidden, 403, headers) except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers) else: return (not_found, 404, headers)
def delete(self, user_id): """ DELETE the rsvp details based on specific user_id This will probably not be used by the user """ user_status, calling_user = has_admin_privileges() if user_status == "no_auth_token": return (bad_request, 400, headers) if user_status == "not_logged_in": return (unauthorized, 401, headers) # getting the user. Assuming the user exists. Case of user not existing is checked below try: rsvp = g.session.query(g.Base.classes.rsvps).filter( g.Base.classes.rsvps.user_id == user_id).first() except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers) if rsvp: try: if user_status in ["director", "organizer" ] or calling_user.id == rsvp.user_id: g.session.delete( g.session.query(g.Base.classes.rsvps).get(rsvp.id)) return ("", 204, headers) else: return (forbidden, 403, headers) except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers) else: return (not_found, 404, headers)
def delete(self, user_id): """ DELETE user request. Only Directors, Organizers and user calling the request """ user_status, calling_user = has_admin_privileges() if user_status == "no_auth_token": return (bad_request, 400, headers) if user_status == "not_logged_in": return (unauthorized, 401, headers) # getting the user. Assuming the user exists. Case of user not existing is checked below try: user = g.session.query(g.Base.classes.users).get(user_id) except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers) # *Only Directors, Organizers and user calling the request if user: try: if user_status in ["director", "organizer" ] or calling_user.id == user.id: if user.rsvps_collection: g.session.delete( g.session.query(g.Base.classes.rsvps).get( user.rsvps_collection[0].id)) if user.applications_collection: g.session.delete( g.session.query(g.Base.classes.applications).get( user.applications_collection[0].id)) g.session.delete( g.session.query(g.Base.classes.users).get(user_id)) else: forbidden["error_list"] = { "Authorization error": "You do not privileges to access this resource. Contact one of the organizers if you think require access." } return (forbidden, 403, headers) except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers) else: return (not_found, 404, headers) # error handling for mail send try: f = open("common/account_creation.html", 'r') body = Template(f.read()) f.close() body = body.render(first_name=user.first_name) send_email(subject="Account creation confirmation!", recipient=user.email, body="Account deleted!") return ("", 204, headers) except Exception as err: print(type(err)) print(err) internal_server_error["error_list"][ "error"] = "Account successfully created. Error in confirmation email sending." return (internal_server_error, 500, headers)
def post(self): """ Create new rsvp Required data: attending dietary_restrictions other_dietary_restrictions resume shirt_size carpool_sharing jobs """ try: data = request.get_json(force=True) except BadRequest: return (bad_request, 400, headers) # *request data validation. Check for empty fields will be done by frontend validation = RSVP_Schema().validate(data) if validation: unprocessable_entity["error_list"] = validation return (unprocessable_entity, 422, headers) Rsvps = g.Base.classes.rsvps user_status, calling_user = has_admin_privileges() if user_status == "no_auth_token": return (bad_request, 400, headers) if user_status == "not_logged_in": return (unauthorized, 401, headers) # check if rsvp already submitted try: exist_check = g.session.query( exists().where(Rsvps.user_id == calling_user.id)).scalar() if exist_check: return (conflict, 409, headers) except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers) try: new_rsvp = Rsvps( user_id=calling_user.id, attending=data["attending"], dietary_restrictions=list(set(data["dietary_restrictions"])), other_dietary_restrictions=data["other_dietary_restrictions"], resume=data["resume"], shirt_size=data["shirt_size"], carpool_sharing=data["carpool_sharing"], jobs=data["jobs"], created_at=datetime.now(), updated_at=datetime.now()) g.session.add(new_rsvp) g.session.commit() ret = g.session.query(Rsvps).filter( Rsvps.user_id == calling_user.id).one() ret = RSVP_Schema().dump(ret).data return (ret, 201, headers) except Exception as err: print(type(err)) print(err) internal_server_error["error_list"][ "error"] = "Error in RSVP submission. Please try again." return (internal_server_error, 500, headers)
def post(self): """ Create new application. Required data: birth_day birth_month birth_year education university other_university travel_origin graduation_season graduation_year major hackathons github linkedin website devpost other_link statement race gender outside_north_america reimbursement phone """ try: data = request.get_json(force=True) except BadRequest: return (bad_request, 400, headers) # *request data validation. Check for empty fields will be done by frontend validation = Application_Schema().validate(data) if validation: unprocessable_entity["error_list"] = validation return (unprocessable_entity, 422, headers) Applications = g.Base.classes.applications user_status, calling_user = has_admin_privileges() if user_status == "no_auth_token": return (bad_request, 400, headers) if user_status == "not_logged_in": return (unauthorized, 401, headers) # check if application already submitted try: exist_check = g.session.query(exists().where( Applications.user_id == calling_user.id)).scalar() if exist_check: waste_time() return (conflict, 409, headers) except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers) try: new_application = Applications( user_id=calling_user.id, birth_day=data['birth_day'], birth_month=data['birth_month'], birth_year=data['birth_year'], education=data['education'], university=data['university'], other_university=data['other_university'], travel_origin=data['travel_origin'], graduation_season=data['graduation_season'], graduation_year=data['graduation_year'], major=list(set(data['major'])), hackathons=data['hackathons'], github=data['github'], linkedin=data['linkedin'], website=data['website'], devpost=data['devpost'], other_link=data['other_link'], statement=data['statement'], created_at=datetime.now(), updated_at=datetime.now(), race=list(set(data['race'])), gender=data['gender'], outside_north_america=data['outside_north_america'], status="Applied", reimbursement=data['reimbursement'], phone=data['phone']) g.session.add(new_application) g.session.commit() ret = g.session.query(Applications).filter( Applications.user_id == calling_user.id).one() ret = Application_Schema().dump(ret).data except Exception as err: print(type(err)) print(err) internal_server_error["error_list"][ "error"] = "Error in application submission. Please try again." return (internal_server_error, 500, headers) # error handling for mail send try: f = open("common/application_submitted.html", 'r') body = Template(f.read()) f.close() body = body.render(first_name=calling_user.first_name) send_email(subject="Application submission confirmation!", recipient=calling_user.email, body=body) return (ret, 201, headers) except Exception as err: print(type(err)) print(err) internal_server_error["error_list"][ "error"] = "Application successfully submitted. Error in confirmation email sending." return (internal_server_error, 500, headers)
def put(self, application_id): """ Update the application. Required data: application_id birth_day birth_month birth_year education university other_university travel_origin graduation_season graduation_year major hackathons github linkedin website devpost other_link statement race gender outside_north_america reimbursement phone PUT is allowed only by users on their own objects. """ #check if data from request is serializable try: data = request.get_json(force=True) except BadRequest: return (bad_request, 400, headers) user_status, calling_user = has_admin_privileges() if user_status == "no_auth_token": return (bad_request, 400, headers) if user_status == "not_logged_in": return (unauthorized, 401, headers) # *request data validation. Check for empty fields will be done by frontend validation = Application_Schema().validate(data) if validation: unprocessable_entity["error_list"] = validation return (unprocessable_entity, 422, headers) #* get application for the calling user try: application = g.session.query( g.Base.classes.applications).get(application_id) except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers) # *Only allow user making the request to access their own application id to access this resource # *The original data to be provided in the request. Just updated value setting will be implemented in PATCH which would be in API 2.0 if application: try: if user_status in ["director", "organizer" ] or calling_user.id == application.user_id: application.birth_day = data['birth_day'] application.birth_month = data['birth_month'] application.birth_year = data['birth_year'] application.education = data['education'] application.university = data['university'] application.other_university = data['other_university'] application.travel_origin = data['travel_origin'] application.graduation_season = data['graduation_season'] application.graduation_year = data['graduation_year'] application.major = list(set(data['major'])) application.hackathons = data['hackathons'] application.github = data['github'] application.linkedin = data['linkedin'] application.website = data['website'] application.devpost = data['devpost'] application.other_link = data['other_link'] application.statement = data['statement'] application.updated_at = datetime.now() application.race = list(set(data['race'])) application.gender = data['gender'] application.outside_north_america = data[ 'outside_north_america'] application.status = data['status'] application.reimbursement = data['reimbursement'] application.phone = data['phone'] ret = Application_Schema().dump(application).data return (ret, 200, headers) else: return (forbidden, 403, headers) except Exception as err: print(type(err)) print(err) return (internal_server_error, 500, headers) else: return (not_found, 404, headers)
def post(self): """ Check users in. Required data: user_id """ def is_minor(application): today = date.today() age = today.year - application.birth_year - ( (today.month, today.day) < (application.birth_month, application.birth_day)) return age < 18 Users = g.Base.classes.users Applications = g.Base.classes.applications try: data = request.get_json(force=True) except BadRequest: return (bad_request, 400, headers) user_status, calling_user = has_admin_privileges() if user_status == "no_auth_token": return (bad_request, 400, headers) if user_status == "not_logged_in": return (unauthorized, 401, headers) if data.get("id", "error") == "error": unprocessable_entity["error_list"]["id"] = "User id missing!" return (unprocessable_entity, 422, headers) # getting the user. Assuming the user exists. Case of user not existing is checked below try: user = g.session.query(g.Base.classes.users).get(data["id"]) except Exception as err: app.logger.info(f'SQLAlchemy error {err}', stack_info=True) app.logger.error(f'Error getting the user for id {data["id"]}') return (internal_server_error, 500, headers) try: user_app = g.session.query(Applications).filter( Applications.user_id == data["id"]).one() except Exception as err: app.logger.info(f'SQLAlchemy error {err}', stack_info=True) app.logger.error(f'Error getting the user app for id {data["id"]}') return (internal_server_error, 500, headers) #* only organizers and directors can check people in if user and user_app: try: if user_status in ["director", "organizer", "volunteer"]: if user.checked_in: if is_minor(user_app): return ( f"{user.first_name} {user.last_name} is already checked in!! and is also a minor!", 200, headers) else: return ( f"{user.first_name} {user.last_name} is already checked in!!", 200, headers) else: if is_minor(user_app): user.checked_in = True g.session.commit() return ( f"{user.first_name} {user.last_name} is checked in!! and is also a minor!", 201, headers) user.checked_in = True g.session.commit() return ( f"{user.first_name} {user.last_name} is checked in!!", 201, headers) else: forbidden["error_list"] = { "Authorization error": "You do not privileges to access this resource. Contact one of the organizers if you think require access." } return (forbidden, 403, headers) except Exception as err: app.logger.info("Something happened that shouldn't", stack_info=True) app.logger.info(f'Specific error {err}') app.logger.error(f'Check in error for user {user}') return (internal_server_error, 500, headers) else: return (not_found, 404, headers)