GithubHelp home page GithubHelp logo

sunscrapers / djoser Goto Github PK

View Code? Open in Web Editor NEW
2.5K 38.0 454.0 1.6 MB

REST implementation of Django authentication system.

License: MIT License

Python 90.31% Makefile 0.38% HTML 3.64% JavaScript 5.67%
djoser rest-api authentication developer-tools python

djoser's Introduction

djoser

image

Build Status

image

image

Docs

REST implementation of Django authentication system. djoser library provides a set of Django Rest Framework views to handle basic actions such as registration, login, logout, password reset and account activation. It works with custom user model.

Instead of reusing Django code (e.g. PasswordResetForm), we reimplemented few things to fit better into Single Page App architecture.

Developed by SUNSCRAPERS with passion & patience.

image

Requirements

To be able to run djoser you have to meet the following requirements:

  • Python>=3.8
  • Django>=3.0.0
  • Django REST Framework>=3.12

Installation

Simply install using pip:

$ pip install djoser

And continue with the steps described at configuration guide.

Documentation

Documentation is available to study at https://djoser.readthedocs.io and in docs directory.

Contributing and development

To start developing on djoser, clone the repository:

$ git clone [email protected]:sunscrapers/djoser.git

We use poetry as dependency management and packaging tool.

$ cd djoser
$ poetry install --all-extras

This will create a virtualenv with all development dependencies.

To run the test just type:

$ poetry run py.test testproject

We also prepared a convenient Makefile to automate commands above:

$ make init
$ make test

To activate the virtual environment run

$ poetry shell

Without poetry

New versions of pip can use pyproject.toml to build the package and install its dependencies.

$ pip install .[test]
$ cd testproject
$ ./manage.py test

Example project

You can also play with test project by running following commands:

$ make migrate
$ make runserver

Commiting your code

Before sending patches please make sure you have pre-commit activated in your local git repository:

$ pre-commit install

This will ensure that your code is cleaned before you commit it.

Similar projects

List of projects related to Django, REST and authentication:

Please, keep in mind that while using custom authentication and TokenCreateSerializer validation, there is a path that ignores intentional return of None from authenticate() and try to find User using parameters. Probably, that will be changed in the future.

djoser's People

Contributors

akalipetis avatar andrewmeares avatar chadys avatar davidtgq avatar decentral1se avatar dekoza avatar dependabot[bot] avatar ferndot avatar gone avatar hawi74 avatar haxoza avatar hhuseyinpay avatar jaredleishman avatar kevin-brown avatar kiraware avatar konradhalas avatar loop0 avatar mmarksnippety avatar mrouhi13 avatar nikolakadic avatar nschlemm avatar pmlynarek avatar pszpetkowski avatar rugala avatar sheepyhollow avatar superhawk610 avatar ticosax avatar tomwojcik avatar zefciu avatar zilehuda avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

djoser's Issues

No module named authtoken

After following the installation instructions for Token Based Authentication I keep getting the above error. I'm using django 1.8.3 and DRF 3.1.3.

Is it possible that the version on pip is different from the one on Github?

AttributeError at /auth/register

AttributeError at /auth/register
'UserRegistrationSerializer' object has no attribute 'init_data'

I was trying to create a new user by issuing a POST request to /auth/register. Exception location is at djoser/djoser/serializers.py in save, line 34

Here are my package versions -

Django==1.7.1
djangorestframework==3.0.0
djoser==0.1.0

Can you tell me why this is happenning?

Compatibility issues with Swagger

I integrated Djoser in my Django project. The api endpoint provided are all working fine, but when I browse to the Swagger docs, it throws the following error, saying AssertionError: 'RootView' should either include a 'serializer_class' attribute, or override theget_serializer_class()method.

Here is the screenshot:-

screenshot from 2015-04-12 20 35 30

Is that a bug?

PyPi version out of date

I have noticed that the djoser version installed from pypi assumes no trailing slash is found at the end of the URL, while the current urls.py does assume trailing slash. I'd assume that it's because the pypi version is out of sync with the github one. Any plans to update it?

html email templates

Hi guys, really glad I found this app, it's helping me a lot. One of the reasons is how straight-forward it is to customise behaviour like this compared to the other apps, but have one question. I want to have html templates for activation/reset. Currently I'm overriding the activation view like this:

class CustomRegistrationView(RegistrationView):
    """
    Override the Djoser view to provide an html template for activation email.
    """

    def get_send_email_extras(self):
        extras = super(CustomRegistrationView, self).get_send_email_extras()
        extras['html_body_template_name'] = 'activation_email_body.html'
        return extras

Is there an easier way of doing this? Would you guys consider looking for html templates by default or adding a config option for it? Cheers!

Feedback and questions

hi Guys,

I do like the product.

The following is the feedback and questions:

/password/reset

If you provide invalid email it does return you 200 HTTP code and doesn't tell you that email is not found in the database. I'd like to get a different response back, such as 404 with "details": "such email doesn't exists"

How to integrate with custom model inherited from django.contrib.auth.user model?

Would be awesome if small tutorial is provided

