ubernostrum / django-registration Goto Github PK
View Code? Open in Web Editor NEWAn extensible user-registration app for Django.
License: BSD 3-Clause "New" or "Revised" License
An extensible user-registration app for Django.
License: BSD 3-Clause "New" or "Revised" License
Contrary to what the documentation says, setting success_url has no effect. This is because of the way form_valid() is implemented, where get_success_url() is always called regardless of the value of RegistrationView.success_url.
Hi,
in the below code snippet you see two events being handled by sending an email. If I just add user_registered
it works. But if I add the callback for user_activated
nothing happens. Then even the user_registered
event doesn't get handled. What can I do next? Do you see a mistake? if it's a bug can I trace it somehow? Events don't give much output.
from django.core.mail import EmailMessage
from django.template.loader import get_template
from django.template import Context
from registration.signals import user_registered, user_activated
# the following function works if it is the only one
@receiver(user_registered)
def registered_callback(sender, **kwargs):
EmailMessage(
subject="activated",
body=get_template("email_registered.txt").render(Context({
'user' : 'FIXED',
})),
to=[
"[email protected]",
],
).send()
#if this one is added or the only function nothing happens
@receiver(user_activated)
def registered_callback(sender, **kwargs):
EmailMessage(
subject="activated",
body=get_template("email_registered.txt").render(Context({
'user' : 'FIXED',
})),
to=[
"[email protected]",
],
).send()
Pip freeze on the Ubuntu 14.04 dev system with Python 3.4.3:
Django==1.10.3
django-bootstrap3==7.1.0
django-registration==2.1.2
mysqlclient==1.3.9
(System Update is no option because customer doesn't want that to happen)
Hello,
Initially I provided a namespace=registration
argument in my urls.py
with the include of registration.backends.hmac.urls
.
I received the following traceback:
Traceback (most recent call last): File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 39, in inner response = get_response(request) File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response response = self.process_exception_by_middleware(e, request) File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/usr/local/lib/python3.6/site-packages/django/views/generic/base.py", line 68, in view return self.dispatch(request, *args, **kwargs) File "/usr/local/lib/python3.6/site-packages/registration/views.py", line 33, in dispatch return super(RegistrationView, self).dispatch(*args, **kwargs) File "/usr/local/lib/python3.6/site-packages/django/views/generic/base.py", line 88, in dispatch return handler(request, *args, **kwargs) File "/usr/local/lib/python3.6/site-packages/django/views/generic/edit.py", line 183, in post return self.form_valid(form) File "/usr/local/lib/python3.6/site-packages/registration/views.py", line 44, in form_valid return redirect(to, *args, **kwargs) File "/usr/local/lib/python3.6/site-packages/django/shortcuts.py", line 56, in redirect return redirect_class(resolve_url(to, *args, **kwargs)) File "/usr/local/lib/python3.6/site-packages/django/shortcuts.py", line 147, in resolve_url return reverse(to, args=args, kwargs=kwargs) File "/usr/local/lib/python3.6/site-packages/django/urls/base.py", line 91, in reverse return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))) File "/usr/local/lib/python3.6/site-packages/django/urls/resolvers.py", line 392, in _reverse_with_prefix (lookup_view_s, args, kwargs, len(patterns), patterns) django.urls.exceptions.NoReverseMatch: Reverse for 'registration_complete' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
However when I removed the namespace argument it worked as expected. Not sure if this is a bug or I did something wrong in this case.
RegistrationProfile.activation_key must be uniqie=True, because we use "get" by
https://github.com/ubernostrum/django-registration/blob/master/registration/models.py#L52
also ALREADY_ACTIVATED , i think, better change to activation datetime field.
Im using this for my URLs:
# Registration
url(r'^accounts/', include('registration.backends.hmac.urls')),
And a basic template for the registration form. All is working but i'd like to include the tos (terms of service) checkbox.
I cant see how to do that easily. Any advice?
Thanks
Thank you for this great app.
I have found an error (or misunderstanding on my part) in the documentation of custom user models which gave me quite a headache.
from registration.forms import RegistrationForm
from mycustomuserapp.models import MyCustomUser
class MyCustomUserForm(RegistrationForm):
class Meta:
model = MyCustomUser
I had to add
fields = (getattr(get_user_model, 'USERNAME_FIELD', 'username'), "email")
otherwise it would give me a cryptic error message.
(citing Django-documentation: "In older versions, omitting both fields and exclude resulted in a form with all the model’s fields. Doing this now raises an ImproperlyConfigured exception.")
Maybe adding a comment about his would make it easier for people to implement that.
Thank you very much.
Why do not set model = User in class Meta in RegistrationForm?
@ubernostrum You should to add in class Meta in rRegistrationForm simple fix model = User. Registration does not work without it. Because your class Meta(UserCreationForm.Meta) in class RegistrationForm inhered parent Meta. And in django.contrib.auth.forms.UserCreationForm does not used construction like it User = get_user_model(). Django developers are using hard code from django.contrib.auth.models import User
documentation regarding simple shows illegal hmac path artifact:
https://github.com/ubernostrum/django-registration/blame/2.0.4/docs/quickstart.rst#L239
shows registration.simple.hmac.urls instead of registration.backends.simple.urls as (correctly in https://github.com/ubernostrum/django-registration/blame/2.0.3/docs/simple-workflow.rst#L25 )
At the moment there's no way to send HTML-based emails on user registration on both HMAC and model-based backends, due to the way User.user_email(...)
is used (without option to passing additional **kwargs
or, at least, the html_message
).
Is there a well defined path to getting this out into the wild?
If so, would it be possible to lay out the things that still need to be done so I (and probably others) can help?
Hi James,
I am using model activation backend with a custom user model. when a None English username is used , it triggers this error.
'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)
This is because of username = str(getattr(user, User.USERNAME_FIELD))
The error occurs on line 77 of registration.backends.hmac.views.py when the get_current_site(self.request)
method is called. It is called within another method get_email_context(self, activation_key)
Hello!
In the django-registration Docs I read: "The 2.0 release of django-registration supports Django 1.7 and 1.8,"
I was wonder if the 2.0 release is out, because I would like to use the app with Django 1.8 but I can only install v1.0 using pip.
Thanks in advance.
When I upgrade from Django 1.8.6 to Django 1.9 the clean methods in registration/forms.py is called twice (I checked with pdb breakpoint).
I don't know why this is happening (and why it only occurs in Django 1.9) but I believe it's a bug.
Hi James,
as documented here
https://docs.djangoproject.com/en/1.8/ref/templates/upgrading/
django 1.8 added new style settings for 'TEMPLATES'. With upcoming django 1.10, the "old way" is no longer deprecated, but removed.
As registration does not officially support django < 1.8, that update can imho be done right away, w/o any compatibility considerations.
Fwiw, here is the patch I used with the Debian packaging:
Thanks!
Stephan
i have a custom auth model where my with USERNAME_FIELD = model.IntegerField
when registration.forms.RegistrationForm() is run, it runs registration.validator()
the validator fails with
AttributeError: 'int' object has no attribute 'startswith'
If i change my USERNAME_FIELD = CharField() then it works fine
class MyUser(AbstractBaseUser):
username = models.IntegerField(default='00', unique=True)
USERNAME_FIELD = 'username'
Is it possible to have a check on an IntegerField instead of a CharField?
Here's probably a bug:
https://github.com/incuna/django-registration/blob/master/registration/forms.py#L57
if there are already exist users having same nick names with different lettercase - .get will throw an error:
MultipleObjectsReturned: get() returned more than one User -- it returned 3!
And so new user will be registered, probably filter with checking nuber of results will be more convinient.
"Configuring the the simple one-step workflow" -- "the" is repeated.
We are getting IntegrityError in create_inactive_user in the model activation backend (but doesn't look backend specific) when the form is saved because of duplicated username.
We can catch IntegrityError in the backends and then pass the user as None to the callers or just catch it in RegistrationView.form_valid. We may add a get_failure_url in RegistrationView to redirect the user to somewhere else. What do you think?
Hello,
Thanks so much for the great package. I am actively using it now and loving it. I have thoroughly looked over the documentation and source code, but I have not been able to see any mention of a forgot username form/view.
Is this currently a feature, and I have just overlooked it? If not, are there plans to add this in the future?
At the moment, on django-registration 2.1.2, there is no way to catch some common error case.
There is at least 2 common cases that could be helpful to catch:
The user copy /paste the right link, but after the allowed time window ended (link is outdated)
The user makes an error when copy / pasting the activation link. Or, since the activation email is sent as plain/text and some mail clients fail to automatically setup a link to the page, the user clicked on this kind of link:
http://server/accounts/activate/ImFudG9pbmVsb3JlbmNlIg:1bGQdx:5ovhXqGm1JsYFVeCPYwDT8HmUx8/
In both case, the view simply loads the default template registration/activate.html
. So there is no easy way to display a message to the user, to inform on what he can do now (depending on the error that happened). In addition, it could be useful for the administrator to also be notified in such cases. For example, a signal could be sent, or a callback function could be called.
Finally, when such an error happen, the user is not activated, and if the administrator doesn't do anything manually, the user will not have a chance to resolve his case. The only way out is to register again with another username (because it must be unique). This can lead to a many junk accounts created, if the user really want to create his account but don't understand why the activation link don't work for him.
For no obvious reasons, the activation key is generated with a custom process involving a SHA-1. There is absolutely no reason to reinvent such a key generation function because django already provides a much better one.
Hi,
In the locale/es/LC_MESSAGES/django.po
file where it says:
"La dirección de correo electrónico ya está siendo usada. Por favor"
"proporciona otra dirección."
It should say:
"La dirección de correo electrónico ya está siendo usada. Por favor "
"proporciona otra dirección."
A whitespace is missing between "Por favor" and "proporciona".
Cheers,
Iván.
The name "cleanupregistration" and the description "Delete expired user registrations from the database" implies that it deletes redundant junk left by the registration process.
But in reality this command deletes "junk" (users that registered and never logged in before it expired, which is helpful); but it also it deletes users that have logged in (and thus have potentially have lots of associated data that could and worst case may actually be cascade deleted when the user is deleted), and then for some reason was explicitly deactivated by an admin rather than outright deleted.
This makes the difference between deactivating a user and deleting it pointless. And it could unexpectedly delete lots of user generated content unless the admin has read the source code and realized that to ban a user but still keep their history and content; they must manually delete their registration profile first.
Unless you rename the management command to "deleteinactiveusers", I think the cleanup command should be changed to:
That would make this command fairly harmless, and do what it's supposed to.
(On a site where users are never explicitly deactivated by admins, the current behavior is harmless, but then this part of the query is simply pointless, since the the all ALREADY_ACTIVATED profiles will be linked to an active user and thus excluded by the 'user__is_active=True' exclude filter. It's only when an admin explicitly chose to deactivate rather than delete a user this part of the filter will have any effect by deleting a user the admin not wanted deleted)
Hi there, sorry for the basic question. I'd like to enable the custom admin-action to re-send the registration email but cant find out how to do that.
The only thing I found in the docs are this:
"Assuming you’re using the model-based workflow, a custom admin action is provided for this; in the admin for the RegistrationProfile model, simply click the checkbox for the user(s) you’d like to re-send the email for, then select the “Re-send activation emails” action."
But my Admin doesnt have that action. Other registration things are working fine.
Django 1.9.4, Python 2.7.10.
Thanks
Hi James, maintainers,
please consider doing this, keeping a compatibility package "registration" (including a deprecation warning) around as long as needed.
Having a django-specific python package called "registration" around is confusing, and takes away this name for other possible uses (namespace pollution).
Current practice for third party django packages seems to be the "django_PACKAGE/" scheme, so I am suggesting this (don't use "django/PACKAGE" as maybe suggested elsewhere, this would pollute django's project namespace).
Fwiw, this is a followup to
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=567739
Thank you for considering!
Stephan
I want to use the whole registration workflow, but require manual approval for a beta period to avoid open access. Is there a setting/way to do that?
Thanks for the great app.
I'm wondering if it would be a good idea to use forms.ModelForm instead of forms.Forms for the registration forms to follow django's DRY concept?
That would also make extension through inheritance more proper / easy, e.g. for a UserProfile model.
If you agree I'd work on that next week or so
Hi James,
in the Debian packaging, there is some legacy patch:
Not knowing better, I am still using that patch for 2.1.2 in the Debian packaging.
It would be very helpful do have your opinion on that -- i.e., is it a bug at all, can or should I drop it for 2.1.2?
Thanks!
Stephan
i have a custom user model which basically changes user table name from auth_user to customuser
from django.db import models
from django.contrib.auth.models import AbstractUser
class customuser(AbstractUser , models.Model):
class Meta:
swappable = 'AUTH_USER_MODEL'
db_table = 'customuser'
and in my settings i have
AUTH_USER_MODEL = 'customuser.customuser'
so every thing works i can login , change my password but only when i try to register i get this error
ProgrammingError at /auth/register/
(1146, "Table 'django_usertest.auth_user' doesn't exist")
Request Method: POST
Request URL: http://localhost:8000/auth/register/
Django Version: 1.9.6
Exception Type: ProgrammingError
Exception Value:
(1146, "Table 'django_usertest.auth_user' doesn't exist")
Exception Location: c:\Python344\lib\site-packages\MySQLdb\connections.py in query, line 280
Python Executable: c:\Python344\python.exe
Python Version: 3.4.4
Python Path:
['C:\wamp\www\django\usertest3',
'C:\Windows\system32\python34.zip',
'c:\Python344\DLLs',
'c:\Python344\lib',
'c:\Python344',
'c:\Python344\lib\site-packages']
Server time: Mon, 23 May 2016 02:57:54 +0430
why it selects/updates user from new table on login/repassword but only on register i get this error ?
btw i can make superuser from command line ... that's how i tested login
The changes in 626d876 does not check if the user is_active
before deleting it.
Meaning the cleanupregistration
management command now deletes every user ever registered before ACCOUNT_ACTIVATION_DAYS
days ago.
We've had to restore the database on a customer server twice now because all the users disappeared, before we found this bug.
Hi,
I'm using Django 1.9 and I'm having some difficulties trying to use a custom template for password change, /accounts/password/change/
Does anyone know how to override the default template?
Should we add base templates for example? I think that will be easier to use, maybe I can create some pull request for templates files.
instead of just calling super(RegistrationForm, self).clean()
shouldn't it be return super(RegistrationForm, self).clean()
?
RegistrationForm is inherited from UserCreationForm and uses model declaration from it's Meta.
The problem is that user model in UserCreationForm defined in a wrong way, not with get_user_model(), but imported directly from django.contrib.auth.models. It causes a bug during registration if User model is custom.
While the docs say all sorts of things about how to include various variables in the email templates, they don't actually explain what path to direct the user towards and how the registration key should be included in it. I was only able to deduce this from https://github.com/macdhuibh/django-registration-templates/blob/master/registration/activation_email.txt and I find it bizarre that it's never explained. Unless I'm just missing something here.
I'm trying to create a subclass of RegistrationForm
that restricts the email address to a specific list of domains but I can't manage to make it work.
Here is the form
from registration.forms import RegistrationForm
class EmailDomainFilterRegistrationForm(RegistrationForm):
# List of allowed email domains
allowed_domains = ['epita.fr', 'lrde.epita.fr']
def clean_email(self):
submitted_data = self.cleaned_data['email']
domain = submitted_data.split('@')[1]
if domain not in self.allowed_domains:
raise forms.ValidationError(
'You must register using an email address with a valid '
'domain ({})'.format(', '.join(self.allowed_domains))
)
return submitted_data
and my urls.py
from django.conf.urls import include, url
from django.views.generic.base import TemplateView
from registration.backends.hmac.views import ActivationView, RegistrationView
from hitchike.forms import EmailDomainFilterRegistrationForm
urlpatterns = [
url(r'^activate/complete/$',
TemplateView.as_view(
template_name='registration/activation_complete.html'
),
name='registration_activation_complete'),
# The activation key can make use of any character from the
# URL-safe base64 alphabet, plus the colon as a separator.
url(r'^activate/(?P<activation_key>[-:\w]+)/$',
ActivationView.as_view(),
name='registration_activate'),
url(r'^register/$',
RegistrationView.as_view(),
{ 'form_class': EmailDomainFilterRegistrationForm },
name='registration_register'),
url(r'^register/complete/$',
TemplateView.as_view(
template_name='registration/registration_complete.html'
),
name='registration_complete'),
url(r'^register/closed/$',
TemplateView.as_view(
template_name='registration/registration_closed.html'
),
name='registration_disallowed'),
url(r'', include('registration.auth_urls')),
]
But I can register with any email domain, as if my validation wasn't called at all.
What am I doing wrong?
Hi,
I'm using django-registration==2.0.3 (with Django==1.9.1). When using the HMAC workflow, the user is able to submit the form without an e-mail address, since this is an optional field in the user model. When the e-mail is empty the flow breaks with an SMTP error.
Am I missing something about the configuration? There is a built-in way to avoid this problem?
thanks!
The activate_user function has not been built with security in mind. It would be possible for an attacker to activate an user without knowing the activation key using a side channel timing attack. I would recommend to adapt the double HMAC verification method in order to prevent such attacks. You can use the key defined in the django settings in the HMAC.
Let's say I have a pretty typical Django project with django.contrib.auth
URLs, like this:
urlpatterns = [
url(r'^accounts/', include('django.contrib.auth.urls')),
]
As you can see from the source code of auth.urls
, it provides these URLs:
login
logout
password_change
password_change_done
password_reset
password_reset_done
password_reset_confirm
password_reset_complete
This is exactly the same list as the URLs provided by registration.auth_urls
, just with the auth_
prefix:
auth_login
auth_logout
auth_password_change
auth_password_change_done
auth_password_reset
auth_password_reset_done
auth_password_reset_confirm
auth_password_reset_complete
However, if I search for auth_login
, auth_logout
, or any of these previous URL names, I cannot find any of them documented.
All the auth_
URLs point to django.contrib.auth
views, so it doesn't seem like auth_
views are necessary. They use the same template names (registration/login.html
, etc.) Interesting, the regexes are slightly different (r'^password/change/$'
instead of r'^password_change/$'
).
It seems like this should be the suggested URL config:
urlpatterns = [
url(r'^accounts/', include('django.contrib.auth.urls')),
url(r'^accounts/', include('registration.backends.hmac.urls')), # change backend if desired
# ...
]
That way, the existing registration/login.html
template does not need to be changed, and {% url "login" %}
does not need to be changed to {% url "auth_login" %}
.
Is my understanding correct? If so, I would be glad to submit a documentation pull request.
With django-registration==2.1.0 and django==1.9.7 when trying to register a user that already exists in the database a "django.db.utils.IntegrityError: UNIQUE constraint failed: auth_user.username" exception is raised and not handled. This seems to be because you override clean in forms.RegistrationForm and are not calling super().clean().
In init of Djangos forms.BaseModelForms the docs say "...self._validate_unique will be set to True by BaseModelForm.clean(). It is False by default so overriding self.clean() and failing to call super will stop validate_unique from being called ..."
Is there a way to build an absolute URL in the activation e-mail? The request does not seem to be available in the activation_email.txt
template.
I see that you're passing in the site
parameter, so you probably expect that this should be done through the sites framework. But since 1.8 (iirc) this is not enabled by default. Also, I don't want to put an URL configuration in my database if it can just live in the settings or be built from the request info.
Therefore, it would be great if you could pass in the request
parameter to the context (see render_to_string docs).
Hello, thanks for great app. The problem is below.
Should you need to contact me: [email protected]
Django==1.9.6
django-registration==2.0.4
Python 3.5.1
In settings: ACCOUNT_ACTIVATION_DAYS = 7
In other words I can doublecheck:
(photoarchive) michael@michael:~/workspace/photoarchive/photoarchive$ python manage.py shell
Python 3.5.1 (default, Dec 18 2015, 00:00:00)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
|>>> import django
|>>> django.conf.settings.ACCOUNT_ACTIVATION_DAYS
7
Then I just run the tests. Everything is fine but one test:
(photoarchive) michael@michael:~/workspace/photoarchive/photoarchive$ python manage.py test registration
Creating test database for alias 'default'...
...........E................................/home/michael/workspace/venvs/photoarchive/lib/python3.5/site-packages/django/core/management/base.py:577: RemovedInDjango110Warning: NoArgsCommand class is deprecated and will be removed in Django 1.10. Use BaseCommand instead, which takes no arguments by default.
RemovedInDjango110Warning
Traceback (most recent call last):
File "/home/michael/workspace/venvs/photoarchive/lib/python3.5/site-packages/registration/tests/test_hmac_workflow.py", line 110, in test_activation_expired
user.date_joined - datetime.datetime.fromtimestamp(0)
TypeError: can't subtract offset-naive and offset-aware datetimes
For what reason are template names hard coded in view functions!? It would be very nice if someone could use custom templates...
Is this package related to https://github.com/macropin/django-registration django-registration-redux?
If I configure my urls.py as mentioned in the documentation for custom user models, I wasn't getting the registration complete view/template when redirected to /register/complete/
. It was just rendering the registration view and form again. I also had to include the following:
url(r'^accounts/register/complete/$',
TemplateView.as_view(
template_name='registration/registration_complete.html'
),
name='registration_complete')
I've noticed strange situation. When I have url:
`
auth_patterns = [
url(r'^', include('registration.backends.hmac.urls')),
]
urlpatterns = i18n_patterns(
url(r'^admin/', admin.site.urls),
url(r'^$', login_required(HomeView.as_view()), name='index'),
url(r'^accounts/', include(auth_patterns)),
)
`
everything works fine, but when I force unique email adress
url(r'^register/$', RegistrationView.as_view(form_class=RegistrationFormUniqueEmail), name='registration_register' ),
Email is sending, but when I click on activation link i get activate.html (which is rendered when activation fails). I tried to debug registration app and I've noticed that this issue is propably in this fragment of code. (registration.backends.hmac.views.ActivationView)
`
def validate_key(self, activation_key):
"""
Verify that the activation key is valid and within the
permitted activation time window, returning the username if
valid or None
if not.
"""
try:
username = signing.loads(
activation_key,
salt=REGISTRATION_SALT,
max_age=settings.ACCOUNT_ACTIVATION_DAYS * 86400
)
return username
# SignatureExpired is a subclass of BadSignature, so this will
# catch either one.
except signing.BadSignature:
return None
`
It returns None so try-code throwing BadSignature, but why?
Hello
Not sure if this is something I did on my end or not but I tried a "pip install django-registration" and version 1.0 of the package was installed. I tried "pip install django-registration==1.8" and received a message:
Could not find a version that satisfies the requirement django-registration==1.8 (from versions: 0.7, 0.8, 1.0)
No matching distribution found for django-registration==1.8
I can always do a manual install but I thought I might check with you first on reasons why this may be happening?
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.