Skip to main content

A toolkit to set up web application with authentication and authorization functionalities based on Django.

Project description

easyauth: A toolkit to set up web application with authentication and authorization functionalities based on Django
====================================================================================================================
Don't need any code for authentication and authorization checking, just use configuration to enable authorization

.. image:: https://img.shields.io/travis/qingfeng0820/easyauth/master.svg
:target: https://travis-ci.org/qingfeng0820/easyauth


`中文README <https://github.com/qingfeng0820/easyauth/blob/master/README-CN.rst>`_

License
-------

`BSD License <LICENSE.txt>`_


Source code
-----------
`Github <https://github.com/qingfeng0820/easyauth>`_


Develop environment
-------------------
- Python 2.7
- pip
- npm (can install nodejs which contains npm)


Installation
------------

from pypi

.. code-block:: shell

pip install easyauth



Setup your own project via easyauth
-----------------------------------

1. Create your app by below command(it will create project under current folder):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. code-block:: shell

> make_project {your_app_name}

2. Setup backend which based on Django
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

1). Change configurations of the easyauth and Django based project
- You can keep the configuration as default if you just want to trial
- Main configurations are in {your_app_name}/settings/production.py
- {your_app_name}/settings/local.py is used for some special configuration only need enabled in development

2). Change your User mode located in {your_app_name}/models.py
- see below example code (don't need add serializer, view and permission classes for User model)

.. code-block:: python

from easyauth.models import AbstractUser


class User(AbstractUser):
# you can define additional fields
{Other field} = models.CharField(...)
# You can specify the some other field to be USERNAME_FIELD.
# USERNAME_FIELD is unique field to identity an user for login
# Default is phone
USERNAME_FIELD = {Other field to stand for username}

# You can specify the USER_DEPART_FIELD field if you user model is grouped by department or company
# For with depart field case, the permitted user can only maintain the users in the same department.
# Default value is None for USER_DEPART_FIELD.
USER_DEPART_FIELD = "company"
company = models.ForeignKey(Company, related_name='users', null=True)

# Filter properties are defined in view classed for filtering.
# But the User model related views are defined in easyauth, you cannot create or change filter properties
# Thus there is another way to add filter properties like below in user model
FILTER_FIELDS = ('company__name', ...)
SEARCH_FIELDS = (...)
ORDERING_FIELDS = ('company__name', ...)

# PS: You can have no implementation of this class (just add 'pass' in this class) if you just want to trial.

3). Create your own models, serializers and views
- modify {your_app_name}/models.py to add your own models

.. code-block:: python

class DummyModel(models.Model):
name = models.CharField(max_length=100, unique=True)
created_time = models.DateTimeField(auto_now_add=True)

class Meta:
permissions = (
("maintain_dummy_model", _("Can maintain dummy model")), # <=== define a permission in your model
)
ordering = ('id', )

- create {your_app_name}/serializers.py to add your own serializers

.. code-block:: python

from rest_framework import serializers

from {your_app_name} import models

class DummyModelSerializer(serializers.ModelSerializer):

class Meta:
model = models.DummyModel
fields = '__all__'
depth = 1


- create {your_app_name}/permissions.py to add your own permission classes

.. code-block:: python

from easyauth.permissions import DBBasedPermissionsAll


class DummyModelMaintainPermission(DBBasedPermissionsAll):
required_permission_names = ["{your_app_name}.maintain_dummy_model", ] # <=== permission check class for the defined permission in your model

- create {your_app_name}/views.py to add your own views

.. code-block:: python

from rest_framework import viewsets, permissions

from {your_app_name} import models, serializers
from {your_app_name}.permissions import DummyModelMaintainPermission

class DummyModelViewSet(viewsets.ModelViewSet):
queryset = models.DummyModel.objects.all()
serializer_class = serializers.DummyModelSerializer
permission_classes = (DummyModelMaintainPermission, ) # <=== use the defined permission class
# Or you can the common permission class DjangoModelPermissions instead, which provided by Rest framework lib
# permission_classes = (permissions.DjangoModelPermissions, )

- modify {your_app_name}/urls.py to add your API urls

.. code-block:: python

from django.conf.urls import url, include
from rest_framework import routers

from easyauth import urls as auth_urls
from easyauth import admin_urls as user_admin_urls

from {your_app_name} import views

router = routers.DefaultRouter(trailing_slash=False)
# app apis
router.register(r'api/dummy_models', views.DummyModelViewSet, base_name='dummy_model') # <=== define your API url

urlpatterns = router.urls

urlpatterns += [
# url(r'^admin/', admin.site.urls),
# auth apis including login, password reset
url(r'^api-auth/', include(auth_urls)), # <=== authentication APIs provided by easyauth
# user crud apis - only used by administrator
url(r'^api/', include(user_admin_urls)), # <=== user/group/permission admin APIs provided by easyauth
]

