revsys / django-tos Goto Github PK
View Code? Open in Web Editor NEWA small app to ensure your users re-agree to Terms of Service changes
License: BSD 3-Clause "New" or "Revised" License
A small app to ensure your users re-agree to Terms of Service changes
License: BSD 3-Clause "New" or "Revised" License
The UserAgreementMiddleware has the following lines:
if not user_agreed:
return add_never_cache_headers(HttpResponseRedirect(tos_check_url))
But add_never_cache_headers does not return anything and middleware returns None.
Maybe there should be something like this:
if not user_agreed:
response = HttpResponseRedirect(tos_check_url)
add_never_cache_headers(response)
return response
If I start the server and log in with a user that didn't accept or reject the TOS before, it just became on a loop at the /confirm/ page.
As seen on the image, it makes the redirect but it keeps making the redirect to the TOC acceptance page.
If I restar the server it stops doing that and works fine for the previously accepted users. Maybe I configured something wrong?
Thank you
Hi , I'm using version 0.7.1 and getting the following error when using "Option 2 (Cache Approach)" as described in the guide.
KeyError at /terms-of-service/confirm/
'tos_user'
In views.py :
https://github.com/revsys/django-tos/blob/master/tos/views.py#L119
The only place where I've seen that session variable being set is in that same file but here :
https://github.com/revsys/django-tos/blob/master/tos/views.py#L119
It seems like the cache should be queried as well ?
Thanks
Hello @frankwiles ! Hello all!
The version in PyPI does not contain migrations. I'm running a very unusual setup, with django-tenants and we spent a little while trying to debug a weird error while creating a new tenant, that came from django-tos.
I had installed tos from the repository and someone else from PyPI. The error was present on his machine, because in PyPI we don't have migrations on TOS, while here worked fine.
Can we get a new release on PyPI, just to make sure everything consistent?
Any plans for a release supporting django 3?
django.shortcuts.render_to_response
was deprecrated jn django3.0 so lhat line 11 in views.py throws an error. Any plans to support v3.0?
https://github.com/revsys/django-tos/blob/master/tos/models.py#L65
.. should use QuerySet.exists().
In fact, you can reduce this entire method to;
return user.user_agreement.filter(terms_of_service=TermsOfService.objects.get_current_tos()).exists()
Thanks for the middleware - appreciate it. One note, as we tend to rebuild our containers for dev often and I get hit with this.
NoActiveTermsOfService at /terms-of-service/confirm/
['Please create an active Terms-of-Service']
Does this really need to raise an exception and prevent accessing the site? Wouldn't logging an error or warning be sufficient and just let the user login / redirect as normal? Doing the TOS update_terms is not part of the normal initialization as we don't want to reset this every time.
Error with the from tos.views import login
line:
Unhandled exception in thread started by <function wrapper at 0x103d295f0>
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/utils/autoreload.py", line 226, in wrapper
fn(*args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/commands/runserver.py", line 121, in inner_run
self.check(display_num_errors=True)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/base.py", line 385, in check
include_deployment_checks=include_deployment_checks,
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/base.py", line 372, in _run_checks
return checks.run_checks(**kwargs)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/checks/registry.py", line 81, in run_checks
new_errors = check(app_configs=app_configs)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/checks/urls.py", line 14, in check_url_config
return check_resolver(resolver)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/checks/urls.py", line 24, in check_resolver
for pattern in resolver.url_patterns:
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/utils/functional.py", line 35, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/urls/resolvers.py", line 310, in url_patterns
patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/utils/functional.py", line 35, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/urls/resolvers.py", line 303, in urlconf_module
return import_module(self.urlconf_name)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/importlib/__init__.py", line 37, in import_module
__import__(name)
File "/Users/jgates/Desktop/SBGBookv2/gbsite/gbsite/urls.py", line 26, in <module>
url(r'^gbook/', include('gbook.urls')),
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/conf/urls/__init__.py", line 50, in include
urlconf_module = import_module(urlconf_module)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/importlib/__init__.py", line 37, in import_module
__import__(name)
File "/Users/jgates/Desktop/SBGBookv2/gbsite/gbook/urls.py", line 3, in <module>
from tos.views import login
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/tos/views.py", line 9, in <module>
from django.contrib.sites.models import Site
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/contrib/sites/models.py", line 86, in <module>
class Site(models.Model):
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/base.py", line 113, in __new__
"INSTALLED_APPS." % (module, name)
RuntimeError: Model class django.contrib.sites.models.Site doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
Hello. Using this in a project, and noticed that it hasn't had activity in a while. Is this project still being maintained? Do you need additional contributors? I'd love to get some fixes in for later Django versions, thanks!
In the UserAgreement model we have a unicode method that is specifically asking for user.username field.
Not all custom users have user.username fields. In our case, we have something like that, but this should be configurable and respect the settings in the custom models.
example:
class UserAgreement(BaseModel):
terms_of_service = models.ForeignKey(TermsOfService, related_name='terms')
user = models.ForeignKey(get_fk_user_model(), related_name='user_agreement')
def __unicode__(self):
username_field = get_user_model().USERNAME_FIELD
if username_field:
return u'%s agreed to TOS: %s' % (getattr(self.user, username_field),
unicode(self.terms_of_service))
else:
return u'%s agreed to TOS: %s' % (self.user,
unicode(self.terms_of_service))
In this case, if the model has the username field, it will use that, as you intented. If not, it will use the user's unicode.
Now that Django 1.9 compatibility has landed we could use a new version and release to PyPI
Thanks for your work on this project. It looks sort of like what I want.
However, we'll have a terms of service and a privacy policy that both need these semantics (are versioned, want users to actively agree to the version).
Thoughts on supporting that? Perhaps this is a feature request.
I already installed the last version (0.8.1) and started making the Option 2 Configuration because of Django Allauth.
After adding the apps, the urls and the middleware class (point 1,2,4) I made a
python manage.py makemigrations
and python manage.py migrate
to create the tables on the DB.
If I try to enter the server I'm getting an error about not having any TOS yet, and so to add that I need to add the point 5 in which I should add the exception for staff and superusers in order to enter django-admin and populate it.
But I don't understand where am I supposed to add that file, and I imagine I should add the point 3 with the specific cache for that...
Could you please guide me on where to add that file on my project? Also if possible, a backend and location for cache that will to work on AWS elasticbeanstalk. I never worked with caches and so I would appreciate a lot a little guidance here too.
Thank you very much.
Hello, thank you for creating and maintaining this project. I am currently unable to install the latest version of it, 0.8.0, via pip. Running pip install django-tos
retrieves version 0.7.2, which PyPI claims is most recent. Can you please update PyPI?
The ondelete argument is a required argument from Django 2.0 - see the docs. Please add support for Django 2.0 and higher
File "/seed/src/django-tos-master/tos/models.py", line 71, in UserAgreement
terms_of_service = models.ForeignKey(TermsOfService, related_name='terms')
TypeError: __init__() missing 1 required positional argument: 'on_delete'
Hello,
I'm using Django 2.2.7
, Wagtail 2.7
, and Django Allauth 0.40.0
. I downloaded a copy of the django-tos
repo and placed it my root project directory. Because I am using Django Allauth
I am following the middleware installation approach. I have created an active TermsOfService
object and am successfully sent to the TosView
after logging in. However, when a user accepts the terms, they are not always passed to the next
page. The UserAgreement
object gets succcessfully created on the first try, but the user remains on the TosView
after the tos_check
form is submitted. It seems as though the user can only move onto the "next" page after I make a change to my project and save the file, causing everything to reload.
I have tried setting request.session['tos_user'] = user.pk
and request.session['tos_backend'] = user.backend
after auth_login(request, user)
is called in check_tos()
, but that had no effect. I also logged user
and UserAgreement.objects.all()
inside check_tos()
to make sure that information is there, and it is.
My value for redirect_to
is /
, which I thought might be problematic. So I changed the value of the hidden next
field to a different relative path in the inspector, but that also did not work. I remain on the TosView
page.
Below are my settings/base.py
and root urls.py
. Thank you for any help you can provide.
### settings/base.py
"""
Django settings for whyyoumatter project.
Generated by 'django-admin startproject' using Django 2.2.7.
For more information on this file, see
https://docs.djangoproject.com/en/2.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.2/ref/settings/
"""
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
BASE_DIR = os.path.dirname(PROJECT_DIR)
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
# Application definition
INSTALLED_APPS = [
"tos",
"accounts",
"articles",
"base",
"partners",
"search",
"testimonials",
"threads",
"wagtail.contrib.forms",
"wagtail.contrib.modeladmin",
"wagtail.contrib.redirects",
"wagtail.contrib.routable_page",
"wagtail.embeds",
"wagtail.sites",
"wagtail.users",
"wagtail.snippets",
"wagtail.documents",
"wagtail.images",
"wagtail.search",
"wagtail.admin",
"wagtail.core",
"wagtailfontawesome",
"wagtailmenus",
"modelcluster",
"taggit",
"widget_tweaks",
"allauth",
"allauth.account",
"allauth.socialaccount",
"allauth.socialaccount.providers.google",
"django_extensions",
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.humanize",
"django.contrib.sessions",
"django.contrib.sitemaps",
"django.contrib.messages",
"django.contrib.sites",
"django.contrib.staticfiles",
"sass_processor",
]
MIDDLEWARE = [
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"django.middleware.security.SecurityMiddleware",
"wagtail.core.middleware.SiteMiddleware",
"wagtail.contrib.redirects.middleware.RedirectMiddleware",
"tos.middleware.UserAgreementMiddleware",
]
ROOT_URLCONF = "whyyoumatter.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [os.path.join(PROJECT_DIR, "templates"),],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
"wagtailmenus.context_processors.wagtailmenus",
],
},
},
]
AUTHENTICATION_BACKENDS = (
# Needed to login by username in Django admin, regardless of `allauth`
"django.contrib.auth.backends.ModelBackend",
# `allauth` specific authentication methods, such as login by e-mail
"allauth.account.auth_backends.AuthenticationBackend",
)
SITE_ID = 2
WSGI_APPLICATION = "whyyoumatter.wsgi.application"
# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
# Password validation
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",},
{"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",},
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",},
]
AUTH_USER_MODEL = "accounts.Account"
# Internationalization
# https://docs.djangoproject.com/en/2.2/topics/i18n/
LANGUAGE_CODE = "en-us"
TIME_ZONE = "America/Detroit"
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/
STATICFILES_FINDERS = (
"django.contrib.staticfiles.finders.FileSystemFinder",
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
"sass_processor.finders.CssFinder",
)
SASS_PROCESSOR_ROOT = os.path.join(BASE_DIR, "static")
STATICFILES_DIRS = [
os.path.join(PROJECT_DIR, "static"),
]
# ManifestStaticFilesStorage is recommended in production, to prevent outdated
# Javascript / CSS assets being served from cache (e.g. after a Wagtail upgrade).
# See https://docs.djangoproject.com/en/2.2/ref/contrib/staticfiles/#manifeststaticfilesstorage
STATIC_ROOT = os.path.join(BASE_DIR, "static")
STATIC_URL = "/static/"
# Wagtail settings
WAGTAIL_SITE_NAME = "#WhyYouMatter"
# Base URL to use when referring to full URLs within the Wagtail admin backend -
# e.g. in notification emails. Don't include '/admin' or a trailing slash
BASE_URL = "https://whyyoumatter.pythonanywhere.com"
ACCOUNT_FORMS = {"signup": "accounts.forms.MySignUpForm"}
LOGIN_URL = "/login/"
LOGIN_REDIRECT_URL = "/"
ACCOUNT_AUTHENTICATION_METHOD = "email"
ACCOUNT_CONFIRM_EMAIL_ON_GET = True
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_UNIQUE_EMAIL = True
ACCOUNT_EMAIL_VERIFICATION = "mandatory"
ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION = True
ACCOUNT_LOGOUT_ON_GET = True
ACCOUNT_LOGIN_ON_PASSWORD_RESET = True
ACCOUNT_SESSION_REMEMBER = False # Change to true once cookie policy is displayed
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_USER_MODEL_USERNAME_FIELD = None
ACCOUNT_DEFAULT_HTTP_PROTOCOL = "https"
SOCIALACCOUNT_PROVIDERS = {
'google': {
'SCOPE': [
'profile',
'email',
],
'AUTH_PARAMS': {
'access_type': 'online',
}
}
}
WAGTAIL_USER_EDIT_FORM = "accounts.forms.CustomUserEditForm"
WAGTAIL_USER_CREATION_FORM = "accounts.forms.CustomUserCreationForm"
WAGTAIL_USER_CUSTOM_FIELDS = ["school"]
WAGTAIL_FRONTEND_LOGIN_URL = LOGIN_URL
### root urls.py
from django.conf import settings
from django.conf.urls import url
from django.contrib import admin
from django.urls import include, path
from wagtail.admin import urls as wagtailadmin_urls
from wagtail.contrib.sitemaps.views import sitemap
from wagtail.core import urls as wagtail_urls
from wagtail.documents import urls as wagtaildocs_urls
from search import views as search_views
urlpatterns = [
url(r"^sitemap\.xml$", sitemap),
url(r"^django-admin/", admin.site.urls),
url(r"^admin/", include(wagtailadmin_urls)),
url(r"^documents/", include(wagtaildocs_urls)),
url(r"^search/$", search_views.search, name="search"),
url(r"^my-account/", include("accounts.urls")),
url(r'^terms-of-service/', include('tos.urls')),
url(r"", include("allauth.urls")),
# For anything not caught by a more specific rule above, hand over to
# Wagtail's page serving mechanism. This should be the last pattern in
# the list:
url(r"", include(wagtail_urls)),
# Alternatively, if you want Wagtail pages to be served from a subpath
# of your site, rather than the site root:
# url(r'^pages/', include(wagtail_urls)),
]
if settings.DEBUG:
from django.conf.urls.static import static
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
import debug_toolbar
urlpatterns = [
path('__debug__/', include(debug_toolbar.urls)),
] + urlpatterns
# Serve static and media files from development server
urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Some users of IE are not able to accept the tos even if they click "accept" button.
They are getting info that they must accept the tos in order to contunue... so it seems like "accept" variable is not set, or they are again redirected to the "accept tos" view with via POST.
I can not replicate the problem...
Do you have any idea ?
my settings py:
LOGIN_REDIRECT_URL="/accounts/profile/"
LOGIN_URL="/login/"
Thanks
Hi and thanks for your work on this.
Are there any plans to release the python >= 3 supporting code of this respository in a pypi package? Or are there reasons that this hasn't happened? As I'd imagine it to be more comfortable for users of this package to be able to include it to a project by using a official pip installable release.
Dear maintainer of the django-tos package,
Thank you for your efforts in maintaining this package. It's much appreciated.
I have a question regarding its use in conjunction with serving static files through Django. I've noticed that it blocks the delivery of stylesheets, images, fonts, etc., which results in an unstyled Terms of Service page.
Is there a recommended way to handle this issue? I would greatly appreciate any guidance you can provide. For now, I just reimplemented the middleware. For now, I am extending the middleware to fast skip certain file types.
I understand that many users do not experience this issue as they serve their static files through a web server. However, I still believe that it could be desirable to have a "fast skip" rule for static and media files.
If this is something you would find useful, I would be happy to prepare a pull request to add this functionality. Please let me know if this is of interest to you.
Thank you again for your work on this package.
Best regards,
Benedikt
And remove Travis CI
Hi,
I'm new to django and django-tos but I had the following issue :
First I started a new project, create my superuser, add my app etc and then add django-tos and it was working well, in particular I was able to log to the admin page.
Then I deleted the sqlite file (so full reset of the DB, superuser included) and create again my superuser.
However this time, since the migration for django-tos happened at the same time that I created to project I'm not even able to log for the 1st time to the admin page since there is no ToS configured and I have the exception :
NoActiveTermsOfService at /terms-of-service/confirm/
['Please create an active Terms-of-Service']
Regards,
Guillaume
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.