def login(self, username, password): """ Validating username and password for login. """ db = self.client.pycaptive.Users ts = datetime.now() try: hash_pass = db.find_one({"UserName": username}, { "Password": 1, "_id": 0 }) self.client.close() if hash_pass is not None: db_hash = hash_pass["Password"] new_hash = bcrypt.hashpw(password.encode("utf-8"), db_hash) if db_hash == new_hash: log.info('%s %s %s %s', "mongodb", "login", "OK", username) return 0 else: log.error('%s %s %s %s %s', "mongodb", "login", "NOK", username, "WRONG_PASS") return 2 else: log.error('%s %s %s %s %s', "mongodb", "login", "NOK", username, "NOT_FOUND") return 1 except Exception as e: log.critical('%s %s %s %s', "mongodb", "login", "EXCEPTION", username) log.critical('%s', e) return e
def add(id=-1): if id > -1: user = User.query.get_or_404(int(id)) form = AddForm(obj=user) else: form = AddForm() #Validate on the second pass only (when button 'Bewaar' is pushed) if 'button' in request.form and request.form[ 'button'] == 'Bewaar' and form.validate_on_submit(): user = User( email=form.email.data, username=form.username.data, first_name=form.first_name.data, last_name=form.last_name.data, password=form.password.data, level=form.level.data, ) db.session.add(user) db.session.commit() log.info('add : {}'.format(user.log())) #flash('You have added user {}'.format(user.username)) return redirect(url_for('management.user.users')) return render_template('management/user/user.html', form=form, title='Add a user', role='add', subject='management.user')
def pop(self, id): ''' Removes the record identified by id from the dataset. Returns the data (if found) or None. ''' if(not self.db_exists): return None url = self.url + '/' + self.db_name + '/' + id # first get it from the DB resp = self.ses.get(url) log.debug('ses.get(%s) => %d', url, resp.status_code) if(resp.status_code != 200): return None res = resp.json() del res['_id'] rev = res.pop('_rev', None) if rev is None: return None # now let's delete it! url = url + '?rev=' + rev resp = self.ses.delete(url) log.debug('ses.delete(%s) => %d', url, resp.status_code) log.info('pop(%s) => %s', id, str(res)) return res
def expire_sessions(self): """ Expires sessions. """ db = self.client.pycaptive.Sessions time_now = datetime.now() expired_sessions = [] try: sessions = db.find().distinct("ExpireTime") for session in sessions: data = db.find_one({"ExpireTime": session}, { "IpAddress": 1, "UserName": 1, "_id": 0 }) ip = data["IpAddress"] if session < time_now: db.delete_one({"ExpireTime": session}) expired_sessions.append(ip) log.info('%s %s %s %s', "mongodb", "expire_sessions", "OK", data) self.client.close() return expired_sessions except Exception as e: log.critical('%s %s %s', "mongodb", "expire_sessions", "EXCEPTION") log.critical('%s', e) return e
def del_conntrack(self, ip): """ Destroys established connections from conntrack table for a specified IP address. This action is complementary to del_rules() method, in order to insure that no connection is persisting between a PyCaptive client and a remote IP address. See del_rules() for more info. Parameters ---------- ip : string IP address provided via del_rules() method. Returns ------- integer if 0: rule successfully deleted else: error while processing command """ destroy_conn = [CONNTRACK, "-D", "--orig-src", ip] result = sp.call(destroy_conn, stderr=sp.DEVNULL, stdout=sp.DEVNULL) if result == 0: log.info('%s %s %s %s', "iptables", "del_conntrack", "OK", ip) else: log.error('%s %s %s %s', "iptables", "del_conntrack", "NOK", ip) return result
def close_storage(self): """закрытие текущего хранилища""" log.info("закрытие текущего хранилища: {}".format(self.storage_path)) # TODO: очистить все вложенные элементы self.s_closed.emit()
def closeEvent(self, QCloseEvent): """перехват зактытия окна - предварительные завершения для объектов""" log.info("закрытие приложения - останавливаем процессы") log.info("закрытие приложения - выходим") QCloseEvent.accept()
def getWorkoutsChangedSince(athlete_id, sinceDate): valid_token = oauth.getValidAuthToken() headers = getAPIRequestHeaders(valid_token) base_url = urls.WORKOUTS_CHANGED_SINCE(athlete_id, sinceDate) params = dict() params['includeDescription'] = True params['pageSize'] = PAGE_SIZE params['page'] = 0 full_response = {'Deleted': [], 'Modified': []} while True: response = requests.get(base_url, headers=headers, params=params) if response.status_code == 200: try: response_json = response.json() full_response['Deleted'] = full_response[ 'Deleted'] + response_json['Deleted'] full_response['Modified'] = full_response[ 'Modified'] + response_json['Modified'] except Exception: print('Error while parsing workouts changed response') if len(response_json['Modified']) < PAGE_SIZE: break else: params['page'] += 1 else: log.info( 'NOTE: athlete with id {} does not have a TP premium account. We should deactivate this athlete.' .format(athlete_id)) break return full_response
def add(template=None): logging_prefix = logger_prefix + "add({}) - ".format(template) log.info(logging_prefix + "Starting") error = None try: populate_simple_choices() form = forms.actorForm(request.form) search_form = forms.searchForm() if request.method == 'POST': #trick the form validation into working with our dynamic drop downs for sub_form in form.actor_class: sub_form.a_id.choices = fetch_child_data('tpx_classification',sub_form.a_family.data) #convert the field that lists the related_element_choices #choices = [] #rec = json.loads(form.related_element_choices.data) #for k,v in rec.items(): # choices.append((v,k)) if form.validate(): log.info(logging_prefix + "Add Detected") #create an actor id actor_id = str(uuid.uuid4()) #convert the form to ES format form_to_es(form, actor_id) #rebuild the form from ES #flash('Not requerying ES, this should change', 'warning') form, editors = es_to_form(actor_id) flash(Markup('<a href="/actor/view/'+actor_id+'" style="text-decoration:none; color:#3c763d;">New Actor Successfully Added. Click here to view this actor</a>') , "success") #return redirect("/add/{}/".format(actor_id), code=302) else: #if there was an error print the error dictionary to the console # temporary help, these should also appear under the form field print(form.errors) elif template: form, editors = es_to_form(template) else: #populate certain fields with default data form.actor_class[0].a_family.data = 'Actors' form.actor_class[0].a_id.choices = fetch_child_data('tpx_classification','Actors') except Exception as e: error = "There was an error completing your request. Details: {}".format(e) flash(error,'danger') log.exception(logging_prefix + error) return render_template("actor.html", page_title="Add New Actor", role="ADD", form=form, search_form = search_form )
def index(): events = Event.query.all() # 37.62, 55.75 user = User.query.filter_by(username=current_user.username).first_or_404() user_dir = user.username + user.timestamp user_folders = os.path.join('app', 'static', 'user_data', user_dir) if not os.path.isdir(user_folders): log.info("User '%s' register." % (user.username)) os.mkdir(user_folders) os.mkdir(os.path.join(user_folders, 'photos')) os.mkdir(os.path.join(user_folders, 'tracking_data')) copydir(os.path.join('app', 'static', 'user_data', 'avatar'), user_folders) remote_addr = request.remote_addr or 'untrackable' old_current_login, new_current_login = user.current_login_at, datetime.utcnow( ) old_current_ip, new_current_ip = user.current_login_ip, remote_addr user.last_login_at = old_current_login or new_current_login user.current_login_at = new_current_login user.last_login_ip = old_current_ip or new_current_ip user.current_login_ip = new_current_ip user.login_count = user.login_count + 1 if user.login_count else 1 db.session.commit() log.info("User '%s' login with ip '%s'." % (user.username, user.current_login_ip)) return render_template('index.html', user=user, events=events)
def view(actor_id): logging_prefix = logger_prefix + "view({}) - ".format(actor_id) log.info(logging_prefix + "Starting") editors = None try: populate_simple_choices() form, editors = es_to_form(actor_id) search_form = forms.searchForm() except Exception as e: error = "There was an error completing your request. Details: {}".format(e) flash(error,'danger') log.exception(logging_prefix + error) form = forms.actorForm() #render the template, passing the variables we need # templates live in the templates folder return render_template("actor.html", page_title="View Actor", role="VIEW", actor_id=actor_id, form=form, editors=editors, search_form = search_form )
def populate_related_elements(_type): logging_prefix = logger_prefix + "populate_related_elements({}) - ".format( _type) log.info(logging_prefix + "Starting") r = fetch_related_elements(_type) return jsonify(r), 200
def register(): if current_user.is_authenticated: return redirect(url_for('index')) form = RegistrationForm() if form.validate_on_submit(): user = User( username=form.username.data, email=form.email.data, city=form.city.data ) user.set_password(form.password.data) log.debug("user before: %s", user) try: db.session.add(user) db.session.commit() log.debug("user after: %s", user) new_user = User.query.filter(User.username == form.username.data).first() user_dir = new_user.username + new_user.timestamp user_folders = os.path.join('app', 'static', 'user_data', user_dir) if not os.path.isdir(user_folders): os.mkdir(user_folders) os.mkdir(os.path.join(user_folders, 'photos')) os.mkdir(os.path.join(user_folders, 'tracking_data')) copydir(os.path.join('app', 'static', 'user_data', 'avatar'), user_folders) flash('Congratulations, you are now a registered user!') log.debug("user after make folder: %s", user) log.info("User '%s' register." % (user.username)) return redirect(url_for('login')) except: flash('Something wrong') log.info("User '%s' can not register." % (user.username)) return redirect(url_for('register')) return render_template('register.html', title='Register', form=form)
def get_rfids(): try: url = msettings.get_configuration_setting('papercut-server-url') port = msettings.get_configuration_setting('papercut-server-port') token = msettings.get_configuration_setting('papercut-auth-token') nbr_updated_rfid = 0 nbr_user_not_found = 0 with xmlrpc.client.ServerProxy( f'http://{url}:{port}/rpc/api/xmlrpc') as server: persons = mperson.get_persons(enabled=True, active=True) for person in persons: try: property = server.api.getUserProperty( token, person.ad_user_name, PROPERTY_RFID) if person.rfid_code != property.upper(): person.rfid_code = property.upper() nbr_updated_rfid += 1 except Exception as e: nbr_user_not_found += 1 log.info( f'get person rfid: person not found: {person.ad_user_name}, error: {e}' ) mperson.end_update_bulk_person() log.info( f'get rfids from papercut: nbr-persons/nbr-updated/nbr-not-found {len(persons)}/{nbr_updated_rfid}/{nbr_user_not_found}' ) return { 'status': True, 'message': f'RFIDs from papercut\nnbr: {len(persons)}\nupdated {nbr_updated_rfid}\nnot found {nbr_user_not_found}' } except Exception as e: log.error('get rfids: error {e}') return {'status': False, 'message': f'{e}'}
def add_rule(self, ip): """ Allowing Internet access to an IP address Parameters ---------- ip : string IP address provided via client request to PyCaptive. Returns ------- integer if 0: rule successfully deleted else: error while processing command """ rule = [ IPTABLES, "-t", TABLE, "-I", CHAIN, "-i", LAN, "-s", ip, "-m", "comment", "--comment", COMMENT, "-j", JUMP ] try: result = sp.call(rule) if result == 0: log.info('%s %s %s %s', "iptables", "add_rule", "OK", ip) else: log.error('%s %s %s %s', "iptables", "add_rule", "NOK", ip) return result except Exception as e: log.critical('%s %s %s %s', "iptables", "add_rule", "EXCEPTION", ip) log.critical('%s', e) return e
def edit_favorite_thing(user_id, favorite_id): try: title = request.json.get("title") description = request.json.get("description") ranking = request.json.get("ranking") meta_data = request.json.get("meta_data") category = request.json.get("category") log.info(f"Editing new favorite thing:{favorite_id} for user:{user_id}") updates = { "title": title, "description": description, "ranking": ranking, "category": category, "meta_data": meta_data } filtered = {k: v for k, v in updates.items() if v is not None} updates.clear() updates.update(filtered) log.debug("Got item to update:{}".format(updates)) favorite = core.update_favorite_thing(user_id, favorite_id, updates) resp = Response(json.dumps({"favorite": favorite}, default=str), status=200, mimetype='application/json') except Exception as ex: log.exception(ex) resp = Response(json.dumps(getattr(ex, "args", ex)), status=400, mimetype='application/json') return resp
def view(report_id): logging_prefix = logger_prefix + "view({}) - ".format(report_id) log.info(logging_prefix + "Starting") editors = None try: form, editors = es_to_form(report_id) search_form = forms.searchForm() except Exception as e: error = "There was an error completing your request. Details: {}".format(e) flash(error, "danger") log.exception(logging_prefix + error) form = forms.reportForm() # render the template, passing the variables we need # templates live in the templates folder return render_template( "report.html", page_title="View Report", role="VIEW", report_id=report_id, form=form, editors=editors, search_form=search_form, )
def post(self): try: args = parser.parse_args() pass_md5 = hashlib.md5( args['password'].encode('utf-8')).hexdigest() user = User.query.filter(User.login == args['login'], User.password == pass_md5).one_or_none() if user is None: log.info("Invalid login/password") return { 'state': 'fail', 'message': 'No such user or password invalid' } new_token = Token(token=str(uuid.uuid4()), user_id=user.id, device=args['device']) if args['expires'] is not None: new_token.expires_at = datetime.fromtimestamp(args['expires'] / 1000.0) db.session.add(new_token) db.session.commit() log.info("Created new token: %s" % new_token.token) return {'token': new_token.token} except Exception as e: db.session.rollback() log.exception(e) return {'state': 'fail', 'message': str(e)}, 500
def send_email_with_link_to_subscribe_for_contactmoment(**kwargs): ret = False if 'org' in kwargs: organization = kwargs['org'] invite_template_key = '_'.join( [organization, 'template_invite_contactmoment']) enable_invite_key = '_'.join( [organization, 'send_invite_contactmoment_email']) if not int( Setting.query.filter( Setting.key == enable_invite_key).first().value): return False invite = Invite.query.filter( Invite.active == True, Invite.enable == True, Invite.organization == organization, Invite.contactmoment_sent == False).first() if not invite: return False template = Setting.query.filter( Setting.key == invite_template_key).first().value email_subject, _, email_body, _ = extract_subject_and_content(template) base_url = Setting.query.filter( Setting.key == 'base_url').first().value link = base_url + '/' + 'subscribe' + '/' + organization + '/' + invite.token email_info = { 'body': email_body.replace('TAG_LINK_URL', link), 'subject': email_subject, 'to': invite.email, } log.info(f'"{email_subject}" to {invite.email}') ret = send_email(organization, email_info) if ret: invite.contactmoment_sent = True db.session.commit() return ret
def preprocess(self, session, *args, **kwargs): # validate username/password present in context validate_keys(self.local_context, [ CSES_USERNAME_YAML_NAME, CSES_PASSWORD_YAML_NAME], to_prompt=True) # log in response = http_get( session, CSES_LOGIN_URL, self.headers, True) # extract csrf token content = parse(response.text) csrfToken = content.find( "input", attrs={"name": CSES_CSRF_TOKEN_FORM_NAME})["value"] # create payload payload = { CSES_USERNAME_FORM_NAME: self.local_context[CSES_USERNAME_YAML_NAME], CSES_PASSWORD_FORM_NAME: self.local_context[CSES_PASSWORD_YAML_NAME], CSES_CSRF_TOKEN_FORM_NAME: csrfToken, } # post response = http_post( session, CSES_LOGIN_URL, payload, self.headers) # verify login successful assert self.local_context[CSES_USERNAME_YAML_NAME] in response.text log.info("Successfully logged in.") # get user id from response post_login_content = parse(response.text) self.user_id = post_login_content.find( "a", attrs={"class": CSES_ACCOUNT_ANCHOR_CLASS})["href"]
def signal_handler(signum, frame): """обработчик сигнала завершения от системы""" log.info("перехвачен сигнал SIGINT(Ctrl+C)") log.info("запрос на выход из cmd") # self.stop() sys.exit(0)
def user_delete(user_id, user_id_hash): logging_prefix = logger_prefix + "user_delete({},{}) - ".format(user_id, user_id_hash) log.info(logging_prefix + "Starting") redirect_url = "/admin/" try: redirect_url = request.args.get("_r") if not redirect_url: log.warning(logging_prefix + "redirect_url not set, using default") redirect_url = "/admin/" #check user_id against user_id_hash and perform delete if match if user_id_hash == sha256( SALTS['user'], user_id ): #now delete the user conn=get_mysql().cursor(DictCursor) conn.execute("DELETE FROM users WHERE id=%s", (user_id,)) conn.close() flash("The user has been deleted", "success") else: flash("Unable to delete user", "danger") except Exception as e: error = "There was an error completing your request. Details: {}".format(e) flash(error,'danger') log.exception(logging_prefix + error) return redirect(redirect_url)
def insertWorkoutsIntoDb(start_date, end_date): """ Inserts all workouts from start_date to end_date into workout table Args: start_date (datetime): Start Datetime object end_date (datetime): End Datetime object Returns: int: number of workouts inserted into the database """ athletes = db_functions.dbSelect(sql.getAllActiveAthletesSQL()) datesList = getListOfStartEndDates(start_date, end_date, MAX_DAYS) workoutsList = list() for athlete in athletes: athlete_num_workouts = 0 for date_period in datesList: currWorkouts = api_service.getDBWorkoutsUsingAPI( athlete.id, date_period) workoutsList += currWorkouts athlete_num_workouts += len(currWorkouts) log.info("{} workouts found for {} from {} to {}".format( athlete_num_workouts, athlete['name'], start_date, end_date)) log.info("Wrong num HR zones: {}".format( InvalidZoneAthletes.wrongNumHrZones)) log.info("Wrong num power zones: {}".format( InvalidZoneAthletes.wrongNumPowerZones)) log.info("Reverse HR zones: {}".format(InvalidZoneAthletes.reverseHrZones)) log.info("Reverse Power zones: {}".format( InvalidZoneAthletes.reversePowerZones)) db_functions.dbInsert(workoutsList) return len(workoutsList)
def send_ack_message(**kwargs): try: registration = mregistration.get_first_registration(ack_sent=False, enabled=True) if registration: message_send_max_retries = msettings.get_configuration_setting('message-send-max-retries') if registration.ack_send_retry >= message_send_max_retries: mregistration.set_enabled(registration, False) return mregistration.update_registration(registration, ack_send_retry=registration.ack_send_retry + 1) flat = registration.ret_flat() data = json.loads(flat['data']) to_id = registration.student_id to_nbr_coaccount = data['nbr_coaccount'] timeslot = registration.timeslot.ret_formio() timeslot_string = mutils.datetime_to_dutch_datetime_string(timeslot['timeslot-date']) url = timeslot['timeslot-meeting-url'] message_subject = msettings.get_configuration_setting('register-message-ack-subject-template') message_content = msettings.get_configuration_setting('register-message-ack-content-template') message_subject = message_subject.replace('{{TAG-TIMESLOT}}', timeslot_string) message_content = message_content.replace('{{TAG-TIMESLOT}}', timeslot_string) message_content = message_content.replace('{{TAG-MEETING-URL}}', f'<a href="{url}" target="_blank">deze link</a>') log.info(f'{message_subject} to {to_id}/{to_nbr_coaccount}') ret = msmartschool.send_message(to_id, to_nbr_coaccount, message_subject, message_content) if ret: mregistration.set_ack_sent(registration, True) return ret return False except Exception as e: log.error(f'Could not send message {e}') return False
def edit_info(slug): photo = Photo.query.filter(Photo.id == slug).first() form = PhotoForm(formdata=request.form, obj=photo) if form.validate_on_submit(): photo.photo_title = form.photo_title.data photo.photo_description = form.photo_description.data try: photo.tags.append(Tag.query.filter_by(name=form.tags.data).first()) log.debug("Photo before db '%s'." % (photo)) db.session.commit() flash('Your photo edited') photo = Photo.query.filter(Photo.id == slug).first() log.debug("Photo after db '%s'." % (photo)) tags = photo.tags log.info("User '%s' edit photo info '%s'." % (current_user.username, photo.photo_title)) return render_template('photos/photo_detail.html', photo=photo, tags=tags, user=current_user) except: redirect('photos.index') form = PhotoForm(obj=photo) return render_template('photos/edit_info.html', form=form)
def main(): logging_prefix = logger_prefix + "main() - " log.info(logging_prefix + "Starting") try: conn=get_mysql().cursor(DictCursor) conn.execute("SELECT id, name, email, company, justification, email_verified, approved, write_permission, delete_permission, admin, created, last_login FROM users ORDER BY created DESC") users = conn.fetchall() for user in users: user['id_hash'] = sha256( SALTS['user'], str(user['id']) ) conn.close() email_user_form = forms.sendUserEmailForm() except Exception as e: error = "There was an error completing your request. Details: {}".format(e) flash(error,'danger') log.exception(logging_prefix + error) return render_template("admin.html", page_title="Admin", url = "/admin/", users=users, email_user_form = email_user_form )
def password_reset(user_id=None, expiration_ts=None, password_reset_hash=None): logging_prefix = logger_prefix + "password_reset({},{},{}) - ".format(user_id, expiration_ts, password_reset_hash) log.info(logging_prefix + "Starting") try: if sha256(SALTS['user'],user_id+expiration_ts) != password_reset_hash: flash("There was an error completing your request", 'danger') return redirect("/user/password/request_reset/") form = forms.passwordPerformResetForm(request.form) search_form = forms.searchForm() now = int(time.time()) if now > int(expiration_ts): # passworD1! flash("This link has expired", 'danger') return redirect("/user/password/request_reset/") conn=get_mysql().cursor(DictCursor) conn.execute("SELECT COUNT(*) as count FROM password_reset_hashes WHERE hash = %s AND user_id = %s", (password_reset_hash,user_id)) result = conn.fetchone() conn.close() if not result: flash("This link has expired", 'danger') return redirect("/user/password/request_reset/") if result['count'] == 0: flash("This link has expired", 'danger') return redirect("/user/password/request_reset/") if request.method == 'POST': if form.validate(): password = form.user_password.data salted_password = sha256(SALTS['user'],password) conn=get_mysql().cursor() conn.execute("UPDATE users SET password = %s WHERE id = %s", (salted_password,user_id)) conn.execute("DELETE FROM password_reset_hashes WHERE user_id = %s", (user_id,)) get_mysql().commit() conn.close() flash("Your password has been updated", "success") return redirect("/user/login") else: print(form.errors) except Exception as e: error = "There was an error completing your request. Details: {}".format(e) flash(error,'danger') log.exception(logging_prefix + error) log.info(logging_prefix + "Rendering") return render_template("password_reset.html", page_title="Reset Your Password", page_type="PERFORM", form=form, search_form=search_form )
def add(template=None): logging_prefix = logger_prefix + "add({}) - ".format(template) log.info(logging_prefix + "Starting") error = None try: form = forms.reportForm(request.form) search_form = forms.searchForm() if request.method == "POST": # trick the form validation into working with our dynamic drop downs for sub_form in form.report_class: sub_form.a_id.choices = fetch_child_data("tpx_classification", sub_form.a_family.data) # convert the field that lists the related_element_choices # choices = [] # rec = json.loads(form.related_element_choices.data) # for k,v in rec.items(): # choices.append((v,k)) if form.validate(): log.info(logging_prefix + "Add Detected") # create a ttp id report_id = str(uuid.uuid4()) # convert the form to ES format form_to_es(form, report_id) # rebuild the form from ES form, editors = es_to_form(report_id) flash( Markup( '<a href="/report/view/' + report_id + '" style="text-decoration:none; color:#3c763d;">New Report Successfully Added. Click here to view this Report</a>' ), "success", ) else: # if there was an error print the error dictionary to the console # temporary help, these should also appear under the form field print(form.errors) elif template: form, editors = es_to_form(template) else: # populate certain fields with default data form.report_class[0].a_family.data = "Actors" form.report_class[0].a_id.choices = fetch_child_data("tpx_classification", "Actors") except Exception as e: error = "There was an error completing your request. Details: {}".format(e) flash(error, "danger") log.exception(logging_prefix + error) form = forms.reportForm() return render_template("report.html", page_title="Add New Report", role="ADD", form=form, search_form=search_form)
def up3_to_4(connection): log.info("миграция 3 -> 4") cursor = connection.cursor() cursor.execute(sql.CREATE_FILES_INDEX_UUID) # создание индекса files uuid cursor.execute( sql.CREATE_FILES_INDEX_PARENT_ID) # создание индекса files parent_id
def add_default_values_if_empty(): for school, topics in MeasureTopic.default_topics: find_topics = MeasureTopic.query.filter(school == school).all() if not find_topics: log.info('MeasureTopic table is empty, adding default values') for t in topics: db.session.add(MeasureTopic(topic=t, school=school)) db.session.commit()
def run(self): log.info("starting scan") self.__event_start() self.tree.set_empty() self.__scan() # self.__make_tree() self.__event_finish()
def PreExit(self): msg = 'GriPy Application is preparing to terminate....' log.info(msg) OM = ObjectManager() UIM = UIManager() UIM.PreExit() OM._reset()
def edit(report_id): logging_prefix = logger_prefix + "edit({}) - ".format(report_id) log.info(logging_prefix + "Starting") error = None try: search_form = forms.searchForm() editors = None if request.method == "POST": form = forms.reportForm(request.form) # trick the form validation into working with our dynamic drop downs for sub_form in form.report_class: sub_form.a_id.choices = fetch_child_data("tpx_classification", sub_form.a_family.data) # convert the field that lists the related_element_choices # choices = [] # rec = json.loads(form.related_element_choices.data) # for k,v in rec.items(): # choices.append((v,k)) if form.validate(): log.info(logging_prefix + "Edit Detected") # convert the form to ES format form_to_es(form, report_id) # rebuild the form from ES form, editors = es_to_form(report_id) flash("Report Update Successful!", "success") else: # if there was an error print the error dictionary to the console # temporary help, these should also appear under the form field print(form.errors) else: form, editors = es_to_form(report_id) except Exception as e: error = "There was an error completing your request. Details: {}".format(e) flash(error, "danger") log.exception(logging_prefix + error) form = forms.reportForm() # render the template, passing the variables we need # templates live in the templates folder return render_template( "report.html", page_title="Edit Report", role="EDIT", report_id=report_id, form=form, editors=editors, search_form=search_form, )
def export(report_id): logging_prefix = logger_prefix + "export({}) - ".format(report_id) log.info(logging_prefix + "Starting") try: tpx = es_to_tpx(report_id) except Exception as e: error = "There was an error completing your request. Details: {}".format(e) log.exception(logging_prefix + error) tpx = {"error": error} return jsonify(tpx), 500 return jsonify(tpx), 200
def password_request_reset(): logging_prefix = logger_prefix + "password_request_reset() - " log.info(logging_prefix + "Starting") try: form = forms.userEmailForm(request.form) search_form = forms.searchForm() if request.method == 'POST': if form.validate(): email = form.user_email.data #make sure the email exists in the system conn=get_mysql().cursor(DictCursor) conn.execute("SELECT id FROM users WHERE email = %s", (email,)) user = conn.fetchone() conn.close() if user: expiration_ts = int(time.time()) + 3600 password_reset_hash = sha256(SALTS['user'],str(user['id']) + str(expiration_ts)) #set this value in the database, so it can be expired after the password is changed conn=get_mysql().cursor(DictCursor) conn.execute("INSERT INTO password_reset_hashes (user_id,hash) VALUES (%s,%s)", (user['id'],password_reset_hash)) get_mysql().commit() conn.close() password_reset_link = "/user/password/reset/{}/{}/{}/".format(user['id'],expiration_ts,password_reset_hash) sendPasswordResetEmail(email, password_reset_link) flash("An email has been sent to '{}' with a link to reset your password. This link expires in 1 hour.".format(email),'success') else: flash("The email you entered was not found", "danger") else: print(form.errors) except Exception as e: error = "There was an error completing your request. Details: {}".format(e) flash(error,'danger') log.exception(logging_prefix + error) return render_template("password_reset.html", page_title="Reset Your Password", page_type="REQUEST", form=form, search_form=search_form )
def logout(): logging_prefix = logger_prefix + "logout() - " log.info(logging_prefix + "Starting") session['logged_in'] = False session['id'] = None session['name'] = None session['email'] = None session['approved'] = None session['write'] = None session['delete'] = None session['admin'] = None session['expires'] = None flash("You have been logged out", 'success') if request.args.get("r"): return redirect("/user/login/?r={}".format(quote_plus(request.args.get("r")))) else: return redirect("/user/login/", code=307)
def verify(email, verification_hash): logging_prefix = logger_prefix + "verify() - " log.info(logging_prefix + "Starting") email = unquote_plus(email) print(email) print(verification_hash) try: conn=get_mysql().cursor(DictCursor) conn.execute("SELECT id, email, name, company, justification FROM users WHERE verification_hash = %s", (verification_hash,)) r = conn.fetchone() if not r: log.error(logging_prefix + "User with email '{}' was not found".format(email)) flash("Your user was not found, try registering again",'danger') elif r['email'] == email: log.info(logging_prefix + "Successful validation of {}".format(email)) flash("Your email address have been verified, you will not be able to log in until you get approved by the Site Admin",'success') #update the database marking this user active user_id = r['id'] conn.execute("UPDATE users SET email_verified=1 WHERE id = %s", (user_id,)) get_mysql().commit() #id, email, name, company sendNewUserToApproveEmail(r['id'], r['email'],r['name'],r['company'],r['justification']) else: log.warning(logging_prefix + "Unsuccessful validation of {}".format(email)) flash("We were unable to verify your account",'danger') except Exception as e: error = "There was an error completing your request. Details: {}".format(e) flash(error,'danger') log.exception(logging_prefix + error) finally: conn.close() return redirect("/", code=307)
def reverify(): logging_prefix = logger_prefix + "reverify() - " log.info(logging_prefix + "Starting") try: form = forms.userEmailForm(request.form) search_form = forms.searchForm() if request.method == 'POST': if form.validate(): email = form.user_email.data #make sure the email exists in the system conn=get_mysql().cursor(DictCursor) conn.execute("SELECT verification_hash FROM users WHERE email = %s", (email,)) user = conn.fetchone() conn.close() if user: sendAccountVerificationEmail(email, user['verification_hash']) flash("A verification email has been sent to '{}' with a link to verify your account.".format(email),'success') else: flash("The email you entered was not found", "danger") else: print(form.errors) except Exception as e: error = "There was an error completing your request. Details: {}".format(e) flash(error,'danger') log.exception(logging_prefix + error) return render_template("account_reverify.html", page_title="Verify Account", form=form, search_form=search_form )
def main(): log.info("app v" + __version__)
def login(): logging_prefix = logger_prefix + "login() - " log.info(logging_prefix + "Starting") try: form = forms.loginForm(request.form) search_form = forms.searchForm() if request.method == 'POST': if form.validate(): email = form.user_email.data password = form.user_password.data hashed_password = sha256(SALTS['user'], password) conn=get_mysql().cursor(DictCursor) #since email is unique conn.execute("SELECT id, password, name, email_verified, approved, write_permission, delete_permission, admin FROM users WHERE email = %s", (email,)) user = conn.fetchone() if user: if user['password'] == hashed_password: #we have found a valid user if user['email_verified']==0: #the user has not verified their email address flash("Your email address has not been verified. Click here if you did not receive a verification email", "danger") elif user['approved']==0: #the user has not been approved, or their access has been disapproved flash("Your account has been approved yet, you will receive an email when your account has been approved", "danger") else: #woohoo successful login, set up session variables session['logged_in'] = True session['id'] = user['id'] session['name'] = user['name'] session['email'] = email session['approved'] = (user['approved'] == 1) session['write'] = (user['write_permission'] == 1) session['delete'] = (user['delete_permission'] == 1) session['admin'] = (user['admin'] == 1) session['expires'] = math.ceil(time.time()) + SESSION_EXPIRE #now + 10 minutes of inactivity #each time this user loads a page #the expiration time gets now + 10m #update last login timestamp conn=get_mysql().cursor(DictCursor) conn.execute("UPDATE users SET last_login=%s WHERE id = %s", (datetime.now(), user['id'])) get_mysql().commit() conn.close() flash("You have been logged in", "success") if request.args.get("r"): return redirect(request.args.get("r")) else: return redirect("/") else: log.warning(logging_prefix + "Invalid login attempt for {}".format(email)) flash("The username or password is incorrect", "danger") else: log.warning(logging_prefix + "Invalid login attempt for {}".format(email)) flash("The username or password is incorrect", "danger") else: print(form.errors) except Exception as e: error = "There was an error completing your request. Details: {}".format(e) flash(error,'danger') log.exception(logging_prefix + error) return render_template("login.html", page_title="Login", form=form, search_form=search_form )
def register(): logging_prefix = logger_prefix + "register() - " log.info(logging_prefix + "Starting") try: form = forms.registerForm(request.form) search_form = forms.searchForm() if request.method == 'POST': #verify captcha perform_validate = True try: if RECAPTCHA_ENABLED: captcha_value = request.form['g-recaptcha-response'] r = requests.post("https://www.google.com/recaptcha/api/siteverify", data={ 'secret': RECAPTCHA_PRIVATE_KEY, 'response': request.form['g-recaptcha-response'] }) r_json = json.loads(r.text) if not r_json['success']: flash("Bots are not allowed",'danger') perform_validate = False except Exception as s: log.exception(logging_prefix + "Error preforming captcha validation") raise s if perform_validate and form.validate(): log.info(logging_prefix + "Sign up Detected") #get data from form name = form.user_name.data email = form.user_email.data password = form.user_password.data company = form.user_company.data reason = form.user_reason.data #create the necessary hashes salted_password = sha256(SALTS['user'],password) verification_hash = sha256(SALTS['email_verification'], email) #insert data into mysql insert = "INSERT INTO users (email, password, name, company, justification, email_verified, verification_hash) VALUES (%s,%s,%s,%s,%s,%s,%s)" values = (email, salted_password, name, company, reason, 0, verification_hash) log.info(logging_prefix + "Adding new user {}".format(values)) try: conn=get_mysql().cursor() conn.execute(insert, values) get_mysql().commit() conn.close() except Exception as s: conn.close() raise s #email the user to verify email try: sendAccountVerificationEmail(email, verification_hash) except Exception as s: log.exception(logging_prefix + "Unable to send email to {} with verification_hash {}".format(email, verification_hash)) raise s flash("You have been registered. A verification email with an actviation link has been sent to {} from [email protected]".format(email),'success') else: print(form.errors) else: pass except Exception as e: error = "There was an error completing your request. Details: {}".format(e) flash(error,'danger') log.exception(logging_prefix + error) return render_template("register.html", page_title="Register", form=form, recaptcha_enabled=RECAPTCHA_ENABLED, recaptcha_key=RECAPTCHA_PUBLIC_KEY, search_form=search_form )
def populate_related_elements(_type): logging_prefix = logger_prefix + "populate_related_elements({}) - ".format(_type) log.info(logging_prefix + "Starting") r = fetch_related_elements(_type) return jsonify(r), 200
def fetch(_type, value): logging_prefix = logger_prefix + "fetch({},{}) - ".format(_type,value) log.info(logging_prefix + "Starting") r = fetch_child_data(_type,value) return jsonify(r), 200
def form_to_es(form, report_id): logging_prefix = logger_prefix + "form_to_es() - " log.info(logging_prefix + "Converting Form to ES for {}".format(report_id)) doc = {} created_t = int(time.mktime(form.report_occurred_at.data.timetuple())) * 1000 created_s = form.report_occurred_at.data.strftime("%Y-%m-%dT%H:%M:%S") now_t = int(time.time()) * 1000 now_s = datetime.now().strftime("%Y-%m-%dT%H:%M:%S") doc["created_milli"] = created_t doc["created_s"] = created_s doc["last_updated_milli"] = now_t doc["last_updated_s"] = now_s doc["name"] = escape(form.report_name.data) doc["identifier"] = escape(form.report_id.data) doc["description"] = escape(form.report_description.data) doc["criticality"] = escape(int(form.report_criticality.data)) doc["classification"] = [] for sub_form in form.report_class.entries: classification_dict = {} classification_dict["score"] = int(get_score(sub_form.data["a_family"], sub_form.data["a_id"])) classification_dict["id"] = escape(sub_form.data["a_id"]) classification_dict["family"] = escape(sub_form.data["a_family"]) if classification_dict not in doc["classification"]: doc["classification"].append(classification_dict) doc["tlp"] = int(escape(form.report_tlp.data)) doc["section"] = [] idx = 1 for sub_form in form.report_sections.entries: section_dict = {} section_dict["order"] = idx section_dict["title"] = escape(sub_form.title.data) section_dict["tlp"] = int(escape(sub_form.tlp.data)) section_dict["content"] = escape(sub_form.text.data) idx += 1 doc["section"].append(section_dict) doc["source_reliability"] = escape(form.report_source_reliability.data) doc["info_reliability"] = int(escape(form.report_info_reliability.data)) doc["source"] = [] for sub_form in form.report_sources.entries: source = sub_form.source.data if source not in doc["source"]: doc["source"].append(source) """ Related elements """ my_id = report_id # Links to actors and reports doc["related_actor"] = [] for sub_form in form.report_actors.entries: r_dict = {} data = escape(sub_form.data.data) if data == "_NONE_": continue data_array = data.split(":::") r_dict["id"] = escape(data_array[0]) # if the related element's id = my id, dont add to es, this should only apply to current type if data_array[0] == my_id: flash("A related actor matched this actor, this entry has been discarded", "warning") continue r_dict["name"] = escape(data_array[1]) # this is gonna be a nightmare to maintain, # but it make sense to have this for searches r_dict["elements"] = [] for sub_sub_form in sub_form.related_elements.entries: if sub_sub_form.element.data: if sub_sub_form.element_value.data not in r_dict["elements"]: r_dict["elements"].append(sub_sub_form.element_value.data) if r_dict not in doc["related_actor"]: doc["related_actor"].append(r_dict) doc["related_report"] = [] for sub_form in form.report_reports.entries: r_dict = {} data = escape(sub_form.data.data) if data == "_NONE_": continue data_array = data.split(":::") r_dict["id"] = escape(data_array[0]) # if the related element's id = my id, dont add to es, this should only apply to current type if data_array[0] == my_id: flash("A related report matched this report, this entry has been discarded", "warning") continue r_dict["name"] = escape(data_array[1]) # this is gonna be a nightmare to maintain, # but it make sense to have this for searches r_dict["elements"] = [] for sub_sub_form in sub_form.related_elements.entries: if sub_sub_form.element.data: if sub_sub_form.element_value.data not in r_dict["elements"]: r_dict["elements"].append(sub_sub_form.element_value.data) if r_dict not in doc["related_report"]: doc["related_report"].append(r_dict) doc["related_ttp"] = [] for sub_form in form.report_ttps.entries: r_dict = {} data = escape(sub_form.data.data) if data == "_NONE_": continue data_array = data.split(":::") r_dict["id"] = escape(data_array[0]) # if the related element's id = my id, dont add to es, this should only apply to current type if data_array[0] == my_id: flash("A related TTP matched this TTP, this entry has been discarded", "warning") continue r_dict["name"] = escape(data_array[1]) # this is gonna be a nightmare to maintain, # but it make sense to have this for searches r_dict["elements"] = [] for sub_sub_form in sub_form.related_elements.entries: if sub_sub_form.element.data: if sub_sub_form.element_value.data not in r_dict["elements"]: r_dict["elements"].append(sub_sub_form.element_value.data) if r_dict not in doc["related_ttp"]: doc["related_ttp"].append(r_dict) # store these to make life easier doc["related_element_choices"] = [] rec = json.loads(form.related_element_choices.data) for k, v in rec.items(): # dont include the n/a choice, as this will be first and handled manually if v != "_NONE_": # this will create a tuple ("display text", "value string") doc["related_element_choices"].append({"display_text": k, "value": v}) """ Edit Tracking """ doc["editor"] = get_editor_list( es=get_es(), index=ES_PREFIX + "threat_reports", doc_type="report", item_id=report_id, user_id=session.get("id", None), ) # index the doc log.info(logging_prefix + "Start Indexing of {}".format(report_id)) response = get_es().index(ES_PREFIX + "threat_reports", "report", doc, report_id) log.info(logging_prefix + "Done Indexing of {}".format(report_id)) return response, doc