4). Go to {your_app_name} folder to initiate database
- run below commands:

.. code-block:: shell

{your_app_name}> python manage.py makemigrations
{your_app_name}> python manage.py makemigrations {your_app_name}
{your_app_name}> python manage.py migrate

5). Then create a superuser
- run below command:

.. code-block:: shell

{your_app_name}> python manage.py createsuperuser

6). Start your backend for your development test
- run below command:

.. code-block:: shell

{your_app_name}> python manage.py runserver 0.0.0.0:80

7). Have a test
- Maintain authentication and authorization test
- User the created super user to login
- Create roles/groups
- Create users, and assign them proper roles or permissions
- All APIs provided by easyauth
- user group(role) admin APIs (super user or have related permissions)
- /api/groups GET: Get all user groups (super user or have 'query_group' permission)
- /api/groups POST: Create an user group (super user)
- /api/groups/[group_id] GET: Get an user group (super user or have 'query_group' permission)
- /api/groups/[group_id] PUT or PATCH: Modify an user group (super user)
- /api/groups/[group_id] DELETE: Delete an user group (super user)
- user admin APIs (super user or have related permissions, if department enabled for user model, user can only maintain users in the same department if he/she has related permissions)
- /api/users GET: Get all users (super user or have 'query_user' permission)
- /api/users POST: Create an user (super user or have 'create_user' permission)
- /api/users/[user_id] GET: Get a specific user (super user or have 'query_user' permission)
- /api/users/[user_id] PUT or PATCH: Modify a specific user (super user or have 'change_user' permission)
- /api/users/[user_id] DELETE: Delete a specific user (super user or have 'delete_user' permission)
- /api/users/[user_id]/reset/password PUT: Reset to default password for a specific user (super user or have 'change_user' permission)
- query permission APIs (permissions are defined in models code)
- /api/permissions GET: Get all permissions (super user or have 'query_permission' permission)
- /api/permissions/[permission_id] GET: Get a specific permission (super user or have 'query_permission' permission)
- authentication APIs
- /api-auth/login POST: User login
- /api-auth/logout POST (or GET if enabled): User logout
- /api-auth/me PUT or PATCH: Modify current login user
- /api-auth/me GET: Get current login user
- /api-auth/password/change PUT: Change the current login user's password
- /api-auth/register POST: Register User (This API can be disabled by configuration)
- Your own APIs
- ...


3. Setup frontend if you need admin dashboard, which based Vue + Element-UI
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1). Go to {your_app_name}/vue-ui folder, and run below command to install dependency libs
- run below command:

.. code-block:: shell

{your_app_name}/vue-ui> npm install

2). Configure your backend baseURL by changing {your_app_name}/vue-ui/src/components/config.js
- see below code:

.. code-block:: javascript

var baseURL = 'http://localhost'; // <=== baseURL for production
if (process.env.NODE_ENV == 'development') {
baseURL = 'http://localhost'; // <=== baseURL for development
}
...

3). Change theme by alias in {your_app_name}/vue-ui/build/webpack.base.conf.js
- Change the value of alias 'THEME'
- Now support two themes
- resolve('src/themes/default') // <=== default theme
- resolve('src/themes/green') // <=== green theme

4). Create your own vue pages to {your_app_name}/vue-ui/src/components/page/
- Common pages are under {your_app_name}/vue-ui/src/components/common/

5). Change the menu in left slider bar by changing {your_app_name}/vue-ui/src/components/menus.js
- see below example code:

.. code-block:: javascript

import i18n from '../i18n/i18n'
import permission from './common/permission'
import Dashboard from '@/components/page/Dashboard'
import UserAdmin from '@/components/page/UserAdmin'
import RoleAdmin from '@/components/page/RoleAdmin' // RoleAdmin and UserAdmin are default pages, you can just use it.
import YourSubMenuItem from '@/components/page/YourSubMenuItem'
import YourSubSubMenuItem from '@/components/page/YourSubSubMenuItem'

