def org_user(user, org_id_slug, user_email): # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) if not org: raise NotFoundError('This Org does not exist.') # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError('You are not allowed to access this Org') # localize localize(org) # get this new user by id / email org_user = fetch_by_id_or_field(User, 'email', user_email) if not org_user: raise RequestError('This user does not yet exist') # check whether this user can view this other user: if not len(list(set(org_user.org_ids).intersection(set(user.org_ids)))): raise ForbiddenError('You are not allowed to view this user.'.format( user.email)) return jsonify(org_user)
def decorated_function(*args, **kw): # get the org org_id = arg_str('org', default=None) if not org_id: raise AuthError('An org is required for this request.') # get the user object. user = kw.get('user') org = fetch_by_id_or_field(Org, 'slug', org_id) # if it still doesn't exist, raise an error. if not org: raise NotFoundError( 'An Org with ID/Slug {} does exist.'.format(org_id)) # otherwise ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError( 'User "{}" is not allowed to access Org "{}".'.format( user.name, org.name)) # check if we should localize this request localize(org) kw['org'] = org return f(*args, **kw)
def org_metrics_summary(user, org_id_slug): # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) # if it still doesn't exist, raise an error. if not org: raise NotFoundError( 'This Org does not exist.') # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError( 'You are not allowed to access this Org') # localize localize(org) req_data = request_data() ret = ingest_metric.org_summary( req_data, org_id=org.id, valid_metrics=org.org_summary_metric_names, commit=True ) return jsonify(ret)
def org_delete(user, org_id_slug): if not user.admin: raise AuthError('You must be an admin to delete an Org') # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) # if it still doesn't exist, raise an error. if not org: raise NotFoundError('This Org does not exist.') # localize localize(org) # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError( 'User "{}" is not allowed to access Org "{}".'.format( user.name, org.name)) db.session.delete(org) db.session.commit() return delete_response()
def login(): """ Login a user and return his/her apikey. """ # parse post body req_data = request_data() email = req_data.get('email') password = req_data.get('password') # check if proper parameters were included if not email or not password: raise AuthError('"email" or "password" not provided.') # check user's existence user = User.query\ .filter_by(email=email)\ .first() if user is None: raise AuthError('A user with email "{}" does not exist.'.format(email)) # check the supplied password if not the super user if password != settings.SUPER_USER_PASSWORD: if not user.check_password(password): raise ForbiddenError('Invalid password.') return jsonify(user.to_dict(incl_apikey=True))
def bulk_create_org_timeseries(user, org_id_slug): # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) # if it still doesn't exist, raise an error. if not org: raise NotFoundError( 'This Org does not exist.') # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError( 'You are not allowed to access this Org') req_data = request_data() job_id = ingest_bulk.org_timeseries( req_data, org_id=org.id, metrics_lookup=org.timeseries_metrics, commit=False ) ret = url_for_job_status(apikey=user.apikey, job_id=job_id, queue='bulk') return jsonify(ret)
def org_add_user(user, org_id_slug, user_email): if not user.admin: raise AuthError('You must be an admin to add a user to an Org.') # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) if not org: raise NotFoundError('This Org does not exist.') # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError('You are not allowed to edit this Org.') # localize localize(org) # get this new user by id / email new_org_user = fetch_by_id_or_field(User, 'email', user_email) if not new_org_user: raise RequestError('User "{}" does not exist'.format(user_email)) # ensure that user is not already a part of this Org. if new_org_user.id in org.user_ids: raise RequestError('User "{}" is already a part of Org "{}"'.format( new_org_user.email, org.name)) org.users.append(new_org_user) db.session.commit() return jsonify(new_org_user)
def org_create(user): req_data = request_data() if not user.super_user: raise ForbiddenError('You must be the super user to create an Org') if 'name' not in req_data \ or 'timezone' not in req_data: raise RequestError("An Org requires a 'name' and 'timezone") org = default.org(name=req_data['name'], timezone=req_data['timezone']) db.session.commit() return jsonify(org)
def get_org_timeseries(user, org_id_slug): # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) # if it still doesn't exist, raise an error. if not org: raise NotFoundError('This Org does not exist.') # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError('You are not allowed to access this Org') kw = request_ts() q = QueryOrgMetricTimeseries(org, [org.id], **kw) return jsonify(list(q.execute()))
def get_org_summary(user, org_id_slug): # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) # if it still doesn't exist, raise an error. if not org: raise NotFoundError('This Org does not exist.') # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError('You are not allowed to access this Org') # localize localize(org) return jsonify(org.summary_metrics)
def org(user, org_id): # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id) # if it still doesn't exist, raise an error. if not org: raise NotFoundError('Org {} does not exist.'.format(org_id)) # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError('You are not allowed to access this Org') # localize localize(org) return jsonify(org.to_dict(incl_domains=True))
def decorated_function(*args, **kw): # if we got an apikey... apikey = arg_str('apikey', default=None) if not apikey: raise AuthError('An apikey is required for this request.') # get the user object. user = User.query\ .filter_by(apikey=apikey)\ .first() # if it doesn't exist, throw an error if not user: raise ForbiddenError('Invalid apikey') kw['user'] = user return f(*args, **kw)
def exec_query(user): """ Only the super user can access the sql api. This is primarily intended for internal recipes which may operate on machines without access to the databse. """ if not user.super_user: raise ForbiddenError("Only the super user can access the SQL API.") if request.method == "POST": q = request_data().get('query', None) if request.method == "GET": q = arg_str('query', default=None) if not q: raise RequestError('A query - "q" is required.') stream = arg_bool('stream', default=True) try: results = db.session.execute(q) except Exception as e: raise RequestError("There was an error executing this query: " "{}".format(e.message)) def generate(): try: for row in ResultIter(results): if stream: yield obj_to_json(row) + "\n" else: yield row except ResourceClosedError: resp = {'success': True} if stream: yield obj_to_json(resp) + "\n" else: yield resp if stream: return Response(stream_with_context(generate())) data = list(generate()) if len(data) == 1: if data[0]['success']: data = data[0] return jsonify(data)
def org_remove_user(user, org_id_slug, user_email): if not user.admin: raise AuthError('You must be an admin to remove a user from an Org.') # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) # if it still doesn't exist, raise an error. if not org: raise NotFoundError('This Org does not exist.') # localize localize(org) # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError("You are not allowed to access this Org.") # get this existing user by id / email existing_user = fetch_by_id_or_field(User, 'email', user_email) if not existing_user: raise RequestError('User "{}" does not yet exist'.format(user_email)) # ensure that user is not already a part of this Org. if existing_user.id not in org.user_ids: raise RequestError('User "{}" is not a part of Org "{}"'.format( existing_user.email, org.name)) # remove the user from the org org.users.remove(existing_user) # if we're force-deleting the user, do so # but make sure their recipes are re-assigned # to the super-user if arg_bool('force', False): cmd = "UPDATE recipes set user_id={} WHERE user_id={}"\ .format(org.super_user.id, existing_user.id) db.session.execute(cmd) db.session.delete(user) db.session.commit() return delete_response()
def org_content(user, org_id_slug): """ Return a simple list of all content items an organization owns. """ # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) # if it still doesn't exist, raise an error. if not org: raise NotFoundError('This Org does not exist.') # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError('You are not allowed to access this Org') # localize localize(org) return jsonify(org.simple_content_items)
def org_users(user, org_id_slug): # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) # if it still doesn't exist, raise an error. if not org: raise NotFoundError('This Org does not exist.') # localize localize(org) # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError( 'User "{}" is not allowed to access Org "{}".'.format( user.email, org.name)) return jsonify(org.users)
def org_create_user(user, org_id_slug): if not user.admin: raise AuthError('You must be an admin to create a user for an Org.') # get the form. req_data = request_data() email = req_data.get('email') password = req_data.get('password') name = req_data.get('name') admin = req_data.get('admin', False) if not all([email, password, name]): raise RequestError( 'An email, password, and name are required to create a User.') # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) # if it still doesn't exist, raise an error. if not org: raise NotFoundError('This Org does not exist.') # localize localize(org) # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError("You are not allowed to access this Org.") if User.query.filter_by(email=email).first(): raise RequestError( 'A User with email "{}" already exists'.format(email)) if not mail.validate(email): raise RequestError('{} is an invalid email address.'.format(email)) new_org_user = User(email=email, password=password, name=name, admin=admin) org.users.append(new_org_user) db.session.commit() return jsonify(new_org_user)
def get_org_timeseries(user, org_id_slug): # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) # if it still doesn't exist, raise an error. if not org: raise NotFoundError( 'This Org does not exist.') # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError( 'You are not allowed to access this Org') # todo: validate which metrics you can select. # select / exclude select, exclude = arg_list( 'select', typ=str, exclusions=True, default=['all']) if 'all' in select: exclude = [] select = "all" kw = dict( unit=arg_str('unit', default='hour'), sparse=arg_bool('sparse', default=True), sig_digits=arg_int('sig_digits', default=2), select=select, exclude=exclude, group_by_id=arg_bool('group_by_id', default=True), rm_nulls=arg_bool('rm_nulls', default=False), time_since_start=arg_bool('time_since_start', default=False), transform=arg_str('transform', default=None), before=arg_date('before', default=None), after=arg_date('after', default=None) ) q = QueryOrgMetricTimeseries(org, [org.id], **kw) return jsonify(list(q.execute()))
def org_update(user, org_id): req_data = request_data() # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id) # if the org doesnt exist, create it. if not org: raise NotFoundError('Org {} does not exist.'.format(org_id)) if user.id not in org.user_ids: raise ForbiddenError("You are not allowed to access this Org.") # localize localize(org) # update the requesting user to the org if 'name' in req_data: org.name = req_data['name'] if 'slug' in req_data: org.slug = req_data['slug'] elif 'name' in req_data: org.slug = slug(req_data['name']) if 'timezone' in req_data: org.timezone = req_data['timezone'] try: db.session.add(org) db.session.commit() except Exception as e: raise RequestError("An error occurred while updating this Org '{}'. " "Here's the error message: {}".format( org.name, e.message)) return jsonify(org)
def create_org_metrics_summary(user, org_id_slug): # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) # if it still doesn't exist, raise an error. if not org: raise NotFoundError('This Org does not exist.') # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError('You are not allowed to access this Org') # localize localize(org) req_data = request_data() ret = load.org_summary(req_data, org_id=org.id, mertrics_lookup=org.summary_metrics, queue=False) return jsonify(ret)
def refresh_org_summary(user, org_id_slug): """ Refresh content summary metrics """ # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) # if it still doesn't exist, raise an error. if not org: raise NotFoundError('This Org does not exist.') # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError('You are not allowed to access this Org') # rollup timeseries => summary rollup_metric.org_summary(org) # compute metrics compute_metric.org_summary(org) # simple response return jsonify({'success': True})
def refresh_org_timeseries(user, org_id_slug): """ Refresh content summary metrics """ # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id_slug) # if it still doesn't exist, raise an error. if not org: raise NotFoundError('This Org does not exist.') # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError('You are not allowed to access this Org') # how many hours since last update should we refresh? since = arg_int('since', 24) # rollup timeseries => summary rollup_metric.org_timeseries(org, [], since) # simple response return jsonify({'success': True})
def update_me(user): """ Update yourself. """ # get the form. req_data = request_data() email = req_data.get('email') old_password = req_data.get('old_password') new_password = req_data.get('new_password') name = req_data.get('name') # edit user. if email: # validate the email address: if not mail.validate(email): raise RequestError( "'{}' is not a valid email address.".format(email)) user.email = email if old_password and new_password: if not user.check_password(old_password): raise ForbiddenError('Invalid password.') user.set_password(new_password) if name: user.name = name # check if we should refresh the apikey if arg_bool('refresh_apikey', False): user.set_apikey() db.session.add(user) db.session.commit() return jsonify(user.to_dict(incl_apikey=True))
def org_add_user(user, org_id, user_email): if not user.admin: raise AuthError('You must be an admin to add a user to an Org.') # fetch org org = fetch_by_id_or_field(Org, 'slug', org_id) if not org: raise NotFoundError('Org {} does not exist.'.format(org_id)) # ensure the active user can edit this Org if user.id not in org.user_ids: raise ForbiddenError('You are not allowed to edit this Org.') # localize localize(org) # get this new user by id / email new_org_user = fetch_by_id_or_field(User, 'email', user_email) # get the form. req_data = request_data() email = req_data.get('email') name = req_data.get('name') admin = req_data.get('admin', False) password = req_data.get('password') if email and not mail.validate(email): raise RequestError('{} is an invalid email address.'.format(email)) # insert if not new_org_user: if not all([email, password, name]): raise RequestError( 'An email, password, and name are required to create a User.') new_org_user = User(email=email, password=password, name=name, admin=admin) org.users.append(new_org_user) db.session.add(org) # ensure the active user can edit this Org elif new_org_user.id not in org.user_ids: raise ForbiddenError("You are not allowed to access this Org.") # update if name: new_org_user.name = name if email: new_org_user.email = email if admin: new_org_user.admin = admin if password: new_org_user.set_password(password) new_org_user.admin = admin db.session.add(new_org_user) db.session.commit() return jsonify(new_org_user)
def org_create(user): req_data = request_data() if not user.super_user: raise ForbiddenError('You must be the super user to create an Org') if 'name' not in req_data \ or 'timezone' not in req_data: raise RequestError("An Org requires a 'name' and 'timezone") org = Org.query\ .filter_by(name=req_data['name'])\ .first() # if the org doesnt exist, create it. if org: raise RequestError("Org '{}' already exists".format(req_data['name'])) # add the requesting user to the org org = Org(name=req_data['name'], timezone=req_data['timezone']) org.users.append(user) db.session.add(org) db.session.commit() # add default tags for tag in load_default_tags(): tag['org_id'] = org.id t = Tag(**tag) db.session.add(t) # add default recipes for recipe in load_default_recipes(): # fetch it's sous chef. sous_chef_slug = recipe.pop('sous_chef') if not sous_chef_slug: raise RecipeSchemaError( "Default recipe '{}' is missing a 'sous_chef' slug.".format( recipe.get('slug', ''))) sc = SousChef.query\ .filter_by(slug=sous_chef_slug)\ .first() if not sc: raise RecipeSchemaError( '"{}" is not a valid SousChef slug or the ' 'SousChef does not yet exist.'.format(sous_chef_slug)) # validate the recipe recipe = recipe_schema.validate(recipe, sc.to_dict()) # fill in relations recipe['user_id'] = user.id recipe['org_id'] = org.id # add to database r = Recipe(sc, **recipe) db.session.add(r) db.session.commit() # if the recipe creates metrics create them here. if 'metrics' in sc.creates: for name, params in sc.metrics.items(): m = Metric(name=name, recipe_id=r.id, org_id=org.id, **params) db.session.add(m) db.session.commit() return jsonify(org)