omab / django-social-auth

Django social authentication made simple
https://groups.google.com/group/django-social-auth
BSD 3-Clause "New" or "Revised" License
2.65k stars 756 forks source link

Value too long DatabaseError with LinkedIn backend #784

Closed antonagestam closed 7 years ago

antonagestam commented 10 years ago

DatabaseError: value too long for type character varying(30)

Traceback (most recent call last):
File "/app/.heroku/python/lib/python2.7/site-packages/newrelic-1.10.2.38/newrelic/hooks/framework_django.py", line 475, in wrapper return wrapped(*args, **kwargs)
File "/app/.heroku/python/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 77, in wrapped_view return view_func(*args, **kwargs)
File "/app/.heroku/python/lib/python2.7/site-packages/social_auth/decorators.py", line 29, in wrapper return func(request, request.social_auth_backend, *args,\ **kwargs)
File "/app/.heroku/python/lib/python2.7/site-packages/social_auth/views.py", line 41, in complete return complete_process(request, backend, *args, **kwargs)
File "/app/.heroku/python/lib/python2.7/site-packages/social_auth/views.py", line 107, in complete_process user = auth_complete(request, backend, *args,\ **kwargs)
File "/app/.heroku/python/lib/python2.7/site-packages/social_auth/views.py", line 190, in auth_complete return backend.auth_complete(user=user, request=request,\ *args, **kwargs)
File "/app/.heroku/python/lib/python2.7/site-packages/social_auth/backends/contrib/linkedin.py", line 127, in auth_complete return super(LinkedinAuth, self).auth_complete(*args,\ **kwargs)
File "/app/.heroku/python/lib/python2.7/site-packages/social_auth/backends/__init__.py", line 681, in auth_complete return self.do_auth(access_token, *args, **kwargs)
File "/app/.heroku/python/lib/python2.7/site-packages/social_auth/backends/__init__.py", line 697, in do_auth return authenticate(*args, **kwargs)
File "/app/.heroku/python/lib/python2.7/site-packages/django/contrib/auth/__init__.py", line 45, in authenticate user = backend.authenticate(**credentials)
File "/app/.heroku/python/lib/python2.7/site-packages/social_auth/backends/__init__.py", line 114, in authenticate out = self.pipeline(pipeline, *args, **kwargs)
File "/app/.heroku/python/lib/python2.7/site-packages/social_auth/backends/__init__.py", line 143, in pipeline result = func(*args, **out) or {}
File "/app/.heroku/python/lib/python2.7/site-packages/social_auth/backends/pipeline/user.py", line 134, in update_user_details user.save()
File "/app/.heroku/python/lib/python2.7/site-packages/django/db/models/base.py", line 463, in save self.save_base(using=using, force_insert=force_insert,\ force_update=force_update)
File "/app/.heroku/python/lib/python2.7/site-packages/django/db/models/base.py", line 529, in save_base rows = manager.using(using).filter(pk=pk_val)._update(values)
File "/app/.heroku/python/lib/python2.7/site-packages/django/db/models/query.py", line 560, in _update return query.get_compiler(self.db).execute_sql(None)
File "/app/.heroku/python/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 988, in execute_sql cursor = super(SQLUpdateCompiler, self).execute_sql(result_type)
File "/app/.heroku/python/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 818, in execute_sql cursor.execute(sql, params)
File "/app/.heroku/python/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py", line 52, in execute return self.cursor.execute(query, args)
File "/app/.heroku/python/lib/python2.7/site-packages/newrelic-1.10.2.38/newrelic/hooks/database_dbapi2.py", line 36, in execute return self._nr_cursor.execute(sql, *args, **kwargs)
DatabaseError: value too long for type character varying(30)
Pragueham commented 10 years ago

I'm getting a similar issue using google oauth:

Environment:

Request Method: GET Request URL: http://***/complete/google-oauth2/?state=gGS6LwKcStXSZxHILVRfQQyiecUeUOl6&code=4/_7U5lalbXwuUX8qok0XMjxuTyWQq.IrmImxWg29MQYKs_1NgQtmXD8TN0hwI

Django Version: 1.6.1 Python Version: 2.7.6 Installed Applications: ('django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.admin', 'south', 'social_auth', 'holiday_tracker') Installed Middleware: ('django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware')

