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
--- 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"> </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)