def get(self, name): ''' Takes the name of on inquiry and returns with every refresh a new IRR of the data. ''' # find inquiry if not ClientInquiriesModel.find_by_name(name): return {'message': "no inquiry with that name"}, 400 #bad request inquiry = ClientInquiriesModel.find_by_name(name) p = inquiry.p q = inquiry.q answer_prr = json.loads(inquiry.answer) #answer_prr = json.loads(inquiry.prr_answer) answer_irr = instantaneous_RandomizedResponse(p, q, answer_prr) #epsilon_prr = 2 * (math.log((1 - (0.5 * f)) / (0.5 * f))) empty = 0 simulation = SimulationModel.find_by_name(name) if simulation is None: s = SimulationModel(name) s.added_irr = json.dumps([0.0] * len(answer_irr)) s.average_irr = json.dumps([0.0] * len(answer_irr)) s.save_to_db() return {'name': inquiry.name}, 200 # status ok simulation.count = simulation.count + 1 irr_sum = [ x + y for x, y in zip(answer_irr, json.loads(simulation.added_irr)) ] simulation.added_irr = json.dumps(irr_sum) simulation.save_to_db() new_average = [0] * len(answer_irr) test = list(map(lambda x: x / simulation.count, irr_sum)) print("test") print(test) print("simulation") print(simulation) return { 'name': inquiry.name, 'number of reports': simulation.count, 'irr_added': simulation.added_irr, 'answer': inquiry.answer, 'answer_prr': answer_prr, 'answer_irr': answer_irr, 'rolling_irr': test }, 200 # status ok
def inquiries_create(): ''' Create new inquiries (web GUI). ''' cnfg = ConfigurationModel.find() if cnfg is None: abort(404) form = InquiryCreateForm() if form.validate_on_submit(): inquiries = json.loads(form.questions.data) # print("client inquiries") # print(type(inquiries)) # print(inquiries) for inquiry in inquiries: #length_options_list = len(json.loads(inquiry['options'])) length_options_list = len(inquiry['options']) print("inquiry") print(inquiry) print("liste laenge") print(length_options_list) options = inquiry['options'] print("options") print(options) inq = ClientInquiriesModel( name=inquiry['name'], type=inquiry['type'], options=json.dumps(inquiry['options']), answer=json.dumps([0] * length_options_list), prr_answer=json.dumps([0] * length_options_list), irr_answer=json.dumps([0] * length_options_list), qdescription=inquiry['description'], responded=False, locked=True, f=cnfg.global_f, p=cnfg.global_p, q=cnfg.global_q) try: inq.save_to_db() except: return render_template('/error_pages/500.html', title='error while creating inquiry.') return redirect('inquiries/') return render_template('inquiries/create.html', form=form, title='create new inquiries')
def delete(self,name): ''' Deletes a client inquiry by it's name. ''' inquiry = ClientInquiriesModel.find_by_name(name) if inquiry: inquiry.delete_from_db() return {'message': "client inquiry '{}' deleted".format(name)}, 202 #accepted return {'message': "client inquiry '{}' not found".format(name)}, 404 #not found
def rolling(name): ''' IRR privacy simulation. ''' inq = ClientInquiriesModel.find_by_name(name) if inq is None: abort(404) return render_template('rolling_irr.html', title='irr simulation', inq=inq, name=name)
def distributions(id): ''' PRR privacy simulation. ''' inq = ClientInquiriesModel.find_by_name(id) if inq is None: abort(404) return render_template('distributions.html', title='epsilon differential privacy', inq=inq, inquiry_id=id)
def inquiries_privacy(id): ''' This is for privacy settings. ''' #access is only allowed if gdpr is set to true cnfg = ConfigurationModel.find() if cnfg is None: abort(404) if cnfg.dsgvo != 1: print("info works") return redirect(url_for('gdpr')) inq = ClientInquiriesModel.find_by_id(id) if inq is None: abort(404) form = PrivacyForm() if form.validate_on_submit(): #answer = form.answer.data locked = form.locked.data f = form.f.data p = convert_range(form.p.data) q = convert_range(form.q.data) if not check_fpq(f, p, q): print("Only values between 0 and 1 allowed for f,p,q!") #debug flash("Only values between 0 and 1 allowed for f,p,q!") return render_template('inquiries/privacy.html', inq=inq, form=form, title='privacy settings') inq.f = f inq.p = p inq.q = q try: inq.save_to_db() except: return render_template( '/error_pages/500.html', title='error while trying to save inquiries.') return render_template('inquiries/privacy.html', inq=inq, form=form, title='privacy')
def get(self,name): ''' Returns a client inquiry by its name. ''' answer = ClientInquiriesModel.find_by_name(name) if answer: print("IRR before") print(answer.irr_answer) prr = json.loads(answer.prr_answer) new_irr = instantaneous_RandomizedResponse(answer.p,answer.q,prr) answer.irr_answer = json.dumps(new_irr) #answer.save_to_db() # this would change an object with a GET-Request which is not allowed by the REST Definition print("IRR afterwards") print(answer.irr_answer) return answer.tojson(), 200 #ok return {'message': "Inquiry with name '{}' not found.".format(name)}, 404 #not found
def post(self,name): ''' Creates a new client inquriy, if not already existing under the same name. ''' cnfg = ConfigurationModel.find() if cnfg is None or cnfg.dsgvo != 1: return {'message': "Configuration error. Check your GDPR/DSGVO settings."}, 400 #bad request if ClientInquiriesModel.find_by_name(name): return {'message': "Inquiry with name '{}' already exists.".format(name)}, 400 #bad request #schreibe zeugs in db data = resources.parsers.ParseClientInquiriesPost.parser.parse_args() #check if description is empty description = "" if (data['qdescription'] is not None): description = data['qdescription'] # answer, prr_answer and irr_answer will set to 0 answer = [0]* len(data['options']) prr = [0]* len(data['options']) irr = [0]* len(data['options']) #validity checks if not check_type(data['type']): return {'message': "type must be 'cbx', 'mc' or 'bool'."}, 400 #bad request if (data['type'] == 'bool' and len(data['options']) != 2): return {'message': "when type 'bool' is chosen, only 2 answer options are possible."}, 400 #bad request if not check_if_bits(answer): return {'message': "only 0s and 1s allowed in answers"}, 400 #bad request if not check_fpq(config_f, config_p, config_q): return {'message': "f,p and q must have values between 0.0 and 1.0"}, 400 #bad request inquiry = ClientInquiriesModel(name, data['type'], json.dumps(data['options']), json.dumps(answer), #json.dumps(data['answer']), json.dumps(prr), json.dumps(irr), description, False, #responded is False, because inquiry is created but not answered yet. config_locked, #data['locked'], cnfg.global_f, #config_f, until first edit by the user global values are used instead of data['f'], cnfg.global_p, #config_p, #until first edit by the user global values are used instead of data['p'], cnfg.global_q) #config_q) #until first edit by the user global values are used instead of data['q']) try: inquiry.save_to_db() except: return {'message': "error while inserting inquiry with name '{}'.".format(name)}, 500 #internal server error return inquiry.tojson(), 201 #created
def get(self, name): ''' Takes the name of on inquiry and returns the distribution in JSON format. ''' # find inquiry if not ClientInquiriesModel.find_by_name(name): return {'message': "no inquiry with that name"}, 400 #bad request inquiry = ClientInquiriesModel.find_by_name(name) # values from the object buckets = len(json.loads(inquiry.answer)) answer = json.loads(inquiry.answer) f = inquiry.f users = 100 #create original world one without user as array (n-1 users) and fill it with random values original_opt_out = [] for x in range(users): histogram = [0] * (buckets - 1) index = randint(0, buckets - 1) histogram.insert(index, 1) #print('histogram') #print(histogram) original_opt_out.append(histogram) #create original world with own answer original_opt_in = original_opt_out.copy() original_opt_in.append(answer) random_opt_out = [] ###random without for element in original_opt_out: new = permanent_RandomizedResponse(f, element) random_opt_out.insert(-1, new) # sum up original world without original_without = [0] * buckets for elem in original_opt_out: #print("step1") #print(original_without) #print("step1 add") #print(elem) original_without = [x + y for x, y in zip(original_without, elem)] #print("step2") #print(original_without) # for k, v in enumerate(original_without): # original_without[k] = v/users # sum up original world within original_within = [0] * buckets for elem in original_opt_in: original_within = [x + y for x, y in zip(original_within, elem)] # sum up random world without random_without = [0] * buckets for elem in random_opt_out: random_without = [(x + y) for x, y in zip(random_without, elem)] random_opt_in = random_opt_out.copy() random_histogram = permanent_RandomizedResponse(f, answer) random_opt_in.append(random_histogram) print(len(random_opt_in)) # sum up random world within random_within = [0] * buckets for elem in random_opt_in: random_within = [(x + y) for x, y in zip(random_within, elem)] epsilon_prr = 2 * (math.log((1 - (0.5 * f)) / (0.5 * f))) return { 'name': inquiry.name, 'answer': inquiry.answer, 'users without': users, 'users withint': users + 1, 'answer': inquiry.answer, 'original_without': original_without, 'original_within': original_within, 'random_without': random_without, 'random_within': random_within, 'f': f, 'epsilon': epsilon_prr }, 200 # status ok
def get(self, inq): ''' Takes the name of on inquiry and returns the distribution in JSON format. ''' # find inquiry if not ClientInquiriesModel.find_by_name(inq): return {'message': "no inquiry with that name"}, 400 #bad request inquiry = ClientInquiriesModel.find_by_name(inq) # values from the object buckets = len(json.loads(inquiry.answer)) answer = json.loads(inquiry.answer) answer_buckets = [i for i, x in enumerate(answer) if x == 1] #f = inquiry.f f = float(request.args.get('f')) users = 100 #create original world one without user as array (n-1 users) and fill it with random values original_opt_out = [] for x in range(users): histogram = [0] * (buckets - 1) index = randint(0, buckets - 1) histogram.insert(index, 1) #print('histogram') #print(histogram) original_opt_out.append(histogram) #create original world with own answer original_opt_in = original_opt_out.copy() original_opt_in.append(answer) random_opt_out = [] ###random without for element in original_opt_out: new = permanent_RandomizedResponse(f, element) random_opt_out.insert(-1, new) # sum up original world without original_without = [0] * buckets for elem in original_opt_out: #print("step1") #print(original_without) #print("step1 add") #print(elem) original_without = [x + y for x, y in zip(original_without, elem)] #print("step2") #print(original_without) # for k, v in enumerate(original_without): # original_without[k] = v/users # sum up original world within original_within = [0] * buckets for elem in original_opt_in: original_within = [x + y for x, y in zip(original_within, elem)] # for k, v in enumerate(original_within): # original_within[k] = v/(users+1) #create random world without user as array (n-1 users) and fill it with random values # random_opt_out = [] # for x in range(users): # histogram = [0]* (buckets-1) # index = randint(0,buckets-1) # histogram.insert(index,1) # #print("zepp") # #print(histogram) # random_histogram = permanent_RandomizedResponse(f,histogram) # #print(random_histogram) # random_opt_out.append(random_histogram) # sum up random world without random_without = [0] * buckets for elem in random_opt_out: random_without = [(x + y) for x, y in zip(random_without, elem)] # for k, v in enumerate(random_without): # random_without[k] = v/users #print(random_without) #create random world within user as array (n-1 users) and fill it with random values # random_opt_in = [] # for x in range(users): # histogram = [0]* (buckets-1) # index = randint(0,buckets-1) # histogram.insert(index,1) # #print("zepp") # #print(histogram) # random_histogram = permanent_RandomizedResponse(f,histogram) # #print(random_histogram) # random_opt_in.append(random_histogram) # randomanswer = permanent_RandomizedResponse(f,answer) # random_opt_in.append(randomanswer) random_opt_in = random_opt_out.copy() random_histogram = permanent_RandomizedResponse(f, answer) random_opt_in.append(random_histogram) print("horst") print(len(random_opt_in)) # sum up random world within random_within = [0] * buckets for elem in random_opt_in: random_within = [(x + y) for x, y in zip(random_within, elem)] # for k, v in enumerate(random_within): # random_within[k] = v/(users+1) #print(random_within) users_opt_in = len(original_opt_in) users_opt_out = len(original_opt_out) print("original_without") print(original_without) print("original_within") print(original_within) print("users_opt_in") print(users_opt_in) print("users_opt_out") print(users_opt_out) print("privacy value f") print(f) print("random_without") print(random_without) print("random_within") print(random_within) epsilon_prr = 2 * (math.log((1 - (0.5 * f)) / (0.5 * f))) print("epsilon") print(epsilon_prr) return { 'original_without': original_without, 'original_within': original_within, 'random_without': random_without, 'random_within': random_within, 'epsilon': epsilon_prr, 'answer_buckets': answer_buckets }, 200, { 'Access-Control-Allow-Origin': '*' }
def put(self,name): ''' Changes a client inquiry by its name. The following values can be changed by the user: answers, description, locked, f,p and q. ''' cnfg = ConfigurationModel.find() if cnfg is None or cnfg.dsgvo != 1: return {'message': "Configuration error. Check your GDPR/DSGVO settings."}, 400 #bad request data = resources.parsers.ParseClientInquiriesPut.parser.parse_args() inquiry = ClientInquiriesModel.find_by_name(name) if inquiry is None: return {'message': "Can not change status, inquiry '{}' does not exist".format(name)}, 400 #bad request #check if description is empty description = data['qdescription'] if (data['qdescription'] is None): description = inquiry.qdescription #check if the lengt of the answer is correct (still the same). if not (len(data['answer']) == len(json.loads(inquiry.answer))): print("laenge") print(len(data['answer'])) print(len(json.loads(inquiry.answer))) return {'message': "old and new answer must have the same amount of options."}, 400 #bad request #check bool if not check_bool(inquiry.type,data['answer']): return {'message': "error: give a correct answer for type 'bool'."}, 400 #bad request #check mc if not check_mc(inquiry.type,data['answer']): return {'message': "error: only one answer options is allowed for mc questions."}, 400 #bad request #answer must be a list of 0s and 1s if not check_if_bits(data['answer']): return {'message': "only 0s and 1s allowed in answers"}, 400 #bad request # user answer must have as many values as inquiry options if (len(json.loads(inquiry.options)) is not len(data['answer'])): return {'message': "Your answer must have as many values as options are available"}, 400 #bad request if not check_fpq(data['f'],data['p'],data['q']): return {'message': "f,p and q must have values between 0.0 and 1.0"}, 400 #bad request # PRR and IRR will be only made if answer changes if (inquiry.answer != json.dumps(data['answer'])): inquiry.answer = json.dumps(data['answer']) # a PRR will be made after a answer is was changed prr = permanent_RandomizedResponse(float(data['f']),data['answer']) inquiry.prr_answer = json.dumps(prr) # a PRR will be made after a answer is was changed irr = instantaneous_RandomizedResponse(float(data['p']),float(data['q']),prr) inquiry.irr_answer = json.dumps(irr) # if a answer was given by the user, responded will be set to TRUE inquiry.responded = True inquiry.qdescription = description #data['qdescription'] inquiry.locked = data['locked'] inquiry.f = data['f'] inquiry.p = data['p'] inquiry.q = data['q'] try: inquiry.save_to_db() except: return {'message': "error while saving inquiry with name: '{}'.".format(name)}, 500 #internal server error return inquiry.tojson(), 202 #accepted
def inquiries_detail(id): ''' Detailed view of an inquiry (web GUI). ''' #access is only allowed if gdpr is set to true cnfg = ConfigurationModel.find() if cnfg is None: abort(404) if cnfg.dsgvo != 1: print("info works") return redirect(url_for('gdpr')) inq = ClientInquiriesModel.find_by_id(id) if inq is None: abort(404) # if the user changes a client inquiry, responded will be set to TRUE # and a PRR will be made with the answer value form = InquiryDetailForm() if inq.type == 'mc': form.radio_elem.description = inq.qdescription form.radio_elem.choices = [('_'.join(o.lower().split(' ')), o) for o in json.loads(inq.options)] form.radio_elem.name = inq.name elif inq.type == 'cbx': form.checkbox_elem.description = inq.qdescription form.checkbox_elem.name = inq.name form.checkbox_elem.choices = [('_'.join(o.lower().split(' ')), o) for o in json.loads(inq.options)] elif inq.type == 'bool': form.boolean_elem.description = inq.qdescription form.boolean_elem.name = inq.name form.boolean_elem.choices = [('_'.join(o.lower().split(' ')), o) for o in json.loads(inq.options)] else: abort(400, "Unknown question type {}".format(inq.type)) if form.validate_on_submit(): answer = form.answer.data locked = form.locked.data f = inq.f p = inq.p q = inq.q # check length of answer if not (len(json.loads(answer)) == len(json.loads(inq.answer))): print("answer must have the same ordinal values!") #debug flash("answer must have the same ordinal values!") return render_template('inquiries/inquiry.html', inq=inq, form=form, title='question') # if bits are zero and one if not check_if_bits(json.loads(answer)): print("only 0s and 1s allowed in the answer list") #debug flash("only 0s and 1s allowed in the answer list") return render_template('inquiries/inquiry.html', inq=inq, form=form, title='question') # a PRR and IRR will be set after a answer is was changed if (inq.answer != answer): prr = permanent_RandomizedResponse(float(f), json.loads(answer)) inq.prr_answer = json.dumps(prr) irr = instantaneous_RandomizedResponse(float(p), float(q), prr) inq.irr_answer = json.dumps(irr) inq.answer = answer inq.responded = True # if a answer was given by the user, responed will be set to TRUE inq.locked = locked # inq.f = inq.f # inq.p = inq.p # inq.q = inq.q try: inq.save_to_db() except: return render_template( '/error_pages/500.html', title='error while trying to save inquiries.') return render_template('inquiries/inquiry.html', inq=inq, form=form, title='question')
def get(self): ''' Request new surveys from the server. If the data is valid, the surveys are stored into the server inquiries table. If quizmode is activated, they will be also saved in the client inquiries table. ''' # contact the server of the serviceprovider. get surveys if suceed cnfg = ConfigurationModel.find() if cnfg is None: return { 'message': "Configuration error." }, 500 #internal server error try: r = requests.get(serviceprovider_surveys) umfragen = r.json() listevonsurveys = (umfragen['surveys']) except requests.exceptions.ConnectionError as e: print(e) #debug return { 'message': "server not available. no survey was requested: {} ".format(e) }, 400 #bad request #this creates client inquiries if quizmode is set. print(cnfg.quizmode) if cnfg.quizmode is 1: print("quizmode is true") for survey in listevonsurveys: inquiries = (survey['questions'] ) #fuer jedes dictonairy in der liste for inq in inquiries: name = inq['name'] qtype = inq['type'] options = inq['options'] options_count = len(inq['options']) answer = [0] * options_count prr_answer = [0] * options_count irr_answer = [0] * options_count qdescription = inq['description'] responded = False locked = config_locked f = cnfg.global_f p = cnfg.global_p q = cnfg.global_q if ClientInquiriesModel.find_by_name(name): print("client inquiry with name " + name + "already in db") #debug continue else: if check_type(qtype): inquiry = ClientInquiriesModel( name, qtype, json.dumps(options), json.dumps(answer), json.dumps(prr_answer), json.dumps(irr_answer), qdescription, responded, locked, f, p, q) inquiry.save_to_db() print( "quizmode on: new inquiry with name '{}' saved to client inquiry." .format(name)) continue #print("error: Type '{}' not correct.".format(qtype)) # creates questions and save the to the db for survey in listevonsurveys: #for every dictonairy in a list of dictionairies #generate surveyids, serviceprovider for the questions format surveyid = (survey['surveyid']) serviceprovider = (survey['serviceprovider']) #generate qid, qname, qtype, qoptions and qdescpritons for the questions format questions = (survey['questions']) for question in questions: qid = question['qid'] name = question['name'] qtype = question['type'] options = question['options'] qdescription = question['description'] #save question to the db, only if it is not already known by surveyid #if survey is in archive, inquiries will not saved. if ArchiveModel.find_by_surveyid(surveyid): print( "survey already in archive. ".format(surveyid)) #debug continue elif ServerInquiriesModel.already_in_db(surveyid, name): print( "survey and matching inquiries already in DB") #debug continue else: print("surveyid: " + surveyid) #debug print("serviceprovider: " + serviceprovider) #debug print("qid: " + str(qid)) #debug print("qname: " + name) #debug print("qtype: " + qtype) #debug print("qoptions: " + json.dumps(options)) #debug print("qdescription: " + qdescription) #debug print("____________________________") #debug if check_type(qtype): frage = ServerInquiriesModel( qid, surveyid, serviceprovider, name, qtype, json.dumps(options), qdescription, config_locked, cnfg.quizmode) frage.save_to_db() print( "new survey with surveyid '{}' available and fetched from the server." .format(surveyid)) print("error: Type '{}' not correct.".format(qtype)) # create a new entry in the archive: if not ArchiveModel.find_by_surveyid(surveyid): rchv = ArchiveModel(surveyid) rchv.save_to_db() return {'message': "done."}, 200 #ok