def workers_status(): """Returns dict of all workers""" try: s = Pyro4.Proxy(RPC_SERVICE).get_workers_status() return eve_response(data=s, status=200) except Exception as e: return eve_response(data={'_error': {'message': str(e)}}, status=200)
def acl_toggle(activity, _id, right, person_id): if person_id != app.globals.get('user_id'): # projection={'acl': 1}, right='read' status, acl, _ = get_acl('{}_observations'.format(activity), _id, projection={ 'acl': 1, 'reporter': 1 }, right='execute') if status is True: if request.method == 'POST': update = modify_user_acl('{}_observations'.format(activity), _id, person_id, right, 'add') elif request.method == 'DELETE': update = modify_user_acl('{}_observations'.format(activity), _id, person_id, right, 'remove') if update is True: return eve_response(True, 201) return eve_response(False, 409)
def acl_activity_roles(activity_id): clubs, _, _, status, _ = get_internal( 'organizations_process', **{ 'type_id': { '$in': [6, 2, 19] }, 'main_activity.id': activity_id }) if status == 200: clubs = list(set([d['id'] for d in clubs['_items']])) resource = 'functions_types_activity_count' datasource = app.config['DOMAIN'][resource]['datasource'] aggregation = datasource.get('aggregation') if aggregation: aggregation['pipeline'][0]['$match']['active_in_org_id'][ '$in'] = clubs functions, _, _, agg_status, _ = _perform_aggregation( resource, aggregation['pipeline'], aggregation['options']) if agg_status == 200: funcs = [{ 'type_id': f['_id'].get('type_id', 0), 'name': f['_id'].get('name', '') } for f in functions['_items']] return eve_response(funcs, status) return eve_response([], status)
def heartbeat(): try: # Mongo check info = int(app.data.driver.db.client.server_info().get('ok', 0)) return eve_response({'_status': True, 'message': {'mongo': info}}, 200) except Exception as e: return eve_response({'_status': False, 'message': {'mongo': 0}}, 500)
def process_kill(pid): p = get_process() if p.pid == int(pid) and p.is_running() and p.status() == 'sleeping': p.kill() return eve_response({'status': True}, 200) return eve_response({'status': False}, 200)
def get_users(collection, _id): status, acl, _ = acl_helper.get_acl(collection, _id) if status is True: res = acl_helper.parse_acl(acl) return eve_response(res) else: return eve_response({})
def acl_clubs(): clubs, _, _, status, _ = get_internal('organizations', **{'type_id': { '$in': [6, 2, 19] }}) if status == 200: return eve_response([d['id'] for d in clubs['_items']]) return eve_response([], status)
def acl_activities_clubs(activity_id): clubs, _, _, status, _ = get_internal( 'organizations_process', **{ 'type_id': { '$in': [6, 2, 19] }, 'main_activity.id': activity_id }) if status == 200: return eve_response(list(set([d['id'] for d in clubs['_items']])), status) return eve_response([], status)
def get_users_flat(collection, _id): status, acl, _ = acl_helper.get_acl(collection, _id) if status is True: res = acl_helper.parse_acl(acl) k = [ p for p in list( set(res['read'] + res['write'] + res['execute'] + res['delete'])) if p != app.globals.get('user_id', 0) ] return eve_response(k) else: return eve_response({})
def message(): try: # ARGS args = request.get_json(force=True) # use force=True to do anyway! event_from = args.get('event_from', None) event_from_id = args.get('event_from_id', None) msg = strip_tags(args.get('message', None)) if event_from is None or event_from_id is None or msg is None: return eve_abort(422, 'Missing parameters') # Can't do if closed or withdrawn status, acl, rest = get_acl(event_from, event_from_id, projection={ 'acl': 1, 'workflow.state': 1, 'id': 1, 'discipline': 1, 'tags': 1 }) if rest.get('workflow', {}).get('state', 'closed') in ['closed', 'withdrawn']: return eve_response_pppd( { 'data': 'Observasjonen er {}'.format( rest.get('workflow', {}).get('state', 'closed')) }, 403, 'Observation is {}'.format( rest.get('workflow', {}).get('state', 'closed'))) k = parse_acl_flat(acl) # If not self too recepients = [x for x in k if x != app.globals.get('user_id', None)] ors_message(recepients=recepients, event_from=event_from, event_from_id=event_from_id, message=msg, ors_id=rest.get('id', None), org_id=rest.get('discipline', None), ors_tags=rest.get('tags', [])) return eve_response(recepients, 200) except Exception as e: app.logger.exception('Error creating message for observation') return eve_response({}, 500)
def acl_roles(): functions, _, _, status, _ = get_internal('functions_types_count') if status == 200: funcs = [{ 'type_id': f['_id'].get('type_id', 0), 'name': f['_id'].get('name', False) } for f in functions['_items']] # funcs = list({v['type_id']: v for v in funcs}.values()) funcs[:] = [d for d in funcs if d.get('name', False) is not False] return eve_response(funcs, status) return eve_response([], status)
def syncdaemon_workers_start(): resp = requests.post('{}/syncdaemon/workers/start'.format(LUNGO_URL), data=None, headers=LUNGO_HEADERS, verify=app.config.get('REQUESTS_VERIFY', True)) return eve_response(resp.json(), resp.status_code)
def audit(observation_id): """ Get audit trail for observation """ wf = ObservationWorkflow(object_id=observation_id, user_id=app.globals.get('user_id')) return eve_response(wf.get_audit(), 200)
def workers_logs(): try: s = Pyro4.Proxy(RPC_SERVICE).get_logs() except: s = [] return eve_response(s, 200)
def state(observation_id): """ Get current state, actions, transitions and permissions """ # No need for user_id, ObservatoinWorkflow already has that! wf = ObservationWorkflow(object_id=observation_id, user_id=app.globals.get('user_id')) return eve_response(wf.get_current_state(), 200)
def get_observation_user_acl(collection, observation_id): ''' This is NOT a good one since jsonifying those objectid's are bad Should rather use Eve for getting stuff! ''' result = acl_helper.get_user_permissions(observation_id, collection) return eve_response(result)
def get_user_acl(username): ''' This is NOT a good one since jsonifying those objectid's are bad Should rather use Eve for getting stuff! ''' col = app.data.driver.db['users'] r = col.find_one({'id': username}, {'acl': 1, 'id': 1}) r['_id'] = str(r['_id']) return eve_response(r)
def get_process(): with open('/home/einar/nif-integration/syncdaemon.pid', 'r') as f: pid = int(f.read().strip()) try: process = psutil.Process(pid) return process except: return eve_response({'status': False}, 200)
def acl_activities_person(person_id): activities = [] status, roles = _acl_from_functions(person_id) if status == 200: for role in roles: activities.append(NLF_ORG[role['activity']]) return eve_response(list(set(activities)), 200)
def get_observations(): """ Get a number of observations which you can execute @todo add max_results from GET """ max_results = request.args.get('max_results', 10, type=int) page = request.args.get('page', 1, type=int) sort_tmp = request.args.get('sort', '_updated', type=str) sort = {} if sort_tmp[0] == '-': sort['field'] = sort_tmp[1:] sort['direction'] = -1 else: sort['field'] = sort_tmp sort['direction'] = 1 col = app.data.driver.db[RESOURCE_COLLECTION] # db.companies.find().skip(NUMBER_OF_ITEMS * (PAGE_NUMBER - 1)).limit(NUMBER_OF_ITEMS ) cursor = col.find({ '$and': [{ 'workflow.state': { '$nin': ['closed', 'withdrawn'] } }, { '$or': [{ 'acl.execute.users': { '$in': [app.globals['user_id']] } }, { 'acl.execute.roles': { '$in': app.globals['acl']['roles'] } }] }] }) total_items = cursor.count() # _items = list(cursor.sort(sort['field'], sort['direction']).skip(max_results * (page - 1)).limit(max_results)) _items = list( cursor.sort('id', 1).skip(max_results * (page - 1)).limit(max_results)) """ #hateos _links = {"self": {"title": "observations/todo", "href": "observations/todo?max_results=%i&page=%i" % (max_results, page), "next": {}, "previous": {}, "last": {}, "first": {}, "parent": {}}} """ _meta = {'page': page, 'max_results': max_results, 'total': total_items} result = {'_items': _items, '_meta': _meta} # return Response(json.dumps(result, default=json_util.default), mimetype='application/json') return eve_response(result, 200)
def met_parse(what, msg): try: if what == 'metar': resp = parse_metar(msg) elif what == 'taf': resp = parse_taf(msg) return eve_response({'decoded': resp, 'msg': msg}, 200) except: return eve_abort(404, 'Could not process')
def acl_toggle(activity, _id, right, person_id): if person_id != app.globals.get('user_id'): # projection={'acl': 1}, right='read' status, acl, ors = acl_helper.get_acl( '{}_observations'.format(activity), _id, projection={ 'acl': 1, 'reporter': 1, 'id': 1, 'discipline': 1, 'tags': 1 }, right='execute') if status is True: if request.method == 'POST': verb = 'tildelte' update = acl_helper.modify_user_acl( '{}_observations'.format(activity), _id, person_id, right, 'add') elif request.method == 'DELETE': verb = 'fjernet' update = acl_helper.modify_user_acl( '{}_observations'.format(activity), _id, person_id, right, 'remove') if update is True: # recepients, event_from, event_from_id, right, verb, ors_acl(recepients=person_id, event_from='{}_observations'.format(activity), event_from_id=_id, right=right, verb='remove' if verb == 'fjernet' else 'add', ors_id=ors.get('id', None), org_id=ors.get('discipline', None), ors_tags=ors.get('tags', [])) return eve_response(True, 201) return eve_response(False, 409)
def met_nearest_metar(icao, date): try: target_time = datetime.datetime.strptime(date, '%Y-%m-%dT%H:%M') status, tafs, metars = get_taf_metar(icao, target_time.strftime('%Y-%m-%d')) metar = get_nearest_metar(metars, target_time) parsed = parse_metar(metar) return eve_response({'metar': metar, 'parsed': '{}'.format(parsed)}, 200) except Exception as e: app.logger.error(e) return eve_abort(404, 'Could not process {}'.format(e))
def lungo_worker_reboot(index): # print('test') # print('{}'.format(request.args)) resp = requests.post('{}/syncdaemon/worker/reboot/{}'.format( LUNGO_URL, index), data=None, headers=LUNGO_HEADERS, verify=app.config.get('REQUESTS_VERIFY', True)) return eve_response(resp.json(), resp.status_code)
def get_user(): """A simple whoami Only return 'I am username'""" try: response, last_modified, etag, status = getitem_internal(resource='users', **{'id': app.globals['id']}) if status == 200 and '_id' in response: return eve_response(data={'iam': response['id']}) except: app.logger.error("Unknown error in get_user") return eve_abort(500, 'Unknown error occurred')
def download(activity, ors_id, version): if has_permission() is True: col = app.data.driver.db['{}_observations'.format(activity)] # db.companies.find().skip(NUMBER_OF_ITEMS * (PAGE_NUMBER - 1)).limit(NUMBER_OF_ITEMS ) cursor = col.find({ '$and': [{ 'id': ors_id }, { '$or': [{ 'reporter': app.globals['user_id'] }, { 'acl.execute.users': { '$in': [app.globals['user_id']] } }, { 'acl.execute.roles': { '$in': app.globals['acl']['roles'] } }] }] }) # _items = list(cursor.sort(sort['field'], sort['direction']).skip(max_results * (page - 1)).limit(max_results)) _items = list(cursor) # Have access! if (len(_items) == 1): try: FILE_WORKING_DIR = '{}/{}/{}/{}'.format( app.config['E5X_WORKING_DIR'], activity, ors_id, version) file_name = 'nlf_{}_{}_v{}.e5x'.format(activity, ors_id, version) app.logger.debug('[E5X DOWNLOAD] {}/{}'.format( FILE_WORKING_DIR, file_name)) # print('####', app.config['static_url_path'] = FILE_WORKING_DIR # with open('{}/{}'.format(FILE_WORKING_DIR, file_name), 'wb') as f: # return send_file('{}/{}'.format(FILE_WORKING_DIR, file_name), as_attachment=True, attachment_filename=file_name, mimetype="'application/octet-stream'") except Exception as e: # print('Download failed', e) app.logger.debug('[E5X DOWNLOAD ERR] {}'.format(e)) app.logger.debug( '[E5X DOWNLOAD ERR] Returned {} items for {} id {} version {}'. format(len(_items), activity, ors_id, version)) return eve_response({'ERR': 'Could not send file'}, 422)
def acl_club_roles(club_id): resource = 'functions_types_org_count' datasource = app.config['DOMAIN'][resource]['datasource'] aggregation = datasource.get('aggregation') print(aggregation) if aggregation: aggregation['pipeline'][0]['$match']['active_in_org_id'] = club_id functions, _, _, status, _ = _perform_aggregation( resource, aggregation['pipeline'], aggregation['options']) if status == 200: funcs = [{ 'type_id': f['_id'].get('type_id', 0), 'name': f['_id'].get('name', '') } for f in functions['_items']] return eve_response(funcs, status) return eve_response([], status)
def publish(content_id): lookup = { '_id': content_id, '$or': [{ "acl.execute.roles": { '$in': app.globals['acl']['roles'] } }, { "acl.execute.users": { '$in': [app.globals.get('user_id')] } }] } acl = { 'read': { 'users': [app.globals.get('user_id')], 'roles': ACL_CLOSED_ALL_LIST if request.method == 'POST' else [] }, 'write': { 'users': [app.globals.get('user_id')], 'roles': [] }, 'execute': { 'users': [app.globals.get('user_id')], 'roles': [] }, 'delete': { 'users': [app.globals.get('user_id')], 'roles': [] } } published = True if request.method == 'POST' else False # response, last_modified, etag, status response, last_modified, etag, status = patch_internal( 'content', { 'acl': acl, 'published': published, 'owner': app.globals.get('user_id') }, False, True, **lookup) print(response, status) if status in [200, 201]: return eve_response(response, status) else: print(response, status) return eve_error_response('Error', 403)
def get_user(): """A simple whoami Only return 'I am username'""" try: response, last_modified, etag, status = getitem_internal( resource='users', **{'id': app.globals['id']}) if status == 200 and '_id' in response: return eve_response(data={'iam': response['id']}) except: app.logger.error("Unknown error in get_user") return eve_abort(500, 'Unknown error occurred')
def acl(person_id): status, function_acl = _acl_from_functions(person_id) if status == 200: function_acl = [{ 'activity': i['activity'], 'org': i['org'], 'role': i['role'], 'type': i['type'] } for i in function_acl] return eve_response(function_acl, 200) return eve_abort(status)
def process_info(): p = get_process() # 'environ' 'memory_info', 'memory_maps','open_files','terminal', d = p.as_dict(attrs=[ 'cmdline', 'connections', 'cpu_affinity', 'cpu_num', 'cpu_percent', 'cpu_times', 'create_time', 'cwd', 'exe', 'gids', 'io_counters', 'ionice', 'memory_full_info', 'memory_percent', 'name', 'nice', 'num_ctx_switches', 'num_threads', 'pid', 'ppid', 'status', 'threads', 'uids', 'username' ]) # Jsonify the dictionary and return it return eve_response(d, 200)
def met_tafmetar(icao, date): try: # print(icao, date) status, taf, metar = get_taf_metar(icao, date) if status is True: return eve_response({'taf': taf, 'metar': metar}, 200) else: # print(get_taf_metar(icao, date)) pass except Exception as e: app.logger.error(e) return eve_abort(500, 'Could not process')
def transition(observation_id, action): """ Perform action on observation reject, approve, reopen, withdraw request.form.get request.args.get ?q=tal @todo: include comment in post! @todo: check permissions here?? """ comment = None try: args = request.get_json() # use force=True to do anyway! comment = args.get('comment', '') except: # Could try form etc pass # Instantiate with observation_id and current user (user is from app.globals.user_id wf = ObservationWorkflow(object_id=observation_id, user_id=app.globals.get('user_id'), comment=comment) # Let draft descide to not process in club if wf.initial_state == 'draft' and action == 'approve': wf.wf_settings['do_not_process_in_club'] = args.get( 'do_not_process_in_club', False) # Let OBSREG descide if not public on close if wf.initial_state == 'pending_review_ors': wf.wf_settings['do_not_publish'] = args.get('do_not_publish', False) # Now just do a if wf.get_resource_mapping().get(action, False): # result = wf.call(get_actions2().get(action)) #getattr(ObservationWorkflow, wf.get_actions2().get(action))() # This is actually safe! result = eval('wf.' + wf.get_resource_mapping().get(action) + '()') # Change owner signal # signal_change_owner.send(app,response=response) return eve_response(wf.state, 200) return eve_abort( 500, 'Error in transitioning observation in workflow for observation id {} and action {}' .format(observation_id, action))
def search_user(): try: err = True result = [] num_results = 0 data = {} message = 'No results' col = app.data.driver.db['melwin_users'] q = request.args.get('q', default='', type=str) max_results = request.args.get('max_results', default=25, type=int) if len(q) > 2: if q.isnumeric(): query = "/^%s.*/.test(this.id)" % q r = col.find({"$where": query}, {"id": 1, "fullname": 1}).limit(max_results) else: regex = re.compile('[^a-zæøåA-ZÆØÅ\s]') query = regex.sub('', q) # re.sub('[^A-Zæøåa-zæøå]+', '', q) r = col.find({"fullname": {"$regex": ".*%s.*" % query, "$options": "i"}}, {"id": 1, "fullname": 1}).limit(max_results) num_results = r.count() # We have a result set! if r and num_results > 0: message = "Found %s results" % num_results err = False for u in r: if 'id' not in u: continue else: result.append({'id': u['id'], 'fullname': u['fullname']}) else: message = "You need at least 3 characters for searching" # Build the result data.update({'_meta': {'err': err, 'total': num_results, 'max_results': max_results, 'message': message}, '_items': result}) return eve_response(data) except: # 406, not acceptable eve_abort(406, 'An error occurred searching for Melwin users')
def get_club_hi(club): groups = app.data.driver.db['acl_groups'] group = groups.find_one({'ref': club}) if group: roles = app.data.driver.db['acl_roles'] role = roles.find_one({'group': group['_id'], 'ref': 'hi'}) if role: users = app.data.driver.db['users'] hi = list(users.find({'acl.roles': {'$in': [role['_id']]}})) r = [] if isinstance(hi, list): for user in hi: r.append(user['id']) else: r.append(hi['id']) return eve_response(r) eve_abort(501, 'Unknown error occurred')
def get_users_by_group(group_id): col = app.data.driver.db['users'] r = col.find({'acl.groups': {'$in': [group_id]}}) return eve_response({'users': r}) # jsonify(**{'users': r})
def delete_group_acl(username, groupid): col = app.data.driver.db['users'] r = col.update({'id': username}, {"$pull": {"acl.groups": ObjectId(groupid)}}) return eve_response(r)
def delete_role_acl(username, roleid): col = app.data.driver.db['users'] r = col.update({'id': username}, {"$pull": {"acl.roles": ObjectId(roleid)}}) return eve_response(r)
def login(): username = None password = None logged_in = False m = Melwin() if m is None: app.logger.critical("Melwin service unavailable") eve_abort('503', 'Melwin service is unavailable') # Request via json rq = request.get_json() try: username = rq['username'] password = rq['password'] except: # Now it will fail in the next if pass if username == 'access_token': try: public_key = _get_public_key() decoded_token = jwt.decode(password, public_key, issuer=ISSUER, algorithm='HS256') logged_in = True username = decoded_token.get('melwin_id', None) if username is None: eve_abort(401, 'Could not validate the token, could not find username') else: # print('Username', username) username = int(username) except jwt.exceptions.InvalidTokenError: logged_in = False eve_abort(401, 'Could not validate the token, InvalidTokenError') except jwt.exceptions.InvalidSignatureError: logged_in = False eve_abort(401, 'Could not validate the token, InvalidSignatureError') except jwt.exceptions.InvalidIssuerError: logged_in = False eve_abort(401, 'Could not validate the token, InvalidIssuerError') except jwt.exceptions.ExpiredSignatureError: logged_in = False eve_abort(401, 'Could not validate the token, ExpiredSignatureError') except Exception as e: logged_in = False eve_abort(401, 'Could not validate your token {}'.format(e)) else: try: username = int(username) logged_in = m.login(username, password) except: logged_in = False eve_abort(503, 'Could not log you into Melwin') # isinstance(username, int) and len(password) == 9 and # Now process user and successful authentication if logged_in is True: try: user, last_modified, etag, status = getitem_internal(resource='users', **{'id': username}) except: user = None if not is_mongo_alive(): eve_abort(502, 'Network problems') # If not existing, make from melwin! if user is None or status != 200: if not create_user(username): app.logger.error("502: Could not create user %i from Melwin" % username) eve_abort(502, 'Could not create user from Melwin') else: app.logger.info("Created user %i" % username) # token = uuid5(uuid4(),rq['username']) token = uuid4().hex # valid = utc.replace(hours=+2) # @bug: utc and cet!!! utc = arrow.utcnow() valid = utc.replace(seconds=+app.config['AUTH_SESSION_LENGHT']) # Pure datetime # valid = datetime.datetime.now() + datetime.timedelta(seconds=60) try: response, last_modified, etag, status = patch_internal('users/auth', payload={'auth': {'token': token, 'valid': valid.datetime}}, concurrency_check=False, **{'id': username}) if status != 200: app.logger.error("Could not insert token for %i" % username) except: app.logger.exception("Could not update user %i auth token" % username) eve_abort(500, "Could not update user %i auth token" % username) t = '%s:' % token b64 = b64encode(t.encode('utf-8')) """return jsonify(**{'success': True, 'token': token, 'token64': b64, 'valid': valid, })""" return eve_response(data={'success': True, 'username': username, 'token': token, 'token64': b64.decode('utf-8'), 'valid': valid.datetime}, status=200) # On error sleep a little against brute force sleep(1) return eve_response({'success': False, 'username': None, 'token': None, 'token64': None, 'valid': None, 'message': 'Wrong username or password'})