From b0f85aef26d15e8ab1c4c8de9c7e38163ef6191c Mon Sep 17 00:00:00 2001 From: Kevin Chung Date: Sat, 15 Aug 2020 03:35:16 -0400 Subject: [PATCH] Add mostly untested way to update field values via API --- CTFd/api/v1/users.py | 7 +++++++ CTFd/forms/self.py | 12 ++++++++++-- CTFd/models/__init__.py | 2 ++ CTFd/themes/core/assets/js/pages/settings.js | 9 +++++++++ 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/CTFd/api/v1/users.py b/CTFd/api/v1/users.py index 09b564be..57443766 100644 --- a/CTFd/api/v1/users.py +++ b/CTFd/api/v1/users.py @@ -305,6 +305,13 @@ class UserPrivate(Resource): if response.errors: return {"success": False, "errors": response.errors}, 400 + from CTFd.models import FieldEntries + fields = data.get("fields") + for k, v in fields.items(): + field_id = int(k.split('-')[1]) + e = FieldEntries.query.filter_by(field_id=field_id, user_id=session["id"]).first() + e.value = v + db.session.commit() # Update user's session for the new session hash diff --git a/CTFd/forms/self.py b/CTFd/forms/self.py index 81d1cc5e..7d906d44 100644 --- a/CTFd/forms/self.py +++ b/CTFd/forms/self.py @@ -1,10 +1,11 @@ +from flask import session from wtforms import PasswordField, SelectField, StringField from wtforms.fields.html5 import DateField, URLField from CTFd.forms import BaseForm from CTFd.forms.fields import SubmitField from CTFd.utils.countries import SELECT_COUNTRIES_LIST -from CTFd.models import Fields +from CTFd.models import Fields, FieldEntries def SettingsForm(*args, **kwargs): @@ -22,8 +23,15 @@ def SettingsForm(*args, **kwargs): def extra(self): fields = [] new_fields = Fields.query.all() + user_fields = {} + + for f in FieldEntries.query.filter_by(user_id=session["id"]).all(): + user_fields[f.field_id] = f.value + for field in new_fields: - entry = (field.name, getattr(self, f"field-{field.id}")) + form_field = getattr(self, f"field-{field.id}") + form_field.data = user_fields.get(field.id, "") + entry = (field.name, form_field) fields.append(entry) return fields diff --git a/CTFd/models/__init__.py b/CTFd/models/__init__.py index 80f7c66a..85a428eb 100644 --- a/CTFd/models/__init__.py +++ b/CTFd/models/__init__.py @@ -276,6 +276,8 @@ class Users(db.Model): # Relationship for Teams team_id = db.Column(db.Integer, db.ForeignKey("teams.id")) + fields = db.relationship("FieldEntries", foreign_keys="FieldEntries.user_id", lazy="select") + created = db.Column(db.DateTime, default=datetime.datetime.utcnow) __mapper_args__ = {"polymorphic_identity": "user", "polymorphic_on": type} diff --git a/CTFd/themes/core/assets/js/pages/settings.js b/CTFd/themes/core/assets/js/pages/settings.js index c1d6c813..97457d9a 100644 --- a/CTFd/themes/core/assets/js/pages/settings.js +++ b/CTFd/themes/core/assets/js/pages/settings.js @@ -24,6 +24,15 @@ function profileUpdate(event) { const $form = $(this); let params = $form.serializeJSON(true); + params.fields = {} + + for (const property in params) { + if (property.startsWith("field-")) { + params.fields[property] = params[property]; + delete params[property]; + } + } + CTFd.api.patch_user_private({}, params).then(response => { if (response.success) { $("#results").html(success_template);