Added agreed_to_tos_on field in user and role model.
authorLennard de Rijk <ljvderijk@gmail.com>
Fri, 30 Jan 2009 09:31:56 +0000
changeset 1076 063194eaf87b
parent 1075 4fd9b11fba56
child 1077 8e0a17067b35
Added agreed_to_tos_on field in user and role model. Also the user and user_self view no properly handle this new field. The ToS will be shown on-screen (not in a nice way) only if it is in effect and a user has not signed it yet. Patch by: Lennard de Rijk Reviewed by: to-be-reviewed
app/soc/logic/models/user.py
app/soc/models/role.py
app/soc/models/user.py
app/soc/templates/soc/user/edit_profile.html
app/soc/views/models/club_admin.py
app/soc/views/models/club_member.py
app/soc/views/models/host.py
app/soc/views/models/role.py
app/soc/views/models/user.py
app/soc/views/models/user_self.py
--- a/app/soc/logic/models/user.py	Thu Jan 29 23:07:04 2009 +0000
+++ b/app/soc/logic/models/user.py	Fri Jan 30 09:31:56 2009 +0000
@@ -85,25 +85,20 @@
       True: no site-wide ToS is currently in effect on the site
       True: site-wide ToS is in effect *and* User agrees to it
         (User explicitly answered "Yes")
