def destroy(self, *args, **kwargs): model = self.model data = request_json() id = data.get('id') ids = [id] if ',' not in id else id.split(',') errorMsg = None try: items = model.objects.filter(id__in=ids)[:] if not self.canDestroy(items): return ut.failed() model.objects.filter(id__in=ids).delete() except Exception as e: errorMsg = str(e) return ut.failed(errorMsg) if errorMsg else ut.success()
def send_confirmation_email(self): data = request_json() # recaptcha errorMsg = validate_recaptcha(data['recaptcha']) if errorMsg: return failed(errorMsg) # errorMsg = None try: self.do_send_confirmation_email(data['email'], current_user.id) except Exception as e: print(e) errorMsg = str(e) return failed(errorMsg) if errorMsg else success()
def store(self): file = request.files['file'] if file and allowed_file(file.filename): filename = make_filename(file.filename) fullPath = make_fullpath(filename) fullUrl = make_file_url(filename) make_dir_by_path(fullPath) # save file.save(fullPath) # mark temperature # todo not deleteTmpFiles if not models.file.objects.filter(path=filename).first(): store(models.file, {'path': filename, 'tmp': True}) return ut.success(fullUrl) return ut.failed('Disallowed file type') if file else ut.failed(message='No file selected')
def login(self): data = request_json() # recaptcha errorMsg = validate_recaptcha(data['recaptcha']) if errorMsg: return failed(errorMsg) user = self.model.objects.filter(email=data['email']).first() if user.user_type != data['user_type']: user = None if not user: return failed('User not found') if not pwd_hashed_compare(data['password'], user.password): return failed('Incorrect password') login_user(user, remember=data.get('remember')) return success()
def register(self): data = request_json() # recaptcha errorMsg = validate_recaptcha(data['recaptcha']) if errorMsg: return failed(errorMsg) # schema = { 'email': rules['email'], 'first_name': { 'required': True, 'type': 'string', 'maxlength': 255 }, 'last_name': { 'required': True, 'type': 'string', 'maxlength': 255 }, 'password': rules['password'], 'user_type': { 'required': True, 'type': 'string', 'allowed': ['school', 'student'] }, } v = make_validator(schema) if not v.validate(data): return failed('Invalid input', {'error': v.errors}) if data.get('user_type') != 'student': return failed('Invalid user_type') user = self.model.objects.filter(email=data['email']).first() if user: return failed('An account with this email already exists') data['password'] = hash_pwd(data['password']) try: user = store(self.model, data) profileData = dict_pluck(data, ['first_name', 'last_name']) profileData['user_id'] = user.id profile = store(models.student_profile, profileData) self.do_send_confirmation_email(user.email, user.id) except Exception as e: print(e) errorMsg = str(e) if errorMsg: return failed(errorMsg) login_user(user) return success()
def send_reset_password_email(self): data = request_json() # recaptcha errorMsg = validate_recaptcha(data['recaptcha']) if errorMsg: return failed(errorMsg) # validate schema = { 'email': rules['email'], } v = make_validator(schema) if not v.validate(data): return failed('Invalid input', {'error': v.errors}) # whether exist email = data['email'] user = self.model.objects.filter(email=email).first() if not user: return failed('The account for the given email does not exist') if user.user_type == 'school' and get_user_profile( user).status != 'normal': return failed('This account is currently not enabled') # data = { 'token': md5(str_rand(16)), 'email': email, } record = models.reset_password_email.objects.filter( email=email).first() if record: item = update(models.reset_password_email, data, record.id) else: item = store(models.reset_password_email, data) link = url_for('index', _external=True) + 'reset-password?token=' + data[ 'token'] # generate absolute link print('reset password link:', link) try: msg = Message('[%s] Reset your account password' % (app.config['site_name']), recipients=[email]) msg.html = render_template('email/reset-password.html', email=email, link=link, app=app) mail.send(msg) except Exception as e: return failed(str(e)) return success()
def check_reset_password_token(self): data = request_json() # recaptcha errorMsg = validate_recaptcha(data['recaptcha']) if errorMsg: return failed(errorMsg) token = data.get('token', None) if not token: return failed('Illegal request') item = models.reset_password_email.objects.filter(token=token).first() if not item: return failed('No record found with given token') expired = (datetime.now() - item.updated_at).seconds > 3600 * 1 if expired: return failed('Link expired') user = self.model.objects.filter(email=item.email).first() return success(user_to_dict(user))
def update(self, *args, **kwargs): errorMsg = None data = request_json() t = self.beforeWrite(data, 'update') if t: return t id = data.get('id') item = self.model.objects(id=id).first() if not item: return ut.failed('Not found', code=404) if not self.canUpdate(item): return ut.failed() try: item = update(self.model, data, id) except Exception as e: errorMsg = str(e) return ut.failed(errorMsg) if errorMsg else ut.success()
def store(self): r = super().store()[0] # may failed if r['result'] == 'success': data = self.data['accomodation'] data['course_id'] = r['id'] item = None # save try: item = store(models.accomodation, data) r['accomodation_id'] = str(item.id) return ut.success(append=r) except Exception as e: print(666) app.logger.debug(e) print(e) return ut.failed(str(e)) else: return ut.failed(append=r)
def update_email(self): data = request_json() schema = { 'email': rules['email'], } v = make_validator(schema) if not v.validate(data): return failed('Invalid input', {'error': v.errors}) current_user.email = data['email'] current_user.email_confirmed = False current_user.save() return success()
def store(self, *args, **kwargs): errorMsg = None item = None data = request_json() t = self.beforeWrite(data, 'store') if t: return t try: item = store(self.model, data) except Exception as e: app.logger.debug(e) print(e) errorMsg = str(e) return ut.failed(errorMsg) if errorMsg else ut.success( append={'id': str(item.id)})
def reset_password(self): data = request_json() # recaptcha errorMsg = validate_recaptcha(data['recaptcha']) if errorMsg: return failed(errorMsg) # validate schema = { 'user_id': { 'required': True, 'type': 'string' }, 'token': { 'required': True, 'type': 'string' }, 'password': rules['password'], } v = make_validator(schema) if not v.validate(data): return failed('Invalid input', {'error': v.errors}) # record = models.reset_password_email.objects.filter( token=data['token']).first() user = self.model.objects.filter(id=data['user_id']).first() if not record or not user or record.email != user.email: return failed('Illegal request') # expired = (datetime.now() - record.updated_at).seconds > 3600 * 1 if expired: return failed('Link expired') user.password = hash_pwd(data['password']) user.email_confirmed = True user.save() record.delete() return success()
def refresh(self): # Load data self.finished_tasks = 0 for arg in self.result.args(): if utils.finished(self.arg_id(arg)): if not utils.failed(self.arg_id(arg)): self.read(arg) self.finished_tasks += 1 self.total_tasks = len(self.result.args()) t = datetime.datetime.now() td = t - self.start_time self.start_time = t self.time_used += td.seconds * 1e6 + td.microseconds self.write_time(self.time_used)
def select(self, id=None, *args, **kwargs): model = self.model data = request_json() if not id: id = data.get('id') if id: # return one row item = model.objects.filter(id=id).first() return ut.success(data=to_dict(item)) if item else ut.failed( 'Not found', code=404) else: # return resources list # default page: 1, per_page: 20 page = int(request.args.get('page') or 1) per_page = int(request.args.get('per_page') or 20) start = (page - 1) * per_page end = page * per_page models = model.objects.all()[start:end] modelsDict = [to_dict(item) for item in models] return ut.success(modelsDict)
def confirm_email(self): data = request_json() token = data.get('token', None) user = current_user errorMsg = None if user.email_confirmed: errorMsg = 'Your email already be confirmed' if token: item = models.confirmation_email.objects().filter( token=token).first() if not item or item.email != user.email: errorMsg = 'Illegal request' else: expired = (datetime.now() - item.updated_at).seconds > 3600 * 1 if expired: errorMsg = 'Link expired' else: user.email_confirmed = True user.save() item.delete() else: errorMsg = 'Token is required' return failed(errorMsg) if errorMsg else success()
def register(self): data = request_json() # recaptcha errorMsg = validate_recaptcha(data['recaptcha']) if errorMsg: return failed(errorMsg) # schema = { 'name': { 'required': True, 'type': 'string', 'maxlength': 255 }, 'address': { 'required': True, 'type': 'string', 'maxlength': 255 }, 'city': { 'required': True, 'type': 'string', 'maxlength': 255 }, 'country': { 'required': True, 'type': 'string', 'maxlength': 255 }, 'email': rules['email'], 'introduction': { 'required': True, 'type': 'string', 'maxlength': 1000 }, 'website': { 'required': True, 'type': 'string', 'maxlength': 1000 }, 'contact_persons': { 'required': True, 'maxlength': 1000 }, 'registration_document': { 'required': True, 'maxlength': 1000 }, } v = make_validator(schema) if not v.validate(data): return failed('Invalid input', {'error': v.errors}) try: t = data['contact_persons'] keys = ['last_name', 'first_name', 'title', 'email', 'tel'] if not keys_match(t[0], keys) or not keys_match(t[1], keys): return failed('Invalid input') for k, v in t[0].items(): if not v: return failed('The %s is required.' % (k.replace('_', ' '))) except Exception as e: app.logger.debug(e) return failed('Invalid input') # user = self.model.objects.filter(email=data['email']).first() if user: return failed('An account with this email already exists') userData = { 'email': data['email'], 'password': hash_pwd(str_rand(16)), 'user_type': 'school', } try: user = store(self.model, userData) data['user_id'] = user.id data['status'] = 'pending' profile = store(models.school_profile, data) except Exception as e: app.logger.debug(e) return failed(str(e)) return success()
def profile(self): data = (request_json() or {}).get('data') if not data: # get return success(to_dict(get_user_profile(current_user))) else: # update if current_user.user_type == 'student': # validate schema = { 'avatar': { 'required': True, 'type': 'string', 'maxlength': 255 }, 'first_name': { 'required': True, 'type': 'string', 'maxlength': 255 }, 'last_name': { 'required': True, 'type': 'string', 'maxlength': 255 }, 'gender': rules['gender'], 'birthday': { 'required': True, 'type': 'number' }, 'nationality': { 'required': True, 'type': 'string', 'maxlength': 255 }, 'country_of_residence': { 'required': True, 'type': 'string', 'maxlength': 255 }, 'email': rules['email'], 'phone': { 'required': True, 'type': 'string', 'maxlength': 255 }, 'passport_info': { 'required': True, 'maxlength': 1000 }, 'emergency_contact_persons': { 'required': True, 'maxlength': 1000 }, } v = make_validator(schema) if not v.validate(data): return failed('Invalid input', {'error': v.errors}) try: t = data['passport_info'] if not keys_match( t, ['number', 'issued_country', 'expiry_date']): return failed('Invalid input') for k, v in t.items(): if not v: return failed('The %s is required.' % (k.replace('_', ' '))) t = data['emergency_contact_persons'] keys = ['name', 'relationship', 'tel'] if not keys_match(t[0], keys) or not keys_match( t[1], keys): return failed('Invalid input') for k, v in t[0].items(): if not v: return failed('The %s is required.' % (k.replace('_', ' '))) except Exception as e: print(e) return failed('Invalid input') # todo validate school profile # model = models.student_profile if current_user.user_type == 'student' else models.school_profile profile = get_user_profile(current_user) if current_user.email != data['email']: current_user.email = data['email'] current_user.email_confirmed = False current_user.save() update(model, data, profile.id) return success()
def auth(next, *args, **kwargs): if not current_user.is_authenticated: return failed('Unauthenticated', code=401) return next()
def beforeWrite(self, data, type): self.data = data # if current_user.user_type != 'school': return ut.failed('Only schools can create courses') # data['school_id'] = current_user.id # validate schema = { # 'with_accom': { 'required': True, 'type': 'boolean' }, # 'start_date': { 'required': True, 'type': 'number' }, 'end_date': { 'required': True, 'type': 'number' }, 'category_id': { 'required': True, 'type': 'string', 'maxlength': 255 }, 'level': { 'required': True, 'type': 'string', 'maxlength': 255 }, 'title': { 'required': True, 'type': 'string', 'maxlength': 255 }, # 'gender': { 'required': True, 'type': 'string', 'maxlength': 255 }, 'age_range': { 'required': True, 'type': 'list' }, 'hours': { 'required': True, 'type': 'list' }, 'description': { 'required': True, 'type': 'string', 'maxlength': 10000 }, # 'language': { 'required': True, 'type': 'string', 'maxlength': 255 }, # 'street': { 'required': True, 'type': 'string', 'maxlength': 255 }, 'city': { 'required': True, 'type': 'string', 'maxlength': 255 }, 'province': { 'required': True, 'type': 'string', 'maxlength': 255 }, 'zip_code': { 'required': True, 'type': 'string', 'maxlength': 255 }, 'country': { 'required': True, 'type': 'string', 'maxlength': 255 }, 'api_key': { 'required': True, 'type': 'string', 'maxlength': 255 }, 'location_description': { 'required': True, 'type': 'string', 'maxlength': 10000 }, 'how_to_get_there': { 'required': True, 'type': 'string', 'maxlength': 10000 }, 'where_to_meet': { 'required': True, 'type': 'string', 'maxlength': 10000 }, # 'schedule': { 'required': True, 'type': 'string', 'maxlength': 10000 }, 'meals_included': { 'required': True, 'type': 'boolean' }, 'meals': { 'required': True, 'type': 'list' }, # 'issue_certificate': { 'required': True, 'type': 'boolean' }, # 'request_form_enabled': { 'required': True, 'type': 'boolean' }, # # 'group_size': { 'required': True, 'type': 'number' }, 'seat_quota': { 'required': True, 'type': 'number' }, 'price': { 'required': True, 'type': 'number' }, # # 'cover': { 'required': True, 'type': 'string', 'maxlength': 255 }, 'photos': { 'required': True, 'type': 'list', 'minlength': 2 }, } v = ut.make_validator(schema) if not v.validate(data): return ut.failed('Invalid input', {'error': v.errors}) # validate instructors meals certificate request_form price early_bird down_payment t = data['instructors'] if not ut.keys_match(t, ["name", "phone", "description", "photo"]): return ut.failed('Invalid input') k = ut.dict_any_key_none(t[0]) if k: return ut.failed('The %s of main instructor is required.' % (k.replace('_', ' '))) if data['meals_included']: if len(data['meals']) == 0: return ut.failed('The meals is required.') if data['issue_certificate']: if not data['certificate']: return ut.failed('The certificate is required.') if data['request_form_enabled']: if data['request_form'][0][ 'enabled'] and not data['request_form'][0]['value']: return ut.failed('Request form 1 is required.') if data['request_form'][1][ 'enabled'] and not data['request_form'][1]['value']: return ut.failed('Request form 2 is required.') if not data['with_accom']: if data['price'] == None: return ut.failed('The price is required.') if data['early_bird']['enabled']: k = ut.dict_any_key_none(data['early_bird']) if k: return ut.failed('The %s of early bird is required.' % (k.replace('_', ' '))) if data['down_payment']['enabled']: k = ut.dict_any_key_none(data['down_payment']) if k: return ut.failed('The %s of down payment is required.' % (k.replace('_', ' '))) # accomodation if data['with_accom']: schema = { 'type': { 'required': True, 'type': 'string' }, 'name': { 'required': True, 'type': 'string' }, 'phone': { 'required': True, 'type': 'string' }, 'address': { 'required': True, 'type': 'string' }, 'facilities': { 'required': True, 'type': 'list' }, 'description': { 'required': True, 'type': 'string', 'maxlength': 10000 }, 'photos': { 'required': True, 'type': 'list' }, } v = ut.make_validator(schema) if not v.validate(data['accomodation']): return ut.failed('Invalid input for accomodation', {'error': v.errors}) roomCount = 0 for i, v in enumerate(data['accomodation']['rooms']): if v['enabled']: roomCount += 1 k = ut.dict_any_key_none(v) if k: return ut.failed('The %s of room %s is required.' % (k.replace('_', ' '), i + 1)) if roomCount == 0: return ut.failed('At least one enabled room is needed')