Update profile - 3 methods?

What's the motivation to make a 3 different methods to update profile /me and POST /username, POST /password? I think it's nicer to just call PUT /me method to update username, password. Otherwise a client should hit 3 different API endpoints.

How to update other fields of profile with PUT /me?

It seems right now it only updates email field and nothing else. What about first_name, last_name? What about other custom fields of the model (question #2 above)?

HTTP Error codes (404, 422)

For example when you do POST /login with non-existing username you get this

400
{
  "non_field_errors": [
    "Unable to login with provided credentials."
  ]
}

but it's correct request, while the response says: 400 (Bad Request). It would be nicer to have 404, error.

Also when you do POST /register and provide non-unique username you get this:

400
{
  "username": [
    "This field must be unique."
  ]
}

however this is a business logic error and code 422 is better for such use case

Generic message

If I do POST /username and provide incorrect value of current_password I get this:

400
{
  "current_password": [
    "Invalid password."
  ]
}

Which makes it hard for the client (say Android mobile app) as I need to know and define maps ahead of time.

Would not it better to return something like this:

422
{
  "errors": 
      [
           {"field": "password", "message""Invalid password provided"},
           ....
     ]
}

the same would be for registration and other methods. That way I don't need to define the model for each JSON response body, as they're all generic. Otherwise for each API call you have to create a custom parser (and you have to know all the fields ahead of time).

Validation for Incorrect request

If I do:
PUT /me

{
    "email": "[email protected]",
    "eeee": "jim",
    "zzz": "smith"
}

I'll get 200 HTTP code back:

{
  "email": "[email protected]",
  "id": 1,
  "username": "admin"
}

However the example above submitted 2 random fields. I would value if API return something like this:

422 or 400
{
  "errors": 
      [
           {"field": "eee", "message""Unknown field"},
           {"field": "zzz", "message""Unknown field"},
           ....
     ]
}

Questions about /password/reset/confirm

I've done some testing, and I'm puzzled about the /password/reset/confirm endpoint. I'm probably missing something obvious...

The password-reset email will contain a link of the form /password/reset/confirm/{id}/{token}. Your documentation says this is a POST endpoint. yet the browser will issue a GET when the user clicks on the link. How does this work?

The URLconf has the regex r'^password/reset/confirm$', yet the link will be /password/reset/confirm/{id}/{token} . The regex includes the EOL match, so I don't see how this can ever match the URL.

In the ActionViewMixin, it appears that request.DATA expects the uid and token to have been sent in via a query string. It also seems to expect the new_password to be present, otherwise self.get_serializer() returns False. Is this correct?

Advice: Overriding templates

I just wanted to confirm that there isn't an easier way to customize the templates, other than:

  1. Subclass the views that use templates.
  2. Create and include my own version of djoser.urls

Correct?

ImportError: No module named authtoken

When I try to use url(r'^auth/', include('djoser.urls.authtoken')),, I get the error ImportError: No module named authtoken. This is with djoser 0.3.1, djangorestframework 3.1.3 and Django 1.8.3.

AssertionError at /auth/logout

AssertionError at /auth/logout
'LogoutView' should either include a 'serializer_class' attribute, or use the 'model' attribute as a shortcut for automatically generating a serializer class.

i think this is due to a change in DRF. Here are my versions:

Django==1.6.8
djoser==0.1.0
djangorestframework==2.4.4

Pull request with a fix incoming...

Set User.is_active=False on registration, until activation

User.is_active is being set to True in the registration view. While a token is not necessarily being granted, the user is still activated. When ActivationView is hit, is_active is being set to True, when it's already True.

Perhaps is_active should be set to True if LOGIN_AFTER_REGISTRATION is True only.

DFR3 User Activation

I get an unauthorized error when clicking the email activation link in the sent email. Do you know if this should work out-of-the-box?

Username is not validated properly for `set_username` endpoint

To be precise the issue is caused by function called create_username_field(). It creates the serializer field but it doesn't add the validators to this field instance. It just doesn't take into account the parameters passed to username model field.

Registration api failing if csrfmiddlewaretoken present in request

If we remove csrfmiddlewaretoken form init_data then only registration succeeded.
del self.init_data['csrfmiddlewaretoken']

Added statement del self.init_data['csrfmiddlewaretoken'] in save method

class UserRegistrationSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = tuple(User.REQUIRED_FIELDS) + (
            User.USERNAME_FIELD,
            'password',
        )
        write_only_fields = (
            'password',
        )

    def save(self, **kwargs):
        self.object = User.objects.create_user(**dict(self.init_data.items()))
        return self.object

400 error when POSTing to /auth/login w/ unique email field

Hey there, awesome package. Really makes a lot of sense.

I'm currently tackling an issue, in which I am just trying to access the basic /auth/login endpoint.

I have a custom user model, which I have created with the help of the django-authtools package. My username is on an email field, which has unique set to True.

When I try to POST to /login/, I get a 400 error saying that the email field must be unique. I assume this is because it is trying to POST on a unique field... can that be a PUT, or is there another way to go about solving this issue?

Happy to provide code samples if needed, and I'll keep tinkering around and see if I can come up with a solution.

Thanks again!

/login username parameter isn't displayed by swagger-ui

This involves multiple packages, and I'm not sure where the issue lies. I'll start here. :-)

