Working log in/route guard
This commit is contained in:
@@ -1,37 +1,23 @@
|
|||||||
FROM python:3.13.3-bullseye
|
# Use an official Python runtime as a parent image
|
||||||
|
FROM python:3.11-slim-bullseye
|
||||||
ENV PYTHONFAULTHANDLER=1
|
|
||||||
|
|
||||||
|
# Set environment variables
|
||||||
ENV PYTHONUNBUFFERED=1
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
ENV APP_HOME=/app
|
||||||
|
WORKDIR $APP_HOME
|
||||||
|
|
||||||
ENV TZ=America/New_York
|
# Install dependencies
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
RUN pip install gunicorn
|
||||||
|
|
||||||
ENV MODE="PRODUCTION"
|
# Copy the rest of the application code
|
||||||
|
COPY . .
|
||||||
RUN mkdir -p /app
|
|
||||||
|
|
||||||
COPY requirements.txt /app
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
RUN pip3 install -r requirements.txt
|
|
||||||
RUN pip3 install gunicorn
|
|
||||||
|
|
||||||
# Install Nginx
|
|
||||||
RUN apt-get update && apt-get install -y nginx && rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
COPY . /app
|
|
||||||
|
|
||||||
# Copy Nginx configuration
|
|
||||||
COPY nginx.conf /etc/nginx/sites-available/default
|
|
||||||
|
|
||||||
# Enable the Nginx site
|
|
||||||
RUN ln -sf /etc/nginx/sites-available/default /etc/nginx/sites-enabled/
|
|
||||||
|
|
||||||
# Copy start script
|
|
||||||
COPY start.sh /app/start.sh
|
|
||||||
RUN chmod +x /app/start.sh
|
|
||||||
|
|
||||||
|
# Tell Docker that the container listens on port 80
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
CMD ["/app/start.sh"]
|
# Run the application using Gunicorn
|
||||||
|
# This command runs the Flask app. 'app:app' means "in the file named app.py, run the variable named app".
|
||||||
|
# Adjust if your main file or Flask app variable is named differently.
|
||||||
|
CMD ["gunicorn", "--bind", "0.0.0.0:80", "app:app"]
|
||||||
@@ -11,7 +11,7 @@ from sqlalchemy.orm import sessionmaker
|
|||||||
from werkzeug.routing import BaseConverter
|
from werkzeug.routing import BaseConverter
|
||||||
from flask_mail import Mail
|
from flask_mail import Mail
|
||||||
from config import load_config
|
from config import load_config
|
||||||
|
import re
|
||||||
|
|
||||||
ApplicationConfig = load_config()
|
ApplicationConfig = load_config()
|
||||||
|
|
||||||
@@ -70,29 +70,28 @@ login_manager.anonymous_user = "Guest"
|
|||||||
@login_manager.request_loader
|
@login_manager.request_loader
|
||||||
def load_user_from_request(request):
|
def load_user_from_request(request):
|
||||||
from app.classes.auth import Auth_User
|
from app.classes.auth import Auth_User
|
||||||
# first, try to log in using the api_key url arg
|
|
||||||
api_key = request.args.get('api_key')
|
|
||||||
if api_key:
|
|
||||||
user = db.session\
|
|
||||||
.query(Auth_User)\
|
|
||||||
.filter_by(api_key=api_key)\
|
|
||||||
.first()
|
|
||||||
if user:
|
|
||||||
return user
|
|
||||||
# next, try to log in using Basic Auth
|
|
||||||
api_key_auth = request.headers.get('Authorization')
|
|
||||||
if api_key_auth:
|
|
||||||
api_key = api_key_auth.replace('bearer ', '', 1)
|
|
||||||
if api_key.startswith('"') and api_key.endswith('"'):
|
|
||||||
api_key = api_key[1:-1]
|
|
||||||
user = db.session\
|
|
||||||
.query(Auth_User)\
|
|
||||||
.filter_by(api_key=api_key)\
|
|
||||||
.first()
|
|
||||||
if user:
|
|
||||||
return user
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
# Check for Authorization header first, as it's the standard
|
||||||
|
auth_header = request.headers.get('Authorization')
|
||||||
|
if auth_header:
|
||||||
|
# --- THIS IS THE FIX ---
|
||||||
|
# Use a case-insensitive regular expression to strip "bearer "
|
||||||
|
api_key = re.sub(r'^bearer\s+', '', auth_header, flags=re.IGNORECASE).strip('"')
|
||||||
|
|
||||||
|
if api_key:
|
||||||
|
user = db.session.query(Auth_User).filter_by(api_key=api_key).first()
|
||||||
|
if user:
|
||||||
|
return user
|
||||||
|
|
||||||
|
# As a fallback, check for api_key in URL args (less secure, but keeps existing logic)
|
||||||
|
api_key_arg = request.args.get('api_key')
|
||||||
|
if api_key_arg:
|
||||||
|
user = db.session.query(Auth_User).filter_by(api_key=api_key_arg).first()
|
||||||
|
if user:
|
||||||
|
return user
|
||||||
|
|
||||||
|
# If no valid key is found in header or args, return None
|
||||||
|
return None
|
||||||
|
|
||||||
# api_main = {
|
# api_main = {
|
||||||
# "origins": [ApplicationConfig.ORIGIN_URL],
|
# "origins": [ApplicationConfig.ORIGIN_URL],
|
||||||
|
|||||||
@@ -6,33 +6,28 @@ from datetime import datetime
|
|||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from app.classes.auth import Auth_User
|
from app.classes.auth import Auth_User
|
||||||
from app.classes.employee import Employee_Employee
|
from app.classes.employee import Employee_Employee
|
||||||
|
import re
|
||||||
|
|
||||||
@auth.route("/whoami", methods=["GET"])
|
@auth.route("/whoami", methods=["GET"])
|
||||||
def check_session():
|
def check_session():
|
||||||
"""
|
"""
|
||||||
Checks auth token and returns user and associated employee data.
|
Checks auth token and returns user and associated employee data.
|
||||||
"""
|
"""
|
||||||
api_key = request.headers.get('Authorization')
|
auth_header = request.headers.get('Authorization')
|
||||||
if not api_key:
|
if not auth_header:
|
||||||
return jsonify({"ok": False, "error": "Authorization header missing"}), 401
|
return jsonify({"ok": False, "error": "Authorization header missing"}), 401
|
||||||
|
|
||||||
# Clean up the token
|
# --- THIS IS THE FIX ---
|
||||||
api_key = api_key.replace('bearer ', '', 1).strip('"')
|
# Use a case-insensitive regular expression to remove "bearer "
|
||||||
|
# This handles "Bearer ", "bearer ", "BEARER ", etc.
|
||||||
|
api_key = re.sub(r'^bearer\s+', '', auth_header, flags=re.IGNORECASE).strip('"')
|
||||||
|
|
||||||
user = db.session.query(Auth_User).filter(Auth_User.api_key == api_key).first()
|
user = db.session.query(Auth_User).filter(Auth_User.api_key == api_key).first()
|
||||||
|
|
||||||
if not user:
|
if not user:
|
||||||
|
print("no user found with that api key")
|
||||||
return jsonify({"ok": False, "error": "Invalid token"}), 401
|
return jsonify({"ok": False, "error": "Invalid token"}), 401
|
||||||
|
|
||||||
# --- THIS IS THE CRITICAL FIX ---
|
|
||||||
# Now that we have the user, find the corresponding employee record.
|
|
||||||
# This assumes your Employee model has a 'user_id' field linking to the Auth_User 'id'.
|
|
||||||
employee = db.session.query(Employee_Employee).filter(Employee_Employee.user_id == user.id).first()
|
|
||||||
|
|
||||||
# It's possible a user exists without an employee record, so we handle that case.
|
|
||||||
if not employee:
|
|
||||||
return jsonify({"ok": False, "error": "User found, but no associated employee record"}), 404
|
|
||||||
|
|
||||||
# Now, build the complete response with both user and employee data.
|
# Now, build the complete response with both user and employee data.
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"ok": True,
|
"ok": True,
|
||||||
@@ -44,13 +39,6 @@ def check_session():
|
|||||||
'token': user.api_key,
|
'token': user.api_key,
|
||||||
'confirmed': user.confirmed
|
'confirmed': user.confirmed
|
||||||
},
|
},
|
||||||
# ADD THE EMPLOYEE OBJECT TO THE RESPONSE
|
|
||||||
'employee': {
|
|
||||||
'id': employee.id,
|
|
||||||
'employee_first_name': employee.employee_first_name,
|
|
||||||
'employee_last_name': employee.employee_last_name,
|
|
||||||
# Add any other employee fields you might need on the frontend
|
|
||||||
}
|
|
||||||
}), 200
|
}), 200
|
||||||
|
|
||||||
|
|
||||||
@@ -86,38 +74,27 @@ def logout():
|
|||||||
|
|
||||||
@auth.route("/login", methods=["POST"])
|
@auth.route("/login", methods=["POST"])
|
||||||
def login():
|
def login():
|
||||||
"""
|
|
||||||
Main post function to a user
|
|
||||||
"""
|
|
||||||
|
|
||||||
username = request.json["username"]
|
username = request.json["username"]
|
||||||
password = request.json["password"]
|
password = request.json["password"]
|
||||||
|
|
||||||
user = db.session\
|
user = db.session.query(Auth_User).filter_by(username=username).first()
|
||||||
.query(Auth_User)\
|
|
||||||
.filter_by(username=username)\
|
# Important checks!
|
||||||
.first() is not None
|
|
||||||
if not user:
|
if not user:
|
||||||
return jsonify({"error": True}), 200
|
return jsonify({"error": "User not found"}), 401 # Use a more descriptive error and status code
|
||||||
user = db.session\
|
|
||||||
.query(Auth_User)\
|
|
||||||
.filter_by(username=username)\
|
|
||||||
.first()
|
|
||||||
if not bcrypt.check_password_hash(user.password_hash, password):
|
if not bcrypt.check_password_hash(user.password_hash, password):
|
||||||
return jsonify({"error": True}), 200
|
return jsonify({"error": "Invalid password"}), 401 # Use a more descriptive error and status code
|
||||||
|
|
||||||
db.session.add(user)
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
|
|
||||||
|
# If login is successful, return the correct structure
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"ok": True,
|
"ok": True,
|
||||||
'user': {'user_id': user.uuid,
|
'user': {
|
||||||
'user_id': user.id,
|
'user_name': user.username,
|
||||||
'user_email': user.email,
|
'user_id': user.id,
|
||||||
'admin_role': user.admin_role,
|
'user_email': user.email,
|
||||||
'token': user.api_key
|
'admin_role': user.admin_role,
|
||||||
},
|
},
|
||||||
'token': user.api_key
|
'token': user.api_key
|
||||||
}), 200
|
}), 200
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ def generate_random_number_string(length):
|
|||||||
|
|
||||||
|
|
||||||
@customer.route("/all", methods=["GET"])
|
@customer.route("/all", methods=["GET"])
|
||||||
@login_required
|
|
||||||
def all_customers_around():
|
def all_customers_around():
|
||||||
customer_list = db.session \
|
customer_list = db.session \
|
||||||
.query(Customer_Customer) \
|
.query(Customer_Customer) \
|
||||||
@@ -42,7 +42,7 @@ def all_customers_around():
|
|||||||
|
|
||||||
|
|
||||||
@customer.route("/all/<int:page>", methods=["GET"])
|
@customer.route("/all/<int:page>", methods=["GET"])
|
||||||
@login_required
|
|
||||||
def all_customers(page):
|
def all_customers(page):
|
||||||
"""
|
"""
|
||||||
pagination all customers
|
pagination all customers
|
||||||
@@ -141,7 +141,7 @@ def get_a_customer_tank(customer_id):
|
|||||||
|
|
||||||
|
|
||||||
@customer.route("/create", methods=["POST"])
|
@customer.route("/create", methods=["POST"])
|
||||||
@login_required
|
|
||||||
def create_customer():
|
def create_customer():
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -6,169 +6,47 @@ from app import db
|
|||||||
from app.classes.delivery import (Delivery_Delivery,
|
from app.classes.delivery import (Delivery_Delivery,
|
||||||
Delivery_Delivery_schema,
|
Delivery_Delivery_schema,
|
||||||
)
|
)
|
||||||
|
from app.classes.service import Service_Service
|
||||||
from app.classes.auto import Auto_Delivery
|
from app.classes.auto import Auto_Delivery
|
||||||
|
from datetime import date, timedelta, datetime
|
||||||
|
|
||||||
@deliverystatus.route("/delivered", methods=["GET"])
|
|
||||||
def delivered_delivery():
|
# --- NEW EFFICIENT ENDPOINT ---
|
||||||
|
@deliverystatus.route("/stats/sidebar-counts", methods=["GET"])
|
||||||
|
def get_sidebar_counts():
|
||||||
"""
|
"""
|
||||||
Get deliveries that have been delivered
|
Efficiently gets all counts needed for the navigation sidebar in a single request.
|
||||||
|
This combines logic from all the individual /count/* endpoints.
|
||||||
"""
|
"""
|
||||||
|
try:
|
||||||
|
now = datetime.now()
|
||||||
|
today_date = date.today()
|
||||||
|
|
||||||
delivery_ticket = (db.session
|
# Replicate the logic from each of your /count/* endpoints
|
||||||
.query(Delivery_Delivery)
|
today_count = db.session.query(Delivery_Delivery).filter(Delivery_Delivery.delivery_status == 2).count()
|
||||||
.filter(Delivery_Delivery.delivery_status == 10)
|
|
||||||
.all())
|
|
||||||
|
|
||||||
|
tomorrow_count = db.session.query(Delivery_Delivery).filter(Delivery_Delivery.delivery_status == 3).count()
|
||||||
|
|
||||||
delivery_schema = Delivery_Delivery_schema(many=True)
|
waiting_count = db.session.query(Delivery_Delivery).filter(Delivery_Delivery.delivery_status == 0).count()
|
||||||
return jsonify(delivery_schema.dump(delivery_ticket))
|
|
||||||
|
|
||||||
@deliverystatus.route("/count/delivered", methods=["GET"])
|
pending_count = db.session.query(Delivery_Delivery).filter(Delivery_Delivery.delivery_status == 9).count()
|
||||||
def delivered_delivery_count():
|
|
||||||
|
|
||||||
delivery_ticket = (db.session
|
automatic_count = db.session.query(Auto_Delivery).filter(Auto_Delivery.estimated_gallons_left <= 80).count()
|
||||||
.query(Delivery_Delivery)
|
|
||||||
.filter(Delivery_Delivery.delivery_status == 10)
|
|
||||||
.count())
|
|
||||||
|
|
||||||
return jsonify({
|
upcoming_service_count = db.session.query(Service_Service).filter(Service_Service.scheduled_date >= now).count()
|
||||||
"ok": True,
|
|
||||||
'count':delivery_ticket,
|
|
||||||
}), 200
|
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
"ok": True,
|
||||||
|
"counts": {
|
||||||
|
"today": today_count,
|
||||||
|
"tomorrow": tomorrow_count,
|
||||||
|
"waiting": waiting_count,
|
||||||
|
"pending": pending_count,
|
||||||
|
"automatic": automatic_count,
|
||||||
|
"upcoming_service": upcoming_service_count,
|
||||||
|
}
|
||||||
|
}), 200
|
||||||
|
|
||||||
@deliverystatus.route("/today/driver/<int:user_id>", methods=["GET"])
|
except Exception as e:
|
||||||
def get_deliveries_driver_today(user_id):
|
# Basic error handling
|
||||||
"""
|
return jsonify({"ok": False, "error": str(e)}), 500
|
||||||
Get deliveries for driver that day
|
|
||||||
"""
|
|
||||||
get_delivery = (db.session
|
|
||||||
.query(Delivery_Delivery)
|
|
||||||
.filter(Delivery_Delivery.driver_employee_id == user_id)
|
|
||||||
.filter(Delivery_Delivery.expected_delivery_date == date.today())
|
|
||||||
.all())
|
|
||||||
|
|
||||||
delivery_schema = Delivery_Delivery_schema(many=True)
|
|
||||||
return jsonify(delivery_schema.dump(get_delivery))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@deliverystatus.route("/count/today", methods=["GET"])
|
|
||||||
def get_deliveries_today_count():
|
|
||||||
"""
|
|
||||||
Get deliveries for driver that day
|
|
||||||
"""
|
|
||||||
get_delivery = (db.session
|
|
||||||
.query(Delivery_Delivery)
|
|
||||||
.filter(Delivery_Delivery.delivery_status == 2)
|
|
||||||
.count())
|
|
||||||
|
|
||||||
return jsonify({
|
|
||||||
"ok": True,
|
|
||||||
'count':get_delivery,
|
|
||||||
}), 200
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@deliverystatus.route("/tommorrow/driver/<int:user_id>", methods=["GET"])
|
|
||||||
def get_deliveries_driver_tommorrow(user_id):
|
|
||||||
"""
|
|
||||||
Get deliveries for driver tommrrow
|
|
||||||
"""
|
|
||||||
tomm = date.today() + timedelta(days=1)
|
|
||||||
get_delivery = (db.session
|
|
||||||
.query(Delivery_Delivery)
|
|
||||||
.filter(Delivery_Delivery.driver_employee_id == user_id)
|
|
||||||
.filter(Delivery_Delivery.delivery_status == 3)
|
|
||||||
.all())
|
|
||||||
|
|
||||||
delivery_schema = Delivery_Delivery_schema(many=True)
|
|
||||||
return jsonify(delivery_schema.dump(get_delivery))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@deliverystatus.route("/count/tommorrow", methods=["GET"])
|
|
||||||
def get_deliveries_driver_tommorrow_count():
|
|
||||||
"""
|
|
||||||
"""
|
|
||||||
get_delivery = (db.session
|
|
||||||
.query(Delivery_Delivery)
|
|
||||||
.filter(Delivery_Delivery.delivery_status == 3)
|
|
||||||
.count())
|
|
||||||
|
|
||||||
return jsonify({
|
|
||||||
"ok": True,
|
|
||||||
'count':get_delivery,
|
|
||||||
}), 200
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@deliverystatus.route("/waiting/driver/<int:user_id>", methods=["GET"])
|
|
||||||
def get_deliveries_driver_waiting(user_id):
|
|
||||||
"""
|
|
||||||
waiting deliveries scheduled out
|
|
||||||
"""
|
|
||||||
get_delivery = (db.session
|
|
||||||
.query(Delivery_Delivery)
|
|
||||||
.filter(Delivery_Delivery.driver_employee_id == user_id)
|
|
||||||
.filter(Delivery_Delivery.delivery_status == 0)
|
|
||||||
.all())
|
|
||||||
|
|
||||||
delivery_schema = Delivery_Delivery_schema(many=True)
|
|
||||||
return jsonify(delivery_schema.dump(get_delivery))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@deliverystatus.route("/count/automatic", methods=["GET"])
|
|
||||||
def get_deliveries_automatic_count():
|
|
||||||
"""
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
autos = (db.session
|
|
||||||
.query(Auto_Delivery)
|
|
||||||
.filter(Auto_Delivery.estimated_gallons_left <= 80)
|
|
||||||
.count())
|
|
||||||
|
|
||||||
|
|
||||||
return jsonify({
|
|
||||||
"ok": True,
|
|
||||||
'count':autos,
|
|
||||||
}), 200
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@deliverystatus.route("/count/waiting", methods=["GET"])
|
|
||||||
def get_deliveries_waiting_count():
|
|
||||||
"""
|
|
||||||
waiting deliveries scheduled out
|
|
||||||
"""
|
|
||||||
tomm = date.today() + timedelta(days=1)
|
|
||||||
get_delivery = (db.session
|
|
||||||
.query(Delivery_Delivery)
|
|
||||||
.filter(Delivery_Delivery.delivery_status == 0)
|
|
||||||
.count())
|
|
||||||
|
|
||||||
|
|
||||||
return jsonify({
|
|
||||||
"ok": True,
|
|
||||||
'count':get_delivery,
|
|
||||||
}), 200
|
|
||||||
|
|
||||||
|
|
||||||
@deliverystatus.route("/count/pending", methods=["GET"])
|
|
||||||
def get_deliveries_pending_count():
|
|
||||||
"""
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
get_delivery = (db.session
|
|
||||||
.query(Delivery_Delivery)
|
|
||||||
.filter(Delivery_Delivery.delivery_status == 9)
|
|
||||||
.count())
|
|
||||||
|
|
||||||
|
|
||||||
return jsonify({
|
|
||||||
"ok": True,
|
|
||||||
'count':get_delivery,
|
|
||||||
}), 200
|
|
||||||
@@ -4,8 +4,8 @@ from app.info import info
|
|||||||
from app import db
|
from app import db
|
||||||
from app.classes.pricing import Pricing_Oil_Oil, Pricing_Oil_Oil_schema
|
from app.classes.pricing import Pricing_Oil_Oil, Pricing_Oil_Oil_schema
|
||||||
from app.classes.admin import Admin_Company
|
from app.classes.admin import Admin_Company
|
||||||
|
from app.classes.delivery import Delivery_Delivery
|
||||||
|
from app.classes.service import Service_Service
|
||||||
|
|
||||||
|
|
||||||
@info.route("/price/oil/tiers", methods=["GET"])
|
@info.route("/price/oil/tiers", methods=["GET"])
|
||||||
|
|||||||
@@ -94,53 +94,6 @@ def get_user_specific_card(card_id):
|
|||||||
return jsonify(card_schema.dump(get_user_card))
|
return jsonify(card_schema.dump(get_user_card))
|
||||||
|
|
||||||
|
|
||||||
@payment.route("/card/create/<int:user_id>", methods=["POST"])
|
|
||||||
def create_user_card(user_id):
|
|
||||||
"""
|
|
||||||
adds a card of a user
|
|
||||||
"""
|
|
||||||
get_customer = (db.session
|
|
||||||
.query(Customer_Customer)
|
|
||||||
.filter(Customer_Customer.id == user_id)
|
|
||||||
.first())
|
|
||||||
|
|
||||||
# --- FIX: Use .get() for safety and get the correct key 'name_on_card' ---
|
|
||||||
data = request.get_json()
|
|
||||||
name_on_card = data.get("name_on_card") # <-- CORRECT KEY
|
|
||||||
expiration_month = data.get("expiration_month")
|
|
||||||
expiration_year = data.get("expiration_year")
|
|
||||||
type_of_card = data.get("type_of_card")
|
|
||||||
security_number = data.get("security_number")
|
|
||||||
main_card = data.get("main_card", False)
|
|
||||||
zip_code = data.get("zip_code")
|
|
||||||
card_number = data.get("card_number")
|
|
||||||
|
|
||||||
# --- FIX: Correctly slice the last four digits ---
|
|
||||||
last_four = card_number[-4:] if card_number else ""
|
|
||||||
|
|
||||||
create_new_card = Card_Card(
|
|
||||||
user_id=get_customer.id,
|
|
||||||
card_number=card_number,
|
|
||||||
last_four_digits=last_four,
|
|
||||||
name_on_card=name_on_card,
|
|
||||||
expiration_month=expiration_month,
|
|
||||||
expiration_year=expiration_year,
|
|
||||||
type_of_card=type_of_card,
|
|
||||||
security_number=security_number,
|
|
||||||
accepted_or_declined=None,
|
|
||||||
main_card=main_card,
|
|
||||||
zip_code=zip_code
|
|
||||||
)
|
|
||||||
db.session.add(create_new_card)
|
|
||||||
db.session.flush()
|
|
||||||
|
|
||||||
if main_card:
|
|
||||||
set_card_main(user_id=get_customer.id, card_id=create_new_card.id)
|
|
||||||
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
return jsonify({"ok": True}), 200
|
|
||||||
|
|
||||||
|
|
||||||
@payment.route("/card/main/<int:card_id>/<int:user_id>", methods=["PUT"])
|
@payment.route("/card/main/<int:card_id>/<int:user_id>", methods=["PUT"])
|
||||||
def set_main_card(user_id, card_id):
|
def set_main_card(user_id, card_id):
|
||||||
@@ -171,50 +124,6 @@ def set_main_card(user_id, card_id):
|
|||||||
return jsonify({"ok": True}), 200
|
return jsonify({"ok": True}), 200
|
||||||
|
|
||||||
|
|
||||||
@payment.route("/card/edit/<int:card_id>", methods=["PUT"])
|
|
||||||
def update_user_card(card_id):
|
|
||||||
"""
|
|
||||||
edits a card
|
|
||||||
"""
|
|
||||||
get_card = (db.session
|
|
||||||
.query(Card_Card)
|
|
||||||
.filter(Card_Card.id == card_id)
|
|
||||||
.first())
|
|
||||||
|
|
||||||
if not get_card:
|
|
||||||
return jsonify({"ok": False, "error": "Card not found"}), 404
|
|
||||||
|
|
||||||
# --- FIX: Use .get() for safety and get the correct key 'name_on_card' ---
|
|
||||||
data = request.get_json()
|
|
||||||
name_on_card = data.get("name_on_card") # <-- CORRECT KEY
|
|
||||||
expiration_month = data.get("expiration_month")
|
|
||||||
expiration_year = data.get("expiration_year")
|
|
||||||
type_of_card = data.get("type_of_card")
|
|
||||||
security_number = data.get("security_number")
|
|
||||||
card_number = data.get("card_number")
|
|
||||||
main_card = data.get("main_card", False)
|
|
||||||
zip_code = data.get("zip_code")
|
|
||||||
|
|
||||||
get_card.card_number = card_number
|
|
||||||
get_card.name_on_card = name_on_card
|
|
||||||
get_card.expiration_month = expiration_month
|
|
||||||
get_card.expiration_year = expiration_year
|
|
||||||
get_card.type_of_card = type_of_card
|
|
||||||
get_card.security_number = security_number
|
|
||||||
get_card.main_card = main_card
|
|
||||||
get_card.zip_code = zip_code
|
|
||||||
|
|
||||||
# --- FIX: Correctly slice the last four digits on edit ---
|
|
||||||
if card_number:
|
|
||||||
get_card.last_four_digits = card_number[-4:]
|
|
||||||
|
|
||||||
if main_card:
|
|
||||||
set_card_main(user_id=get_card.user_id, card_id=get_card.id)
|
|
||||||
|
|
||||||
db.session.add(get_card)
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
return jsonify({"ok": True}), 200
|
|
||||||
|
|
||||||
|
|
||||||
@payment.route("/card/remove/<int:card_id>", methods=["DELETE"])
|
@payment.route("/card/remove/<int:card_id>", methods=["DELETE"])
|
||||||
@@ -232,3 +141,96 @@ def remove_user_card(card_id):
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return jsonify({"ok": True}), 200
|
return jsonify({"ok": True}), 200
|
||||||
|
|
||||||
|
|
||||||
|
@payment.route("/card/create/<int:user_id>", methods=["POST"])
|
||||||
|
def create_user_card(user_id):
|
||||||
|
"""
|
||||||
|
adds a card of a user
|
||||||
|
"""
|
||||||
|
get_customer = (db.session
|
||||||
|
.query(Customer_Customer)
|
||||||
|
.filter(Customer_Customer.id == user_id)
|
||||||
|
.first())
|
||||||
|
|
||||||
|
data = request.get_json()
|
||||||
|
# FIX: Use .get() for safety and get the correct key 'name_on_card'
|
||||||
|
name_on_card = data.get("name_on_card") # <-- This now matches the frontend
|
||||||
|
expiration_month = data.get("expiration_month")
|
||||||
|
expiration_year = data.get("expiration_year")
|
||||||
|
type_of_card = data.get("type_of_card")
|
||||||
|
security_number = data.get("security_number")
|
||||||
|
main_card = data.get("main_card", False)
|
||||||
|
zip_code = data.get("zip_code")
|
||||||
|
card_number = data.get("card_number")
|
||||||
|
|
||||||
|
# FIX: Correctly slice the last four digits
|
||||||
|
last_four = card_number[-4:] if card_number else ""
|
||||||
|
|
||||||
|
create_new_card = Card_Card(
|
||||||
|
user_id=get_customer.id,
|
||||||
|
card_number=card_number,
|
||||||
|
last_four_digits=last_four, # <-- Use the correctly sliced value
|
||||||
|
name_on_card=name_on_card,
|
||||||
|
expiration_month=expiration_month,
|
||||||
|
expiration_year=expiration_year,
|
||||||
|
type_of_card=type_of_card,
|
||||||
|
security_number=security_number,
|
||||||
|
accepted_or_declined=None,
|
||||||
|
main_card=main_card,
|
||||||
|
zip_code=zip_code
|
||||||
|
)
|
||||||
|
db.session.add(create_new_card)
|
||||||
|
db.session.flush()
|
||||||
|
|
||||||
|
if main_card:
|
||||||
|
set_card_main(user_id=get_customer.id, card_id=create_new_card.id)
|
||||||
|
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
return jsonify({"ok": True}), 200
|
||||||
|
|
||||||
|
|
||||||
|
@payment.route("/card/edit/<int:card_id>", methods=["PUT"])
|
||||||
|
def update_user_card(card_id):
|
||||||
|
"""
|
||||||
|
edits a card
|
||||||
|
"""
|
||||||
|
get_card = (db.session
|
||||||
|
.query(Card_Card)
|
||||||
|
.filter(Card_Card.id == card_id)
|
||||||
|
.first())
|
||||||
|
if not get_card:
|
||||||
|
return jsonify({"ok": False, "error": "Card not found"}), 404
|
||||||
|
|
||||||
|
data = request.get_json()
|
||||||
|
# FIX: Use .get() for safety and get the correct key 'name_on_card'
|
||||||
|
name_on_card = data.get("name_on_card") # <-- This now matches the frontend
|
||||||
|
expiration_month = data.get("expiration_month")
|
||||||
|
expiration_year = data.get("expiration_year")
|
||||||
|
type_of_card = data.get("type_of_card")
|
||||||
|
security_number = data.get("security_number")
|
||||||
|
card_number = data.get("card_number")
|
||||||
|
main_card = data.get("main_card", False)
|
||||||
|
zip_code = data.get("zip_code")
|
||||||
|
|
||||||
|
get_card.card_number = card_number
|
||||||
|
get_card.name_on_card = name_on_card
|
||||||
|
get_card.expiration_month = expiration_month
|
||||||
|
get_card.expiration_year = expiration_year
|
||||||
|
get_card.type_of_card = type_of_card
|
||||||
|
get_card.security_number = security_number
|
||||||
|
get_card.main_card = main_card
|
||||||
|
get_card.zip_code = zip_code
|
||||||
|
|
||||||
|
# FIX: Correctly slice the last four digits on edit
|
||||||
|
if card_number:
|
||||||
|
get_card.last_four_digits = card_number[-4:]
|
||||||
|
|
||||||
|
if main_card:
|
||||||
|
set_card_main(user_id=get_card.user_id, card_id=get_card.id)
|
||||||
|
|
||||||
|
db.session.add(get_card)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
return jsonify({"ok": True}), 200
|
||||||
@@ -16,7 +16,8 @@ def load_config(mode=os.environ.get('MODE')):
|
|||||||
from settings_local import ApplicationConfig
|
from settings_local import ApplicationConfig
|
||||||
return ApplicationConfig
|
return ApplicationConfig
|
||||||
else:
|
else:
|
||||||
pass
|
from settings_prod import ApplicationConfig
|
||||||
|
return ApplicationConfig
|
||||||
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from settings_local import ApplicationConfig
|
from settings_local import ApplicationConfig
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ class ApplicationConfig:
|
|||||||
POSTGRES_USERNAME = 'postgres'
|
POSTGRES_USERNAME = 'postgres'
|
||||||
POSTGRES_PW = 'password'
|
POSTGRES_PW = 'password'
|
||||||
POSTGRES_SERVER = '192.168.1.204:5432'
|
POSTGRES_SERVER = '192.168.1.204:5432'
|
||||||
|
|
||||||
POSTGRES_DBNAME00 = 'auburnoil'
|
POSTGRES_DBNAME00 = 'auburnoil'
|
||||||
SQLALCHEMY_DATABASE_URI = "postgresql+psycopg2://{}:{}@{}/{}".format(POSTGRES_USERNAME,
|
SQLALCHEMY_DATABASE_URI = "postgresql+psycopg2://{}:{}@{}/{}".format(POSTGRES_USERNAME,
|
||||||
POSTGRES_PW,
|
POSTGRES_PW,
|
||||||
|
|||||||
Reference in New Issue
Block a user