I have a Django server (Using PostGis) and I want to disable everything related to authentication:
When entering the admin no authentication will be required
In the admin hide the Users/Groups
After searching online I tried the combination of this & this
It does get me the result I hoped for, until I try to add an object via the admin. Then I get an IntegrityError:
insert or update on table "django_admin_log" violates foreign key constraint "django_admin_log_user_id_c564eba6_fk_auth_user_id"
DETAIL: Key (user_id)=(1) is not present in table "auth_user".
I tried solving it using solutions like this and it didn't help.
I don't mind having a solution in a whole new approach as long as the end goal is acquired.
Thanks ahead,
As the Django project is running in dockers, and can be deployed when the users already exist or don't I ended up doing:
# Create superuser for admin use in case it doesn't exist
try:
User.objects.get_by_natural_key('admin')
except User.DoesNotExist:
User.objects.create_superuser('admin', 'admin#comapny.com', '123456')
Hope this helps someone one day. Full use:
from django.contrib import admin
from django.contrib.auth.models import User, Group
# We add this so no authentication is needed when entering the admin site
class AccessUser(object):
has_module_perms = has_perm = __getattr__ = lambda s,*a,**kw: True
admin.site.has_permission = lambda r: setattr(r, 'user', AccessUser()) or True
# We add this to remove the user/group admin in the admin site as there is no user authentication
admin.site.unregister(User)
admin.site.unregister(Group)
# Create superuser for admin use in case it doesn't exist
try:
User.objects.get_by_natural_key('admin')
except User.DoesNotExist:
User.objects.create_superuser('admin', 'admin#optibus.co', '123456')
Related
O.K. I have a headache with this problem. I have to different sites(non django) with login option and I would like to join in it into one new website based on django.
Each of these two user databases consist of table with columns:(username, password, e-mail).
The problem is, I just can not copy it to User table in Django as we all know django is very rigid about it, so I am trying to think a way, existing users would be able to login to site as nothing has changed.
Is there any django/pythonic way to do so?
I was thinking to create an app, which would take a foreign key to User model. Within User model I would create two users (database_1, database_2), so whenever a user from database 1 would login, e.g. JohnSmith, he would be connected as database_1 user, but so would JessicaSimpson if she would be in database 1. I am just thing to create Authentication and Authorization app as system app in some way... Is this a right way thinking? Would love to hear from professionals. Thanks
in models:
from django.db import models
from django.contrib.auth.models import User, Group
# Create your models here.
class New_users(models.Model):
new_user_id = models.ForeignKey(User, unique=False)
username = models.CharField(max_length=25)
password = models.CharField(max_length=25)
email = models.CharField(max_length=25)
in views:
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def home(request):
if request.method == 'POST':
#if username and password from New_users are ok...
login()#User where id is the same blah blah....
I'm a professional, and I would add the old users to the new DB and put in random passwords. I would also make a table of old_users with their old hashed passwords.
I would flag these old users such that, when they visit the new app, they would be forced to enter their old pw (you'd need to know the hash method) and, if successful, then set the old pw to the new user, and log them in.
If that's too much trouble, you could write a script that sends all the old users an email (naturally, you have their email address) and a link to a change_password form. It's pretty easy to extend the django reset password functionality. And it's a good thing to have.
Could you just migrate the existing users into the new database by looping through the existing users and calling the create_user function? This would take care of the password hashing and everything, assuming that you can decrypt your current passwords back to plaintext.
I have setup my Django (1.8) admin to allow superusers to create new users interactively. My User model is customized using AbstractUser which means my admin file looks like this:
admin.py
from django.contrib import admin
from app.models import CPRUser
class UserAdmin(admin.ModelAdmin):
model = CPRUser
extra = 1
admin.site.register(CPRUser, UserAdmin)
and here is the model:
class CPRUser(AbstractUser):
student = models.PositiveIntegerField(verbose_name=_("student"),
default=0,
blank=True)
saved = models.IntegerField(default=0)
This appears to work OK, I can go through the admin and set the password, username and all the other custom fields of a new user. However, when I try and login with the newly created user, some part of the authentication process fails. I login from a page which is using the auth_views.login view and the boilerplate django login template.
On the other hand, if I create a new user using either manage.py createsuperuser or createuser() within the django shell, these users can login fine. This leads me to suspect it is to do with password storage or hashing - currently in the admin I can just type in a new user's password. Thing is, that is what I want to be able to do. How can I get this desired result - I want non-IT savy managers (whose details I won't have) to be able to easily create new users in the admin. I am aware of the risks of such a system.
The docs seem contradictory on setting this interactive user creation up in one section:
"The “Add user” admin page is different than standard admin pages in that it requires you to choose a username and password before allowing you to edit the rest of the user’s fields."
and then a couple of paragraphs later:
"User passwords are not displayed in the admin (nor stored in the database)"
Here is a screen shot of my admin:
How can I make Django accept the login attempts of users created interactively via the admin?
This is described in the documentation,
If your custom User model extends django.contrib.auth.models.AbstractUser, you can use Django’s existing django.contrib.auth.admin.UserAdmin class.
So, extending UserAdmin should do the trick.
I have a Django app that gets it's data completely from apis. so I don't have to use database. Session data is stored on signed cookies. I tried to code a custom User model and a custom auth backend like on the docs, but I get the following error:
django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model 'my_app.MyUser' that has not been installed
My settings.py:
AUTH_USER_MODEL = 'my_app.MyUser'
AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',
'my_app.backends.LoginAuthBackend',)
models.py:
class MyUser(object):
def save(self):
pass
objects = None
username = ""
Here, If a try use the AbstractUser from django instead of Object I got the following error: AttributeError: 'NoneType' object has no attribute '_meta' or the db table doesn't exit.
backends.py
class LoginAuthBackend(object):
def authenticate(self, username=None, password=None):
if username and password:
try:
response = my_auth_function(username, password)
if response.status_code == 200:
token = response.get('my_key')
user = MyUser()
return user
except MyCustomException:
return None
It's drives me crazy. Looks like Django that's not easy to use without a DB.
EDIT
After several of tries, a simple way to solve this is remove 'django.contrib.auth.backends.ModelBackend' from AUTHENTICATION_BACKENDS and AUTH_USER_MODEL from settings. The model continues basically the same way. works smoothly
The default set of authentication back-end processors is defined in the AUTHENTICATION_BACKENDS setting. See the Django documentation for Customizing authentication.
By default, AUTHENTICATION_BACKENDS is set to:
['django.contrib.auth.backends.ModelBackend']
That’s the basic authentication backend that checks the Django users database and queries the built-in permissions.
So, if you don't want the django.contrib.auth.backends.ModelBackend authentication method, remove that from the list. You'll probably want to find (or create) a different one and add that to the list.
I need to start using model-level permissions in my existing Django-based web service. The permission types I'd like to add are django admin's default ("add", "change", "delete") and are already there (I can see them in the admin.)
I have already many users in the database, so manual permission assignment is out of the question.
How do I auto assign these permissions for every existing user and for future users for a subset of model in my app?
You can use groups to do so, using the get_or_create method, like the code below:
from django.contrib.auth.models import Group, Permission, User
from django.contrib.contenttypes.models import ContentType
content_type = ContentType.objects.get_for_model(User)
add_permission = Permission.objects.get(content_type=content_type,codename='add_user')
change_permission = Permission.objects.get(content_type=content_type,codename='change_user')
delete_permission = Permission.objects.get(content_type=content_type,codename='delete_user')
group, created = Group.objects.get_or_create(name='your_group')
if created: #assign permission to all users in database
group.permissions.add(add_permission, change_permission, delete_permission)
for user in User.objects.all():
user.groups.add(group)
This way, if the group is not yet created, you create it, add all users in your database to it and add the permissions you want. Also, for every new user you want to add those permissions, you should add it to the group, so the following code should go on their creation:
groupGroup.objects.get(name='your_group')
user.groups.add(group)
For documentation, click here
Is it possible to use Flask-Social and Flask-Security if I only want to use Facebook Login, for example, for user registration and login, i.e. no local registration/login forms?
I looked through the Flask-Social example application and documentation but couldn't tell if this is possible. In the example application, users cannot login with Facebook unless they've previously registered. After registering with the example application, they can associate their Facebook account with their local account.
When I tried to call social.facebook.get_connection() I got an AttributeError 'AnonymousUser' object has no attribute 'id' because there's no current_user, which is defined by flask-security after registration/login.
This is doable without too much extra work using the #login_failed.connect_via decorator. With app as your instance of a Flask app, it would look like
#login_failed.connect_via(app):
def on_login_failed(sender, provider, oauth_response):
connection_values = get_connection_values_from_oauth_response(provider, oauth_response)
ds = current_app.security.datastore
user = ds.create_user( ... ) #fill in relevant stuff here
ds.commit()
connection_values['user_id'] = user.id
connect_handler(connection_values, provider)
login_user(user)
db.commit()
return render_template('success.html')
As for filling in the relevant stuff for creating the user, I just create a random string for the password, and haven't had issues leaving the email null. I also just included the exact same answer on the Flask-Social github page.