Using...

  • djoser from the git repository's master branch
  • django-rest-swagger 0.2.9
  • and the dist directory from swagger-ui's master branch..

I find that the "username" parameter for the /login endpoint isn't displayed in the swagger-ui documentation. "Password" is there, but username is not:

screen shot 2015-04-29 at 11 30 42 am

In djoser.serializers.UserLoginSerializer.Meta.fields, "username" is not listed as a field. The username is manually picked off through User.USERNAME_FIELD, but Django Rest Swagger can't find that reference and so isn't aware of the username parameter.

Limit login attempts

I'm trying to limit login attempts, and temporary ban by ip users who exceed that limit. I've been investigating django-axes, but it's implemented in a way that makes hard to use it in a webservice.

Someone had success using it with djoser, or know an alternative solution?

Error in /auth/logout

Any time I hit the logout endpoint I get this error. If I refresh a couple of times the errors goes away I I'm able to logout.

'LogoutView' should either include a `serializer_class` attribute, or override the `get_serializer_class()` method.

django = 1.7.4
djoser = 0.2.0
django rest framework = 3.0.3

account activation

I think we have a typo here --- ActivationView is misplaced by PasswordResetConfirmView.

url(r'^activate$', views.PasswordResetConfirmView.as_view(), name='activate'),

https://github.com/sunscrapers/djoser/blob/master/djoser/urls.py#L13

Another question is that why we need to use POST method for activation? The activation link is sent via email, and user's click supposes to activate the related account. Such click would generate a GET request, I suppose.

Add frontend demo app to test project

It would be awesome to have simple frontend demo app. I'm thinking about something really simple with VanillaJS. In the future we could also create AngulaJS library.

A djoser fork with Python 2.6 support?

Do you know of any djoser forks with Python 2.6 support?

I tried searching in Github, and on the web, but came up empty. If there aren't any, I may fork it to add 2.6 support.

Thanks!

Add support for BasicAuthentication backend

I'm hesitant to call this an issue -- more of a curiosity. Was there a reason that you chose not to implement the handling of authentication for the /login endpoint via the BasicAuthentication class in DRF?

Enhancement: Get domain for email from request

We've got 100's of tenants running out of a single settings.py file. Having settings.DOMAIN provided in settings.py is pretty limiting. Suggestion would be to pull the domain from the request. There may be a better way though.

Here is the change I made to utils.py

    def get_email_context(self, user):
        token = self.token_generator.make_token(user)
        uid = encode_uid(user.pk)
        # Pull domain from request
        try:
            domain = self.request.get_host()
        except:
            domain = settings.get('DOMAIN')
        return {
            'user': user,
            'domain': domain, # Use domain from request or if not provided fall back to settings.
            'site_name': settings.get('SITE_NAME'),
            'uid': uid,
            'token': token,
            'protocol': 'https' if self.request.is_secure() else 'http',
        }

Add support for django-rest-swagger

There are probably two things to do:

  • add integration tests to testproject to check if the Swagger doc is generated without any issues
  • fix the issue with dynamically added fields to serializers - see #41

Remove `LOGIN_AFTER_*` settings

Reasons:

  1. those settings increase code complexity too much,
  2. you could just make login request after registration/activation.

Refs: discussion in #56 PR.

'ModelSerializer' has no attribute '_field_mapping' in Django REST framework 3.1.0

Django REST framework 3.1.0

Traceback (most recent call last):
  File "/home/pokidovea/.virtualenvs/myapp/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 132, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/pokidovea/.virtualenvs/myapp/local/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/pokidovea/.virtualenvs/myapp/local/lib/python2.7/site-packages/django/views/generic/base.py", line 71, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/pokidovea/.virtualenvs/myapp/local/lib/python2.7/site-packages/rest_framework/views.py", line 452, in dispatch
    response = self.handle_exception(exc)
  File "/home/pokidovea/.virtualenvs/myapp/local/lib/python2.7/site-packages/rest_framework/views.py", line 449, in dispatch
    response = handler(request, *args, **kwargs)
  File "build/bdist.linux-x86_64/egg/djoser/utils.py", line 42, in post
    serializer = self.get_serializer(data=request.DATA)
  File "/home/pokidovea/.virtualenvs/myapp/local/lib/python2.7/site-packages/rest_framework/generics.py", line 109, in get_serializer
    return serializer_class(*args, **kwargs)
  File "build/bdist.linux-x86_64/egg/djoser/serializers.py", line 94, in __init__
    self.fields[User.USERNAME_FIELD] = create_username_field()
  File "build/bdist.linux-x86_64/egg/djoser/serializers.py", line 16, in create_username_field
    mapping_dict = serializers.ModelSerializer._field_mapping.mapping
AttributeError: type object 'ModelSerializer' has no attribute '_field_mapping'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.