var menu = [
{
name: 'Dashboard',
path: '/dashboard',
component: Dashboard,
icon: 'el-icon-lx-home',
meta: {
getTitle: function() {
return i18n.t("page.homeTitle")
},
},
},
{
name: 'UserAdmin',
path: '/userAdmin',
component: UserAdmin,
icon: 'el-icon-lx-people',
meta: {
getTitle: function() {
return i18n.t("page.userAdminTitle")
},
// must have all permissions listed below to access this menu item
requiredPermissions: ['query_group', 'query_permission', 'add_user', 'change_user', 'delete_user'],
},
},
{
name: 'RoleAdmin',
path: '/roleAdmin',
component: RoleAdmin,
icon: 'el-icon-lx-group',
meta: {
getTitle: function() {
return i18n.t("page.roleAdminTitle")
},
permissionCheck: function(user) {
return permission.isSuperUser(user)
}
},
},
{
name: 'YourFolderMenu',
icon: 'xxx',
meta: {
getTitle: function() {
return "Your Folder Menu"
},
notRequireAuth: true, // <=== this configuration item means this menu can access by anonymous user
},
subs: [
{
name: 'YourSubFolderMenu',
meta: {
getTitle: function() {
return "Your Sub Folder Menu"
},
requiredPermissions: [...],
},
subs: [
// only can support three levels menu
{
name: 'YourSubSubMenuItem',
path: '/yourSubSubMenuItem',
component: YourSubSubMenuItem,
meta: {
getTitle: function() {
return "Your Sub Sub Menu Item"
},
},
},
...

]
},
{
name: 'YourSubMenuItem',
path: '/yourSubMenuItem',
component: YourSubMenuItem,
meta: {
getTitle: function() {
return "Your Sub Menu Item"
},
requiredPermissions: ['maintain_dummy_model', ...], // <=== Use the defined permission in your model
},
},
...
]
},
]


- screen shot for above menu
.. image:: img/ui.JPG

6). Modify UserAdmin.vue page
- If you have additional fields in your User model, you can change the UserAdmin.vue to support them
- Add columns in <el-table> for additional fields
- Add form items in <el-dialog> of editing user for additional fields
- Change related javascript code in that page

7). Build you pages
- run below command:

.. code-block:: shell

{your_app_name}/vue-ui> npm run build

8). Deploy build results to static folder
- run below commands:

.. code-block:: shell

{your_app_name}> mkdir static
{your_app_name}> cp vue-ui/build/* static/

9). Access you pages
- Visit http://localhost/static/index.html

10). if you are focus on pages development, you can use use dev model instead of steps 7 - 9
- run below command, then visit http://localhost:8080:

.. code-block:: shell

{your_app_name}/vue-ui> npm run build


More configurations
-------------------


Language configuration
^^^^^^^^^^^^^^^^^^^^^^^^
- Change to be Chinese
- Change LANGUAGE_CODE = 'zh-hans' in {your app name}/settings/production.py (backend)
- Change defaultLangCode: "zh-hans" in {your_app_name}/vue-ui/src/components/config.js (frontend)

.. code-block:: javascript

...
const config = {
loginFieldName: "phone", // <=== should keep this value same as USERNAME_FIELD in your User model
backendBaseURL: baseURL,
requestTimeout: 10000,
defaultLangCode: "zh-hans", // <=== Change here for frontend
}
...


easyauth Configuration
^^^^^^^^^^^^^^^^^^^^^^^^

Change EASYAUTH_CONF in {your_app_name}/settings/product.py if you need:

.. code-block:: python

EASYAUTH_CONF = {
'USER_DEFAULT_PWD_MAINTAIN_BY_ADMIN': "12345678",
'ACCOUNT_LOGOUT_ON_GET': False,
'DISABLE_REGISTER': False,
'LANG_PARAM': 'lang',
}

+----------------------------------------+------------+--------------------------------------------------------------+
| Configuration Item | Type | Description |
+========================================+============+==============================================================+
| USER_DEFAULT_PWD_MAINTAIN_BY_ADMIN | string | Define the default password for maintaining by administrator.|
| | | |
| | | Default value is 123456 for absent |
+----------------------------------------+------------+--------------------------------------------------------------+
| ACCOUNT_LOGOUT_ON_GET | bool | Switch for enabling GET method for logout API. |
| | | |
| | | Default value is False for absent |
+----------------------------------------+------------+--------------------------------------------------------------+
| DISABLE_REGISTER | bool | Switch for disabling register API. |
| | | |
| | | Default value is False for absent |
+----------------------------------------+------------+--------------------------------------------------------------+
| LANG_PARAM | string | Set the language parameter name in http request. |
| | | (Usually don't need to change it) |
| | | |
| | | Default value is lang, it will be used like |
| | | http://localhost/api/users?lang=zh-hans |
| | | |
| | | Tips: Keep the value of lang_param in |
| | | {your_app_name}/vue-ui/src/components/common/easyauth.js |
| | | same with this configuration value. |
+----------------------------------------+------------+--------------------------------------------------------------+

More examples please see the test app in this repo






Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

easyauth-0.1.3.tar.gz (287.8 kB view hashes)

Uploaded Source

Built Distribution

easyauth-0.1.3-py2-none-any.whl (314.6 kB view hashes)

Uploaded Python 2

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page