def carmod(): "Modify a car in inventory; restrict to admin or sales only." if "role" not in session.keys() or session["role"] not in ["Admin", "Sales"]: return redirect(url_for("home")) # user submitted a modification if request.method == "POST": if validate_table(caradd_ft, request.form): vin = request.form[caradd_ft[0]] make = request.form[caradd_ft[1]] model = request.form[caradd_ft[2]] year = request.form[caradd_ft[3]] retail = request.form[caradd_ft[4]] message = "" # validate the form if len(vin) != 17: message = "VIN must be 17 characters long ({})".format(len(vin)) if not 1 <= len(make) <= 30: message = "Make must be 1 to 30 characters long ({})".format(len(make)) if not 1 <= len(model) <= 30: message = "Model must be 1 to 30 characters long ({})".format(len(model)) if len(year) != 4: message = "Year must be 4 characters long ({})".format(len(year)) if not 1 <= len(model) <= 30: message = "Retail price must be 1 to 30 characters long ({})".format(len(model)) # check if form is validated if message == "": car = Car.query.filter_by(vin=vin).first() if car: car.make = make car.model = model car.year = year car.retail = retail db.session.add(car) db.session.commit() message = "Car modified; review the car management list." else: message = "Car failed to modify; invalid car({}) identification.".format(vin) # return to main car management page return redirect(url_for("carmanage", page=1, message=message)) # user presented with current car information elif request.method == "GET": if validate_table(carmod_ft, request.args): vin = request.args.get(carmod_ft[0]) car = Car.query.filter_by(vin=vin).first() if car: return render_template("cartemps/carmod.html", car=car) return redirect(url_for("home"))
def test_validate_table(self): import flask app = flask.Flask(__name__) with app.test_request_context('/login'): assert flask.request.path == '/login' assert not validate_table(['a', 'b'], flask.request.form)
def servicechange(): 'Process a service order; restrict to admin or sales only.' # check if user is login and check if role is admin or sales if 'role' not in session.keys() or session['role'] not in ['Admin','Sales']: return redirect(url_for("home")) # user attempt to process customer service if request.method == 'GET': if validate_table(servicechg_ft, request.args): # extract form entries action = request.args.get(servicechg_ft[0]) sid = request.args.get(servicechg_ft[1]) # double check form service = ServiceInfo.query.filter_by(sid = sid).first() if service: if service.stats == 1: if action == 'completed': message = 'Customer service completed!' service.stats = 2 elif action == 'cancel': message = 'Customer service canceled!' service.stats = 0 else: message = 'Customer service action denied; invalid service process action.' db.session.commit() else: message = 'Customer service action denied; invalid service identification.' else: message = 'Customer service action denied; invalid form method.' service_list = ServiceInfo.query.paginate(1, 10, False) return render_template("servicetemps/servicemanage.html", service_list = service_list, message = message)
def ordergen(): 'Add a customer order; restrict to admin or sales only.' if 'role' not in session.keys() or session['role'] not in ['Admin','Sales']: return redirect(url_for("home")) # user submit a order if request.method == 'POST': if validate_table(orderadd_ft, request.form): fname = request.form[orderadd_ft[0]] addr1 = request.form[orderadd_ft[1]] addr2 = request.form[orderadd_ft[2]] city = request.form[orderadd_ft[3]] state = request.form[orderadd_ft[4]] zipcode = request.form[orderadd_ft[5]] country = request.form[orderadd_ft[6]] message = '' # check if customer exist customer = CustomerInfo.query.filter_by(fname = fname, addr1 = addr1).first() if not customer: customer = CustomerInfo(fname, addr1, addr2, city, state, zipcode, country) db.session.add(customer) db.session.commit() cid = customer.cid vin = request.form[orderadd_ft[7]] sname = request.form[orderadd_ft[8]] price = request.form[orderadd_ft[9]] ddate = request.form[orderadd_ft[10]] # check if car exist car = Car.query.filter_by(vin = vin).first() if car: car.avail_purchase = False # create a new order new_order = OrderInfo(cid, vin, sname, price, ddate, datetime.now()) db.session.add(new_order) db.session.commit() message = 'Customer order added; review the order management list.' else: message = 'Customer order failed; car({}) cannot be found.'.format(vin) return redirect(url_for("ordermanage", message = message)) # add order from car management if 'vin' in request.args: vin = request.args.get('vin') return render_template("ordertemps/ordergen.html", cars = Car.query, vin = vin) # present the original order generation form return render_template("ordertemps/ordergen.html", cars = Car.query)
def upload(): "Upload a car picture to the server; restrict to admin or sales only." if "role" not in session.keys() or session["role"] not in ["Admin", "Sales"]: return redirect(url_for("home")) # user want to upload a picture for the car if request.method == "GET": if validate_table(carpic_ft, request.args): vin = request.args.get("vin") car = Car.query.filter_by(vin=vin).first() if car: return render_template("cartemps/upload.html", car=car) # user uploaded a picture for the car elif request.method == "POST": if validate_table(carpic_ft, request.args): vin = request.args.get(carpic_ft[0]) car = Car.query.filter_by(vin=vin).first() if car and "file" in request.files: file = request.files["file"] if file and file.filename.rsplit(".", 1)[1] in ["jpg", "tiff", "jpeg", "bmp", "gif", "png"]: # check if filename is already in database filename = secure_filename(vin + file.filename) file_exists = CarPics.query.filter_by(vin=vin, picname=filename).first() if not file_exists: new_pic = CarPics(vin=vin, picname=filename) db.session.add(new_pic) db.session.commit() file.save(os.path.join(app.config["UPLOAD_FOLDER"], filename)) message = "Upload picture; view car information for picture." else: message = "Upload picture failed; file name already exist." else: message = "Upload picture failed; invalid file or file extension." else: message = "Upload picture failed; invalid car({}) identification.".format(vin) return redirect(url_for("carmanage", page=1, message=message)) return redirect(url_for("home"))
def caradd(): "Add a car to inventory; restrict to admin or sales only." global vin_cache, vin_tsize, vin_table if "role" not in session.keys() or session["role"] not in ["Admin", "Sales"]: return redirect(url_for("home")) if request.method == "POST": if validate_table(caradd_ft, request.form): vin = request.form[caradd_ft[0]] make = request.form[caradd_ft[1]] model = request.form[caradd_ft[2]] year = request.form[caradd_ft[3]] retail = request.form[caradd_ft[4]] message = "" # validate the form if len(vin) != 17: message = "VIN must be 17 characters long ({})".format(len(vin)) if not 1 <= len(make) <= 30: message = "Make must be 1 to 30 characters long ({})".format(len(make)) if not 1 <= len(model) <= 30: message = "Model must be 1 to 30 characters long ({})".format(len(model)) if len(year) != 4: message = "Year must be 4 characters long ({})".format(len(year)) if not 1 <= len(model) <= 30: message = "Retail price must be 1 to 30 characters long ({})".format(len(model)) # check if form is validated if message == "": # check if car already exist car = Car.query.filter_by(vin=vin).first() if not car: # add the car newcar = Car(vin, make, model, year, retail) db.session.add(newcar) db.session.commit() if vin_cache == True: vin_table.append(vin) vin_tsize += 1 message = "Car added; review the car management list." else: message = "Car failed; {} already exist in database.".format(vin) return redirect(url_for("carmanage", page=1, message=message)) return render_template("cartemps/caradd.html", vin=genvin())
def indicar(): "Display car information and pictures." message = "" if request.method == "GET": if validate_table(carind_ft, request.args): vin = request.args.get(carind_ft[0]) car = Car.query.filter_by(vin=vin).first() if car: feats = CarFeatures.query.filter_by(vin=vin) pics = CarPics.query.filter_by(vin=vin) panels, extras = divmod(pics.count(), 3) return render_template( "cartemps/indicarview.html", car=car, feats=feats, pics=pics, panels=panels, extras=extras ) else: message = "Unable to view car information; invalid car({}) identification.".format(vin) return redirect(url_for("carmanage", page=1, message=message))
def login(): 'Login the user by setting the session object.' # redirect signed in user to home page (already login) if 'username' in session: return redirect(url_for("home")) # user has submitted credentials if request.method == "POST": if validate_table(accountlog_ft, request.form): # extract form entries username = request.form[accountlog_ft[0]] password = request.form[accountlog_ft[1]] status = 0x0000 # check whether the fields are empty if not 5 <= len(username) <= 25: status += 0x0001 # username must be 5 - 25 characters long if not 5 <= len(password) <= 25: status += 0x0002 # password must be 5 - 25 characters long # check whether the user exist try: user_exists = User.query.filter_by(uname=username).first() except Exception, e: user_exists = None if user_exists: # check whether the password matches if createhash(user_exists.salt,password) == user_exists.password: session['username'] = user_exists.uname session['role'] = user_exists.role if user_exists.isadmin: session['isadmin'] = True else: session['isadmin'] = False status += 0x0010 else: status += 0x0008 else: status += 0x0004 if status & 0x0001 or status & 0x0002: return redirect(url_for("login", message = 'Short username or password; must be at least length 5 or greater.')) elif status & 0x0004 or status & 0x0008: return redirect(url_for("login", message = 'Invalid username or password.')) elif status & 0x0010: return redirect(url_for("home"))
def cardel(): "Delete a car in inventory; restrict to admin or sales only." if "role" not in session.keys() or session["role"] not in ["Admin", "Sales"]: return redirect(url_for("home")) if validate_table(cardel_ft, request.args): vin = request.args.get(cardel_ft[0]) car = Car.query.filter_by(vin=vin).first() if car: db.session.delete(car) db.session.commit() return redirect(url_for("carmanage", page=1, message="Car deleted; review the car management list.")) else: return redirect( url_for( "carmanage", page=1, message="Car failed to delete; invalid car({}) identification.".format(vin) ) )
def register(): # TODO: Add template logic for trying to register an existing user if request.method == 'POST': if validate_table(register_form, request.form): username = request.form['username_register'] email = request.form['email'] password = request.form['password_register'] confirm = request.form['confirm'] if username == "" or email == "" or \ password == "" or confirm == "": return redirect(url_for('login')) if password != confirm: # Add template logic for invalid registration. return redirect(url_for('login')) user_exists = User.query.filter( User.uname == username ).scalar() if user_exists is None: salt = getsalt() passhash = createhash(salt, password) new_user = User(username, email, salt, passhash) db.session.add(new_user) db.session.commit() return render_template( 'index.html', message='Registration successful' ) else: message = 'Error account already exists' return render_template( 'index.html', message=message ) else: return redirect(url_for('login')) else: return render_template('login.html')
def addfeatures(): "Add features to a car in inventory; restrict to admin or sales only." if "role" not in session.keys() or session["role"] not in ["Admin", "Sales"]: return redirect(url_for("home")) message = "" if validate_table(carfea_ft, request.args): vin = request.args.get("vin") car = Car.query.filter_by(vin=vin).first() if car: feat_car = CarFeatures.query.filter_by(vin=vin).all() # auto-fill the form if request.method == "GET": feat_dict = {fcar.feat_type: fcar.descr for fcar in feat_car} return render_template("cartemps/addfeature.html", vin=car.vin, feats=feat_dict, feats_list=feat_table) # user submit features for car if request.method == "POST": # retrieve all entered features feat_list = [request.form[feat] for feat in feat_table] # update car features for ftype, feat in zip(feat_table, feat_list): override = False # check if feature already exist for fcar in feat_car: # override existing feature if ftype == fcar.feat_type: fcar.descr = feat override = True break # check if feature does not exit if not override: feat_new = CarFeatures(car.vin, ftype, feat.strip()) db.session.add(feat_new) db.session.commit() return redirect( url_for("carmanage", page=1, message="Feature added; please review the car information.") ) else: message = "Add feature failed; invalid car({}) identification.".format(vin) return redirect(url_for("carmanage", page=1, message=message))
def roles(): 'Allow administrators to change the roles of other users.' # check if user is login in and check if user is administrator if 'isadmin' not in session.keys() or session['isadmin'] == False: return redirect(url_for("home")) if request.method == 'GET': if validate_table(accountroe_ft, request.args): username = request.args.get(accountroe_ft[0]) newrole = request.args.get(accountroe_ft[1]) message = '' # check the role if newrole in ['Admin','Sales', 'Guest']: # check if user exist user_exists = User.query.filter_by(uname = username).first() if user_exists == None: message = 'You\'ve modified an invalid user\'s role.' # check if user is modifying his own permission level elif user_exists.uname == session['username']: message = 'You cannot modify your own permission level.' else: # set off administrator flag if user_exists.role == "Admin" and newrole != "Admin": user_exists.isadmin = 0 # set new role user_exists.role = newrole # set on administrator flag if user_exists.role == "Admin": user_exists.isadmin = 1 # commit the transaction db.session.commit() message = '{} role changed to {}.'.format(user_exists.uname, user_exists.role) else: message = 'Role action denied; invalid role({}).'.format(newrole) return render_template('accounttemps/roles.html', User = User, message = message) # present user with initial table return render_template('accounttemps/roles.html', User = User)
def register(): 'Register the user by adding an entry to the User table.' # redirect signed in user to home page (already register) if 'username' in session: return redirect(url_for("home")) # user has submitted a registration form if request.method == "POST": if validate_table(accountreg_ft, request.form): # extract form entries username = request.form[accountreg_ft[0]] password = request.form[accountreg_ft[1]] verified = request.form[accountreg_ft[2]] status = 0x0000 # validate registration if not 5 <= len(username) <= 25: status += 0x0002 # username must be 5 - 25 characters long if set(username) - chars: status += 0x0004 # username must contain only letters and digits if not 5 <= len(password) <= 25: status += 0x0008 # password must be 5 - 25 characters long if len(set(password) & set(digit)) < 1: status += 0x0010 # must contain digit character if len(set(password) & set(upper)) < 1: status += 0x0020 # must contain capital character if len(set(password) & set(speci)) < 1: status += 0x0040 # must contain special character if password != verified: status += 0x0080 # password is not verified if User.query.filter_by(uname=username).first() != None: status += 0x0100 # username already exist # create the user if it does not exist if not status: salt = getsalt() passhash = createhash(salt,password) newuser = User(username, salt, passhash, "Guest", 0) db.session.add(newuser) db.session.commit() return redirect(url_for("login", message="Registration successful, please sign in!")) # report password does not match elif status & 0x0080: return redirect(url_for("register", message = "Unable to verified password, please re-enter password.")) # report username already exist elif status & 0x0100: return redirect(url_for("register", message = "{} has already been taken, please choose another username.".format(username))) # report validation error else: return redirect(url_for("register", message = "Invalid username or password, please re-read the registration form rules.")) # present user with initial registration return render_template('accounttemps/register.html')
def login(): if request.method == 'POST': if validate_table(login_form, request.form): username = request.form['username_login'] password = request.form['password_login'] if username == "" or password == "": empty_message = 'Error: Empty username or password' return render_template( 'login.html', message=empty_message, username=username ) user_exists = User.query.filter_by(uname=username).first() if user_exists: if createhash(user_exists.salt, password) ==\ user_exists.password: session['logged_in'] = True session['username'] = username session['uid'] = str(user_exists.uid) next_url = request.form.get('next', '') if next_url: return redirect(next_url) return render_template( 'index.html', message='Login successful' ) return render_template( 'login.html', message='Error: Bad Login', username=username ) else: return render_template('login.html', next=request.args.get('next', ""))
def orderproc(): 'Deliver or cancel a customer order; restrict to admin or sales only.' if 'role' not in session.keys() or session['role'] not in ['Admin','Sales']: return redirect(url_for("home")) message = '' # user submit a order if request.method == 'GET': if validate_table(orderpoc_ft, request.args): action = request.args.get(orderpoc_ft[0]) oid = request.args.get(orderpoc_ft[1]) if action in ["deliver", "cancel"]: # check if order exist order = OrderInfo.query.filter_by(oid = oid).first() if order: # deliver the order if action == "deliver": order.delivered = True order.status = "Delivered" order.update = datetime.now() db.session.commit() message = 'Customer order process delivered; please check order history.' elif action == "cancel": # check if car exist car = Car.query.filter_by(vin = order.vin).first() if car: car.avail_purchase = True order.status = "Canceled" order.update = datetime.now() db.session.commit() else: message = 'Customer order process failed; invalid car({}) identification.'.format(order.vin) else: message = 'Customer order process failed; invalid order({}) identification.'.format(oid) else: message = 'Customer order process failed; invalid action({}) on customer order.'.format(action) return redirect(url_for("ordermanage", message = message))
def serviceadd(): 'Add a service order; restrict to admin or sales only.' # check if user is login and check if role is admin or sales if 'role' not in session.keys() or session['role'] not in ['Admin','Sales']: return redirect(url_for("home")) # service add template data vin_search = '' vin_status = 0 vin_match = [] vin_ord = None vin_car = None vin_cus = None # user submit a VIN if request.method == 'POST': if validate_table(serviceadd_ft, request.form): # extract form entries vin = request.form[serviceadd_ft[0]] cid = request.form[serviceadd_ft[1]] sdesc = request.form[serviceadd_ft[2]] scost = request.form[serviceadd_ft[3]] sdate = request.form[serviceadd_ft[4]] message = '' # double check the form car = Car.query.filter_by(vin = vin).first() if car: customer = CustomerInfo.query.filter_by(cid = cid).first() if customer: new_service = ServiceInfo(cid, vin, sdesc, scost, sdate) db.session.add(new_service) db.session.commit() message = 'Customer service added; review the car management list.' else: message = 'Customer service failed; customer({}) cannot be found.'.format(cid) else: message = 'Customer service failed; car({}) cannot be found.'.format(vin) service_list = ServiceInfo.query.paginate(1, 10, False) return render_template("servicetemps/servicemanage.html", service_list = service_list, message = message) # user supplying the vin (searching) if vin_cache == True and 'vin' in request.form: vin_search = request.form['vin'] if 16 <= len(vin_search) <= 18: # check if vin is in vin table if vin_search in vin_table: vin_car = Car.query.filter_by(vin = vin_search).first() # check if car exist if vin_car != None: vin_ord = OrderInfo.query.filter_by(vin = vin_search).first() # check if car solded if vin_ord != None: vin_cus = CustomerInfo.query.filter_by(cid = vin_ord.cid).first() # check if customer exist if vin_cus != None: vin_status = 1 # check possible matches else: for vin in vin_table: if editdistance(vin, vin_search) <= 2: vin_match.append(vin) if len(vin_match) > 5: break if len(vin_match): vin_status = 2 return render_template('servicetemps/serviceadd.html', info = [vin_search, vin_status, vin_match, vin_ord, vin_cus, vin_car]) # display initial user form return render_template('servicetemps/serviceadd.html')