-      False: site-wide ToS is in effect but User does not agree to it
-        (User explicitly answered "No")
-      None: site-wide ToS in effect, but User has not answered "Yes" or "No"
-        (this answer still evaluates to False, denying access to the site,
-         but can be used to detect non-answer to ask the User to provide the
-         missing answer)
+      False: site-wide ToS is in effect but User did not agree to it yet
     """
     if not site_logic.getToS(site_logic.getSingleton()):
       # no site-wide ToS in effect, so let the User slide for now
       return True
 
     try:
-      agrees = entity.agrees_to_tos
+      agreed_on = entity.agreed_to_tos_on
     except db.Error:
-      # return still-False "third answer" indicating that answer is missing
-      return None
+      # return False indicating that answer is missing
+      return False
 
-    # make sure the stored value is really a Boolean only
-    if not agrees:
+    # user has not agreed yet
+    if not agreed_on:
       return False
 
     return True
@@ -144,7 +139,7 @@
     if (name == 'is_developer') and (entity.is_developer != value):
       sidebar.flush(entity.account)
 
-    if (name == 'agrees_to_tos') and (entity.agrees_to_tos != value):
+    if (name == 'agreed_to_tos') and (entity.agreed_to_tos != value):
       sidebar.flush(entity.account)
 
     if (name == 'account') and (entity.account != value):
--- a/app/soc/models/role.py	Thu Jan 29 23:07:04 2009 +0000
+++ b/app/soc/models/role.py	Fri Jan 30 09:31:56 2009 +0000
@@ -275,13 +275,21 @@
       verbose_name=ugettext('T-shirt Style'),
       choices=('male', 'female'))
 
-  #: field storing whether User has agreed to the Role-specific Terms of
-  #: Service. (Not a required field because some Roles may not have special
-  #: Terms of Service.)
-  agrees_to_tos = db.BooleanProperty(
-      verbose_name=ugettext('I agree to the Terms of Service'))
-  agrees_to_tos.help_text = ugettext(
-      'Indicates that the user agrees to the Terms of Service for this Role.')
+  #: field storing wheter the User has agreed to the site-wide Terms of Service.
+  #: (Not a required field because the Terms of Service might not be present
+  #: when the first User profile is created when bootstrapping the site.)
+  agreed_to_tos = db.BooleanProperty(required=False, default=False,
+      verbose_name=ugettext('I Agree to the Terms of Service'))
+  agreed_to_tos.help_text = ugettext(
+      'Indicates whether the user agreed to this role Terms of Service.')
+
+  #: field storing when the User has agreed to the site-wide Terms of Service.
+  #: (Not a required field because the Terms of Service might not be present
+  #: when the first User profile is created when bootstrapping the site.)
+  agreed_to_tos_on = db.DateTimeProperty(required=False, default=None,
+      verbose_name=ugettext('Has agreed to the Terms of Service on'))
+  agreed_to_tos_on.help_text = ugettext(
+      'Indicates when the user agreed to this role Terms of Service.')
 
   #: field storing the state of this role
   #: Active means that this role can exercise all it's privileges.
--- a/app/soc/models/user.py	Thu Jan 29 23:07:04 2009 +0000
+++ b/app/soc/models/user.py	Fri Jan 30 09:31:56 2009 +0000
@@ -91,11 +91,19 @@
   is_developer.help_text = ugettext(
       'Field used to indicate user with site-wide Developer access.')
 
-  #: field storing whether User has agreed to the site-wide Terms of Service.
+  #: field storing wheter the User has agreed to the site-wide Terms of Service.
   #: (Not a required field because the Terms of Service might not be present
   #: when the first User profile is created when bootstrapping the site.)
-  agrees_to_tos = db.BooleanProperty(
-      verbose_name=ugettext('I agree to the Terms Of Service'))
-  agrees_to_tos.help_text = ugettext(
-      'Indicates that the user agrees to the site-wide Terms of Service.')
+  agreed_to_tos = db.BooleanProperty(required=False, default=False,
+      verbose_name=ugettext('I Agree to the Terms of Service'))
+  agreed_to_tos.help_text = ugettext(
+      'Indicates whether the user agreed to the site-wide Terms of Service.')
 
+  #: field storing when the User has agreed to the site-wide Terms of Service.
+  #: (Not a required field because the Terms of Service might not be present
+  #: when the first User profile is created when bootstrapping the site.)
+  agreed_to_tos_on = db.DateTimeProperty(required=False, default=None,
+      verbose_name=ugettext('Has agreed to the Terms of Service on'))
+  agreed_to_tos_on.help_text = ugettext(
+      'Indicates when the user agreed to the site-wide Terms of Service.')
+
--- a/app/soc/templates/soc/user/edit_profile.html	Thu Jan 29 23:07:04 2009 +0000
+++ b/app/soc/templates/soc/user/edit_profile.html	Fri Jan 30 09:31:56 2009 +0000
@@ -56,8 +56,13 @@
   </tr>
   <tr><td colspan="4">&nbsp;</td></tr>
 
-{% if tos_link %}
-  {% field_as_table_row form.agrees_to_tos %}
+{% if tos_link and not user.agreed_to_tos %}
+<tr>
+  <td>
+      {{ tos_contents|safe|linebreaks }}
+  </td>
+</tr>
+  {% field_as_table_row form.agreed_to_tos %}
   <tr>
    <td class="fieldhelptext" colspan="4">
 In order to participate on this site, you must agree to the
--- a/app/soc/views/models/club_admin.py	Thu Jan 29 23:07:04 2009 +0000
+++ b/app/soc/views/models/club_admin.py	Fri Jan 30 09:31:56 2009 +0000
@@ -72,7 +72,7 @@
     new_params['name'] = "Club Admin"
     new_params['sidebar_grouping'] = 'Clubs'
 
-    new_params['extra_dynaexclude'] = ['user', 'state']
+    new_params['extra_dynaexclude'] = ['agreed_to_tos']
 
     new_params['create_extra_dynafields'] = {
        'scope_path': forms.CharField(widget=forms.HiddenInput,
--- a/app/soc/views/models/club_member.py	Thu Jan 29 23:07:04 2009 +0000
+++ b/app/soc/views/models/club_member.py	Fri Jan 30 09:31:56 2009 +0000
@@ -74,7 +74,7 @@
     new_params['name'] = "Club Member"
     new_params['sidebar_grouping'] = 'Clubs'
 
-    new_params['extra_dynaexclude'] = ['user', 'state']
+    new_params['extra_dynaexclude'] = ['agreed_to_tos']
 
     new_params['create_extra_dynafields'] = {
        'scope_path': forms.CharField(widget=forms.HiddenInput,
--- a/app/soc/views/models/host.py	Thu Jan 29 23:07:04 2009 +0000
+++ b/app/soc/views/models/host.py	Fri Jan 30 09:31:56 2009 +0000
@@ -75,13 +75,11 @@
 
     new_params['scope_view'] = sponsor_view
 
-    new_params['invite_filter'] = {'group_ln': 'link_id'}
-
     new_params['name'] = "Program Administrator"
     new_params['module_name'] = "host"
     new_params['sidebar_grouping'] = 'Programs'
 
-    new_params['extra_dynaexclude'] = ['user', 'state']
+    new_params['extra_dynaexclude'] = ['agreed_to_tos']
 
     new_params['create_extra_dynafields'] = {
        'scope_path': forms.CharField(widget=forms.HiddenInput,
--- a/app/soc/views/models/role.py	Thu Jan 29 23:07:04 2009 +0000
+++ b/app/soc/views/models/role.py	Fri Jan 30 09:31:56 2009 +0000
@@ -100,7 +100,9 @@
     new_params['extra_django_patterns'] = patterns
     new_params['scope_redirect'] = redirects.getInviteRedirect
 
-    params = dicts.merge(params, new_params)
+    new_params['extra_dynaexclude'] = ['user', 'state', 'agreed_to_tos_on']
+
+    params = dicts.merge(params, new_params, sub_merge=True)
 
     super(View, self).__init__(params=params)
 
--- a/app/soc/views/models/user.py	Thu Jan 29 23:07:04 2009 +0000
+++ b/app/soc/views/models/user.py	Fri Jan 30 09:31:56 2009 +0000
@@ -72,18 +72,22 @@
 
     new_params['sidebar_heading'] = 'Users'
 
-    new_params['extra_dynaexclude'] = ['former_accounts']
+    new_params['extra_dynaexclude'] = ['former_accounts', 'agreed_to_tos',
+        'agreed_to_tos_on']
     new_params['create_extra_dynafields'] = {
         'clean_link_id': cleaning.clean_user_not_exist('link_id'),
         'clean_account': cleaning.clean_user_account_not_in_use('account')}
 
     new_params['edit_extra_dynafields'] = {
         'link_id': forms.CharField(widget=widgets.ReadOnlyInput(),
-                                   required=True),
+            required=True),
         'clean_link_id': cleaning.clean_link_id,
+        'agreed_to_tos_on' : forms.CharField(widget=widgets.ReadOnlyInput(),
+            required=False),
         'clean_account': cleaning.clean_user_account('account'),
         'clean': cleaning.validate_user_edit('link_id', 'account'),
     }
+
     params = dicts.merge(params, new_params)
 
     super(View, self).__init__(params=params)
@@ -95,24 +99,13 @@
 
     # fill in the email field with the data from the entity
     form.fields['account'].initial = entity.account.email()
-    form.fields['agrees_to_tos'].example_text = self.getToSExampleText()
+    form.fields['agreed_to_tos_on'].initial = entity.agreed_to_tos_on
+    form.fields['agreed_to_tos_on'].example_text = self._getToSExampleText()
 
     super(View, self)._editGet(request, entity, form)
 
-  def _editPost(self, request, entity, fields):
-    """See base.View._editPost().
-    """
 
-    if not entity:
-      # developer is creating a new entity set agrees_to_tos to None
-      fields['agrees_to_tos'] = None
-    else:
-      # editing an existing user so don't change the agrees_to_tos field
-      fields['agrees_to_tos'] = entity.agrees_to_tos
-
-    super(View, self)._editPost(request, entity, fields)
-
-  def getToSExampleText(self):
+  def _getToSExampleText(self):
     """Returns example_text linking to site-wide ToS, or a warning message.
     """
     tos_link = redirects.getToSRedirect(site_logic.getSingleton())
--- a/app/soc/views/models/user_self.py	Thu Jan 29 23:07:04 2009 +0000
+++ b/app/soc/views/models/user_self.py	Fri Jan 30 09:31:56 2009 +0000
@@ -24,6 +24,8 @@
   ]
 
 
+import datetime
+
 from google.appengine.api import users
 
 from django import http
@@ -82,8 +84,9 @@
     # set the specific fields for the users profile page
     new_params['extra_dynaexclude'] = ['former_accounts', 
         'account', 'is_developer']
+
     new_params['create_extra_dynafields'] = {
-        'clean_agrees_to_tos' : cleaning.clean_agrees_to_tos('agrees_to_tos'),
+        'clean_agreed_to_tos' : cleaning.clean_agrees_to_tos('agreed_to_tos'),
         'clean_link_id': cleaning.clean_user_not_exist('link_id'),}
 
     new_params['edit_extra_dynafields'] = {
@@ -140,15 +143,30 @@
            page_name=page_name, params=params, seed=seed, link_id=link_id, **kwargs)
 
 
-  def _editGet(self, request, entity, form):
-    """See base.View._editGet().
+  def editGet(self, request, entity, context, seed, params=None):
+    """Overwrite so we can add the contents of the ToS.
+    For params see base.View.editGet().
     """
 