Traceback: File "/app/.heroku/python/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response

  1. response = wrapped_callback(request, _callback_args, *_callback_kwargs) File "/app/.heroku/python/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
  2. return view_func(_args, *_kwargs) File "/app/.heroku/python/lib/python2.7/site-packages/social_auth/decorators.py" in wrapper
  3. return func(request, request.social_auth_backend, _args, *_kwargs) File "/app/.heroku/python/lib/python2.7/site-packages/social_auth/views.py" in complete
  4. return complete_process(request, backend, _args, *_kwargs) File "/app/.heroku/python/lib/python2.7/site-packages/social_auth/views.py" in complete_process
  5. user = auth_complete(request, backend, _args, *_kwargs) File "/app/.heroku/python/lib/python2.7/site-packages/social_auth/views.py" in auth_complete
  6. return backend.auth_complete(user=user, request=request, _args, *_kwargs) File "/app/.heroku/python/lib/python2.7/site-packages/social_auth/backends/init.py" in auth_complete
  7. _args, *_kwargs) File "/app/.heroku/python/lib/python2.7/site-packages/social_auth/backends/init.py" in do_auth
  8. return authenticate(_args, *_kwargs) File "/app/.heroku/python/lib/python2.7/site-packages/django/contrib/auth/init.py" in authenticate
  9. user = backend.authenticate(credentials) File "/app/.heroku/python/lib/python2.7/site-packages/social_auth/backends/init**.py" in authenticate
  10. out = self.pipeline(pipeline, _args, *_kwargs) File "/app/.heroku/python/lib/python2.7/site-packages/social_auth/backends/init.py" in pipeline
  11. result = func(_args, *_out) or {} File "/app/.heroku/python/lib/python2.7/site-packages/social_auth/backends/pipeline/social.py" in associate_user
  12. social = UserSocialAuth.create_social_auth(user, uid, backend.name) File "/app/.heroku/python/lib/python2.7/site-packages/social_auth/db/base.py" in create_social_auth
  13. return cls.objects.create(user=user, uid=uid, provider=provider) File "/app/.heroku/python/lib/python2.7/site-packages/django/db/models/manager.py" in create
  14. return self.get_queryset().create(**kwargs) File "/app/.heroku/python/lib/python2.7/site-packages/django/db/models/query.py" in create
  15. obj.save(force_insert=True, using=self.db) File "/app/.heroku/python/lib/python2.7/site-packages/django/db/models/base.py" in save
  16. force_update=force_update, update_fields=update_fields) File "/app/.heroku/python/lib/python2.7/site-packages/django/db/models/base.py" in save_base
  17. updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields) File "/app/.heroku/python/lib/python2.7/site-packages/django/db/models/base.py" in _save_table
  18. result = self._do_insert(cls._base_manager, using, fields, update_pk, raw) File "/app/.heroku/python/lib/python2.7/site-packages/django/db/models/base.py" in _do_insert
  19. using=using, raw=raw) File "/app/.heroku/python/lib/python2.7/site-packages/django/db/models/manager.py" in _insert
  20. return insert_query(self.model, objs, fields, **kwargs) File "/app/.heroku/python/lib/python2.7/site-packages/django/db/models/query.py" in insert_query
  21. return query.get_compiler(using=using).execute_sql(return_id) File "/app/.heroku/python/lib/python2.7/site-packages/django/db/models/sql/compiler.py" in execute_sql
  22. cursor.execute(sql, params) File "/app/.heroku/python/lib/python2.7/site-packages/django/db/backends/util.py" in execute
  23. return super(CursorDebugWrapper, self).execute(sql, params) File "/app/.heroku/python/lib/python2.7/site-packages/django/db/backends/util.py" in execute
  24. return self.cursor.execute(sql, params) File "/app/.heroku/python/lib/python2.7/site-packages/django/db/utils.py" in exit
  25. six.reraise(dj_exc_type, dj_exc_value, traceback) File "/app/.heroku/python/lib/python2.7/site-packages/django/db/backends/util.py" in execute
  26. return self.cursor.execute(sql, params)

Exception Type: DataError at /complete/google-oauth2/ Exception Value: value too long for type character varying(16)

goldsmith commented 10 years ago

@antonagestam @Pragueham I'm getting this issue as well. Any idea why it happened for you guys?

I'm using Google OAuth2 backend

Pragueham commented 10 years ago

@antonagestam @goldsmith no nothing - maybe @omab could help?

sipp11 commented 10 years ago

This is django.contrib.auth.models related issue. It's because username and first_name and last_name field of auth_user table are fixed at 30 characters while user's data has longer than 30 characters.

This can be easily fixed by altering above fields to bigger one. I used varchar(75) and I didn't see any problem so far. If you are using all Django form, you might need to let Django know too. For example,

User._meta.get_field_by_name('username')[0].max_length = 75
User._meta.get_field('username').validators[0].limit_value = 75
User._meta.get_field_by_name('first_name')[0].max_length = 75
User._meta.get_field('first_name').validators[0].limit_value = 75
User._meta.get_field_by_name('last_name')[0].max_length = 75
User._meta.get_field('last_name').validators[0].limit_value = 75
omab commented 10 years ago

You can also add a pipeline entry before the user instance is created, and modify the values in details to fit your database limits.

Pragueham commented 10 years ago

Thanks, I'm obviously being thick, but having read the docs, I still don't understand @omab 's solution. Can you please explain a little more?

omab commented 10 years ago

@Pragueham, create a pipeline function (docs at http://django-social-auth.readthedocs.org/en/latest/pipeline.html) like this:

from django.contrib.auth.models import User
from django.db.models.fields import FieldDoesNotExist

def clean_user_details(backend, details, user=None, *args, **kwargs):
    if user is not None:
        return
    details_copy = details.copy()
    for field_name, field_value in details.items():
        try:
            field = User._meta.get_field(field_name)
        except FieldDoesNotExist:
            pass
        else:
            if len(field_value) > field.max_length:
                details_copy[field_name] = field_value[:field.max_length]
    return details_copy

And put it before the create_user entry in the pipeline. That pipeline will enforce your fields limits to the values that will be used later to create the user.

jpatel3 commented 3 years ago

@omab is above modification in pipeline is still the best possible solution? I am running into similar issue with username field coming from google social signin, and would like to add truncation so that user creation doesn't fail.