dn-scribe commited on
Commit
fc6941c
·
1 Parent(s): f26e1ec

Add user id to products model and apis

Browse files
Files changed (5) hide show
  1. api/evidence.py +1 -1
  2. models.py +4 -0
  3. templates/products.html +8 -0
  4. web/products.py +14 -6
  5. web/routes.py +10 -2
api/evidence.py CHANGED
@@ -682,7 +682,7 @@ def finish_attestation():
682
  from web.products import update_product_data
683
  product_key = attestation.product_key
684
  product_version = attestation.product_version
685
- update_product_data(product_key, product_version)
686
 
687
  # Return response matching swagger spec
688
  return jsonify({
 
682
  from web.products import update_product_data
683
  product_key = attestation.product_key
684
  product_version = attestation.product_version
685
+ update_product_data(product_key, product_version, user_id=attestation.user_id)
686
 
687
  # Return response matching swagger spec
688
  return jsonify({
models.py CHANGED
@@ -386,6 +386,7 @@ class Product(db.Model):
386
  id = db.Column(Integer, primary_key=True)
387
  product_key = db.Column(String(255), nullable=False)
388
  product_version = db.Column(String(255), nullable=False)
 
389
  name = db.Column(String(255), nullable=True)
390
  description = db.Column(Text, nullable=True)
391
  product_metadata = db.Column(MutableDict.as_mutable(JSON), nullable=True)
@@ -394,6 +395,8 @@ class Product(db.Model):
394
  updated_at = db.Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
395
  deleted = db.Column(Boolean, default=False)
396
 
 
 
397
  __table_args__ = (
398
  db.UniqueConstraint('product_key', 'product_version', name='uq_product_key_version'),
399
  )
@@ -403,6 +406,7 @@ class Product(db.Model):
403
  'id': self.id,
404
  'product_key': self.product_key,
405
  'product_version': self.product_version,
 
406
  'name': self.name,
407
  'description': self.description,
408
  'product_metadata': self.product_metadata,
 
386
  id = db.Column(Integer, primary_key=True)
387
  product_key = db.Column(String(255), nullable=False)
388
  product_version = db.Column(String(255), nullable=False)
389
+ user_id = db.Column(Integer, ForeignKey('users.id'), nullable=False)
390
  name = db.Column(String(255), nullable=True)
391
  description = db.Column(Text, nullable=True)
392
  product_metadata = db.Column(MutableDict.as_mutable(JSON), nullable=True)
 
395
  updated_at = db.Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
396
  deleted = db.Column(Boolean, default=False)
397
 
398
+ user = relationship("User", backref="products")
399
+
400
  __table_args__ = (
401
  db.UniqueConstraint('product_key', 'product_version', name='uq_product_key_version'),
402
  )
 
406
  'id': self.id,
407
  'product_key': self.product_key,
408
  'product_version': self.product_version,
409
+ 'user_id': self.user_id,
410
  'name': self.name,
411
  'description': self.description,
412
  'product_metadata': self.product_metadata,
templates/products.html CHANGED
@@ -22,6 +22,14 @@
22
  <div class="col-md-4">
23
  <input type="text" class="form-control" name="filter" placeholder="Products substring" value="{{ filter_query }}">
24
  </div>
 
 
 
 
 
 
 
 
25
  <div class="col-md-2">
26
  <button type="submit" class="btn btn-primary w-100">
27
  <i data-feather="filter" class="me-1"></i> Filter
 
22
  <div class="col-md-4">
23
  <input type="text" class="form-control" name="filter" placeholder="Products substring" value="{{ filter_query }}">
24
  </div>
25
+ {% if is_admin %}
26
+ <div class="col-md-3 form-check align-items-center d-flex">
27
+ <input class="form-check-input me-2" type="checkbox" id="showAllCheckbox" name="show_all" value="1" {% if show_all %}checked{% endif %} onchange="this.form.submit()">
28
+ <label class="form-check-label" for="showAllCheckbox">
29
+ Show all users' products
30
+ </label>
31
+ </div>
32
+ {% endif %}
33
  <div class="col-md-2">
34
  <button type="submit" class="btn btn-primary w-100">
35
  <i data-feather="filter" class="me-1"></i> Filter
web/products.py CHANGED
@@ -1,10 +1,12 @@
1
- from flask import Blueprint, render_template, request, redirect, url_for
2
  from models import db, Attestation, PolicyResult, Product
3
  from sqlalchemy import func, text
4
 
5
- def get_products_with_stats(filter_query=None):
6
  # Only consume data from products table
7
  query = Product.query.filter(Product.deleted == False)
 
 
8
  if filter_query:
9
  like_pattern = f'%{filter_query}%'
10
  query = query.filter(
@@ -42,16 +44,22 @@ def get_products_with_stats(filter_query=None):
42
  'attestation_count': attestation_count,
43
  'policy_result_count': policy_result_count,
44
  'badges': badges,
45
- 'product_metadata': product.product_metadata
 
46
  })
47
  return products, pagination
48
  return products
49
 
50
  # Function to update product data
51
- def update_product_data(product_key, product_version, name=None, description=None, metadata=None, badges=None):
52
- product = Product.query.filter_by(product_key=product_key, product_version=product_version, deleted=False).first()
 
 
 
 
 
53
  if not product:
54
- product = Product(product_key=product_key, product_version=product_version)
55
  db.session.add(product)
56
  if name is not None:
57
  product.name = name
 
1
+ from flask import Blueprint, render_template, request, redirect, url_for, session
2
  from models import db, Attestation, PolicyResult, Product
3
  from sqlalchemy import func, text
4
 
5
+ def get_products_with_stats(filter_query=None, user_id=None, show_all=False):
6
  # Only consume data from products table
7
  query = Product.query.filter(Product.deleted == False)
8
+ if not show_all and user_id is not None:
9
+ query = query.filter(Product.user_id == user_id)
10
  if filter_query:
11
  like_pattern = f'%{filter_query}%'
12
  query = query.filter(
 
44
  'attestation_count': attestation_count,
45
  'policy_result_count': policy_result_count,
46
  'badges': badges,
47
+ 'product_metadata': product.product_metadata,
48
+ 'user_id': product.user_id
49
  })
50
  return products, pagination
51
  return products
52
 
53
  # Function to update product data
54
+ def update_product_data(product_key, product_version, name=None, description=None, metadata=None, badges=None, user_id=None):
55
+ # Allow user_id to be passed explicitly (for background/API use), else fallback to session
56
+ if user_id is None:
57
+ user_id = session.get('user_id')
58
+ if user_id is None:
59
+ raise ValueError("user_id must be provided to update_product_data")
60
+ product = Product.query.filter_by(product_key=product_key, product_version=product_version, deleted=False, user_id=user_id).first()
61
  if not product:
62
+ product = Product(product_key=product_key, product_version=product_version, user_id=user_id)
63
  db.session.add(product)
64
  if name is not None:
65
  product.name = name
web/routes.py CHANGED
@@ -225,8 +225,16 @@ def products_page():
225
  filter_query = request.args.get('filter', '')
226
  page = request.args.get('page', 1, type=int)
227
  per_page = request.args.get('per_page', 20, type=int)
228
- products, pagination = get_products_with_stats(filter_query)
229
- return render_template('products.html', products=products, pagination=pagination, filter_query=filter_query)
 
 
 
 
 
 
 
 
230
 
231
  # --- Products CSV Download ---
232
  @web_bp.route('/products/download-csv')
 
225
  filter_query = request.args.get('filter', '')
226
  page = request.args.get('page', 1, type=int)
227
  per_page = request.args.get('per_page', 20, type=int)
228
+ user_id = session.get('user_id')
229
+ show_all = False
230
+ is_admin = False
231
+ if user_id:
232
+ from .routes import is_admin_user_web as _is_admin_user_web
233
+ is_admin = _is_admin_user_web(user_id)
234
+ if is_admin:
235
+ show_all = request.args.get('show_all', '0') == '1'
236
+ products, pagination = get_products_with_stats(filter_query, user_id=user_id, show_all=show_all)
237
+ return render_template('products.html', products=products, pagination=pagination, filter_query=filter_query, show_all=show_all, is_admin=is_admin)
238
 
239
  # --- Products CSV Download ---
240
  @web_bp.route('/products/download-csv')