-    # set the ToS example text
-    form.fields['agrees_to_tos'].example_text = user_view.view.getToSExampleText()
-    form.fields['link_id'].initial = entity.link_id
+    s_logic = model_logic.site.logic
+    site_tos = s_logic.getToS(s_logic.getSingleton())
+    if site_tos:
+      context['tos_contents'] = site_tos.content
+
+    return super(View, self).editGet(request, entity, context, seed, params=params)
 
-    super(View, self)._editGet(request, entity, form)
+  def editPost(self, request, entity, context, params=None):
+    """Overwrite so we can add the contents of the ToS.
+    For params see base.View.editPost().
+    """
+
+    s_logic = model_logic.site.logic
+    site_tos = s_logic.getToS(s_logic.getSingleton())
+    if site_tos:
+      context['tos_contents'] = site_tos.content
+
+    return super(View, self).editPost(request, entity, context, params=params)
+
 
   def _editPost(self, request, entity, fields):
     """See base.View._editPost().
@@ -164,10 +182,14 @@
       # there is no Terms of Service set
       if not entity:
         # we are a new user so set the agrees_to_tos field to None
-        fields['agrees_to_tos'] = None
+        fields['agreed_to_tos'] = None
       else:
-        # editing an existing user so don't change the agrees_to_tos field
-        fields['agrees_to_tos'] = entity.agrees_to_tos
+        # editing an existing user so no value changes allowed
+        fields['agreed_to_tos'] = entity.agreed_to_tos
+    else:
+      if not entity or not entity.agreed_to_tos:
+        # set the time of agreement
+        fields['agreed_to_tos_on'] = datetime.datetime.now()
 
     super(View, self)._editPost(request, entity, fields)