def user_add(context, request): ''' if we have a password in our request, create and auth entry for the user as well ''' #do we have valid data pwd = request.json.get('password', None) pwd_less_data = request.json.copy() if pwd is not None: del pwd_less_data['password'] validate_request(context.type_info.schema, request, pwd_less_data) if request.errors: return HTTPUnprocessableEntity(json={'errors': request.errors}, content_type='application/json') # this will create an AuthUser with random password result = collection_add(context, request) if result: email = request.json.get('email') pwd = request.json.get('password', None) if pwd is not None: # now update the password db = request.registry['dbsession'] auth_user = db.query(AuthUser).filter_by(email=email).first() auth_user.password = pwd import transaction transaction.commit() return result
def signup(context, request): """ Create new user. :param request: Pyramid request object """ domain = 'encode.auth0.com' access_token = request.json.get('accessToken') if not access_token: raise HTTPBadRequest(explanation='Access token required') url = 'https://{domain}/userinfo?access_token={access_token}'.format(domain=domain, access_token=access_token) user_data_request = requests.get(url) if user_data_request.status_code != 200: raise HTTPBadRequest(explanation='Could not get user data') user_data = user_data_request.json() if user_data['email_verified'] is not True: raise HTTPBadRequest(explanation='Unverified email') user_info = _get_user_info(user_data) validate_request(context.type_info.schema, request, user_info) if request.errors: raise ValidationError(', '.join(request.errors)) result = collection_add(context, request, user_info) if not result or result['status'] != 'success': raise HTTPInternalServerError(explanation='attempt to create account was not successful') return HTTPCreated(explanation='User created')
def user_add(context, request): ''' if we have a password in our request, create and auth entry for the user as well ''' # do we have valid data pwd = request.json.get('password', None) pwd_less_data = request.json.copy() if pwd is not None: del pwd_less_data['password'] validate_request(context.type_info.schema, request, pwd_less_data) if request.errors: return HTTPUnprocessableEntity(json={'errors': request.errors}, content_type='application/json') result = collection_add(context, request) if result: email = request.json.get('email') pwd = request.json.get('password', None) name = request.json.get('first_name') if pwd is not None: auth_user = AuthUser(email, pwd, name) db = request.registry['dbsession'] db.add(auth_user) transaction.commit() return result
def user_add(context,request): ''' if we have a password in our request, create and auth entry for the user as well ''' #do we have valid data pwd = request.json.get('password', None) pwd_less_data = request.json.copy() if pwd is not None: del pwd_less_data['password'] validate_request(context.type_info.schema, request, pwd_less_data) if request.errors: return HTTPUnprocessableEntity(json={'errors':request.errors}, content_type='application/json') # this will create an AuthUser with random password result = collection_add(context, request) if result: email = request.json.get('email') pwd = request.json.get('password', None) if pwd is not None: # now update the password db = request.registry['dbsession'] auth_user = db.query(AuthUser).filter_by(email=email).first() auth_user.password = pwd import transaction transaction.commit() return result
def create_unauthorized_user(request): """ Endpoint to create an unauthorized user, which will have no lab or award. Requires a reCAPTCHA response, which is propogated from the front end registration form. This is so the endpoint cannot be abused. Given a user properties in the request body, will validate those and also validate the reCAPTCHA response using the reCAPTCHA server. If all checks are succesful, POST a new user Args: request: Request object Returns: dictionary User creation response from collection_add Raises: LoginDenied, HTTPForbidden, or ValidationFailure """ recaptcha_resp = request.json.get('g-recaptcha-response') if not recaptcha_resp: raise LoginDenied() email = request._auth0_authenticated # equal to: jwt_info['email'].lower() user_props = request.json if user_props.get('email') != email: raise HTTPForbidden(title="Provided email %s not validated with Auth0. Try logging in again." % user_props.get('email')) del user_props['g-recaptcha-response'] user_props['was_unauthorized'] = True user_coll = request.registry[COLLECTIONS]['User'] request.remote_user = '******' # permission = import_items # validate the User json validate_request(user_coll.type_info.schema, request, user_props) if request.errors: raise ValidationFailure('body') # use errors from validate_request # validate recaptcha_resp # https://developers.google.com/recaptcha/docs/verify recap_url = 'https://www.google.com/recaptcha/api/siteverify' recap_values = { 'secret': request.registry.settings['g.recaptcha.secret'], 'response': recaptcha_resp } data = urlencode(recap_values).encode() headers = {"Content-Type": "application/x-www-form-urlencoded; charset=utf-8"} recap_res = requests.get(recap_url, params=data, headers=headers).json() if recap_res['success']: sno_res = sno_collection_add(user_coll, request, False) # POST User if sno_res.get('status') == 'success': return sno_res else: raise HTTPForbidden(title="Could not create user. Try logging in again.") else: # error with re-captcha raise HTTPForbidden(title="Invalid reCAPTCHA. Try logging in again.")
def subrequest_item_creation(request: pyramid.request.Request, item_type: str, json_body: dict = None) -> dict: """ Acting as proxy on behalf of request, this creates a new item of the given item_type with attributes per json_body. For example, subrequest_item_creation(request=request, item_type='NobelPrize', json_body={'category': 'peace', 'year': 2016)) Args: request: the request on behalf of which this subrequest is done item_type: the name of the item item type to be created json_body: a python dictionary representing JSON containing data to use in initializing the newly created item Returns: a python dictionary (JSON description) of the item created """ if json_body is None: json_body = {} collection_path = '/' + item_type method = 'POST' # json_utf8 = json.dumps(json_body).encode('utf-8') # Unused, but here just in case check_true(not request.remote_user, "request.remote_user has %s before we set it." % request.remote_user) request.remote_user = '******' subrequest = make_subrequest(request=request, path=collection_path, method=method, json_body=json_body) subrequest.remote_user = '******' subrequest.registry = request.registry # Maybe... # validated = json_body.copy() # subrequest.validated = validated collection: Collection = subrequest.registry[COLLECTIONS][item_type] check_true(subrequest.json_body, "subrequest.json_body is not properly initialized.") check_true(not subrequest.validated, "subrequest was unexpectedly validated already.") check_true(not subrequest.errors, "subrequest.errors already has errors before trying to validate.") check_true(subrequest.remote_user == request.remote_user, "Mismatch: subrequest.remote_user=%r request.remote_user=%r" % (subrequest.remote_user, request.remote_user)) validate_request(schema=collection.type_info.schema, request=subrequest, data=json_body) if not subrequest.validated: return { "@type": ["Exception"], "errors": subrequest.errors } else: json_result: dict = sno_collection_add(context=collection, request=subrequest, render=False) return json_result
def create_and_commit(cls, request, properties, clean_headers=False): """ Create a TrackingItem with a given request and properties, committing it directly to the DB. This works by manually committing the transaction, which may cause issues if this function is called as part of another POST. For this reason, this function should be used to track GET requests -- otherwise, use the standard POST method. If validator issues are hit, will not create the item but log to error Args: request: current request object properties (dict): TrackingItem properties to post clean_headers(bool): If True, remove 'Location' header created by POST Returns: dict response from snovault.crud_views.collection_add Raises: ValidationFailure if TrackingItem cannot be validated """ collection = request.registry[COLLECTIONS]['TrackingItem'] # set remote_user to standarize permissions prior_remote = request.remote_user request.remote_user = '******' # remove any missing attributes from DownloadTracking properties['download_tracking'] = { k: v for k, v in properties.get('download_tracking', {}).items() if v is not None } validate_request(collection.type_info.schema, request, properties) if request.errors: # added from validate_request request.remote_user = prior_remote raise ValidationFailure('body', 'TrackingItem: create_and_commit', 'Cannot validate request') ti_res = sno_collection_add(collection, request, False) # render=False transaction.get().commit() if clean_headers and 'Location' in request.response.headers: del request.response.headers['Location'] request.remote_user = prior_remote return ti_res
def create_and_commit(cls, request, properties, clean_headers=False): """ Create a TrackingItem with a given request and properties, committing it directly to the DB. This works by manually committing the transaction, which may cause issues if this function is called as part of another POST. For this reason, this function should be used to track GET requests -- otherwise, use the standard POST method. If validator issues are hit, will not create the item but log to error Args: request: current request object properties (dict): TrackingItem properties to post clean_headers(bool): If True, remove 'Location' header created by POST Returns: dict response from snovault.crud_views.collection_add Raises: ValidationFailure if TrackingItem cannot be validated """ import transaction collection = request.registry[COLLECTIONS]['TrackingItem'] # set remote_user to standarize permissions prior_remote = request.remote_user request.remote_user = '******' # remove any missing attributes from DownloadTracking properties['download_tracking'] = {k: v for k, v in properties.get('download_tracking', {}).items() if v is not None} validate_request(collection.type_info.schema, request, properties) if request.errors: # from validate_request request.remote_user = prior_remote raise ValidationFailure('body') # use errors from validate_request ti_res = sno_collection_add(collection, request, False) # render=False transaction.get().commit() if clean_headers and 'Location' in request.response.headers: del request.response.headers['Location'] request.remote_user = prior_remote return ti_res
def _validate_set_status_patch(request, schema, new_properties, current_properties): validate_request(schema, request, new_properties, current_properties) if any(request.errors): raise ValidationFailure(request.errors)
def create_unauthorized_user(context, request): """ Endpoint to create an unauthorized user, which will have no institution/project. Requires a reCAPTCHA response, which is propogated from the front end registration form. This is so the endpoint cannot be abused. Given a user properties in the request body, will validate those and also validate the reCAPTCHA response using the reCAPTCHA server. If all checks are succesful, POST a new user Args: request: Request object Returns: dictionary User creation response from collection_add Raises: LoginDenied, HTTPForbidden, or ValidationFailure """ recaptcha_resp = request.json.get('g-recaptcha-response') if not recaptcha_resp: raise LoginDenied() email = request._auth0_authenticated # equal to: jwt_info['email'].lower() user_props = request.json user_props_email = user_props.get("email", "<no e-mail supplied>").lower() if user_props_email != email: raise HTTPUnauthorized( title= "Provided email {} not validated with Auth0. Try logging in again." .format(user_props_email), headers={ 'WWW-Authenticate': "Bearer realm=\"{}\"; Basic realm=\"{}\"".format( request.domain, request.domain) }) del user_props['g-recaptcha-response'] user_props['was_unauthorized'] = True user_props['email'] = user_props_email # lowercased user_coll = request.registry[COLLECTIONS]['User'] request.remote_user = '******' # permission = restricted_fields # validate the User json validate_request(user_coll.type_info.schema, request, user_props) if request.errors: raise ValidationFailure('body', 'create_unauthorized_user', 'Cannot validate request') # validate recaptcha_resp # https://developers.google.com/recaptcha/docs/verify recap_url = 'https://www.google.com/recaptcha/api/siteverify' recap_values = { 'secret': request.registry.settings['g.recaptcha.secret'], 'response': recaptcha_resp } data = urlencode(recap_values).encode() headers = { "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" } recap_res = requests.get(recap_url, params=data, headers=headers).json() if recap_res['success']: sno_res = sno_collection_add(user_coll, request, False) # POST User if sno_res.get('status') == 'success': return sno_res else: raise HTTPForbidden( title="Could not create user. Try logging in again.") else: # error with re-captcha raise HTTPUnauthorized( title="Invalid reCAPTCHA. Try logging in again.", headers={ 'WWW-Authenticate': "Bearer realm=\"{}\"; Basic realm=\"{}\"".format( request.domain, request.domain) })