Skip to content

Commit

Permalink
Merge pull request #136 from dmm-com/v3.0-dev
Browse files Browse the repository at this point in the history
Merge all changing of updating Django
  • Loading branch information
hinashi authored May 28, 2021
2 parents ce3c199 + 3986eed commit c7f996b
Show file tree
Hide file tree
Showing 39 changed files with 573 additions and 266 deletions.
1 change: 1 addition & 0 deletions .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
max-line-length = 100
exclude =
./venv,
./.venv,
./.tox,
./*/migrations,
.manage.py
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
### Changed
* Changed implementation of Entity to create, edit and delete it at Celery.
* Changed to show unauthorized entity on the dashboard
* Update Django version from v1.11 to v2.2 (LTS)

## v2.6.0

Expand Down
360 changes: 339 additions & 21 deletions LICENSE

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion acl/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def _get_objid(permission):
class ACLBase(models.Model):
name = models.CharField(max_length=200)
is_public = models.BooleanField(default=True)
created_user = models.ForeignKey(User)
created_user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
is_active = models.BooleanField(default=True)
status = models.IntegerField(default=0)
default_permission = models.IntegerField(default=ACLType.Nothing.id)
Expand Down
9 changes: 2 additions & 7 deletions acl/tests/test_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

from airone.lib.acl import ACLType
from airone.lib.test import AironeViewTest
from xml.etree import ElementTree


class ViewTest(AironeViewTest):
Expand Down Expand Up @@ -46,9 +45,7 @@ def test_index(self):

resp = self.client.get(reverse('acl:index', args=[self._aclobj.id]))
self.assertEqual(resp.status_code, 200)

root = ElementTree.fromstring(resp.content.decode('utf-8'))
self.assertIsNotNone(root.find('.//form'))
self.assertEqual([x['name'] for x in resp.context['members']], ['admin'])

def test_index_with_objects(self):
self.admin_login()
Expand All @@ -57,9 +54,7 @@ def test_index_with_objects(self):

resp = self.client.get(reverse('acl:index', args=[self._aclobj.id]))
self.assertEqual(resp.status_code, 200)

root = ElementTree.fromstring(resp.content.decode('utf-8'))
self.assertIsNotNone(root.find('.//table/tbody/tr/td'))
self.assertEqual([x['name'] for x in resp.context['members']], ['admin', 'hoge'])

def test_get_acl_set(self):
self.admin_login()
Expand Down
3 changes: 2 additions & 1 deletion airone/auth/ldap.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@

class LDAPBackend(object):
# This method is called by Django to authenticate user by specified username and password.
def authenticate(self, username=None, password=None):
def authenticate(self, request, username=None, password=None):

# check authentication with local database at first.
user = User.objects.filter(username=username,
authenticate_type=User.AUTH_TYPE_LOCAL,
Expand Down
14 changes: 14 additions & 0 deletions airone/lib/db.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import random
from django.conf import settings


def get_slave_db():
'''Change the DB query request to Slave.
The slave DB has a replication delay compared to the master DB.
There is a problem if change all read query requests to slaves.
Use this function only for query requests that can afford replication delays.
Usage:
Entry.objects.using(get_slave_db()).filter(...)
'''
return random.choice(settings.AIRONE['DB_SLAVES'])
10 changes: 5 additions & 5 deletions airone/lib/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ def wrapper(*args, **kwargs):
if request.method != 'GET':
return HttpResponse('Invalid HTTP method is specified', status=400)

if not request.user.is_authenticated():
return HttpResponseSeeOther('/dashboard/login?next=%s?%s' %
if not request.user.is_authenticated:
return HttpResponseSeeOther('/auth/login?next=%s?%s' %
(request.path, quote(request.GET.urlencode())))

return func(*args, **kwargs)
Expand Down Expand Up @@ -66,8 +66,8 @@ def check_superuser(func):
def wrapper(*args, **kwargs):
request = args[0]

if not request.user.is_authenticated():
return HttpResponseSeeOther('/dashboard/login')
if not request.user.is_authenticated:
return HttpResponseSeeOther('/auth/login')

if not request.user.is_superuser:
return HttpResponse('This page needs administrative permission to access', status=400)
Expand All @@ -84,7 +84,7 @@ def http_post_handler(*args, **kwargs):
if request.method != 'POST':
return HttpResponse('Invalid HTTP method is specified', status=400)

if not request.user.is_authenticated():
if not request.user.is_authenticated:
return HttpResponse('You have to login to execute this operation', status=401)

try:
Expand Down
2 changes: 1 addition & 1 deletion airone/lib/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,4 @@ def import_data_from_request(self, data, request_user):
dataset = tablib.Dataset([x in data and data[x] or '' for x in self._IMPORT_INFO['header']],
headers=self._IMPORT_INFO['header'])

return resource.import_data(dataset)
return resource.import_data(dataset, raise_errors=True)
3 changes: 0 additions & 3 deletions airone/settings.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import os
import logging
import subprocess
import pymysql
import errno
import importlib

from airone.lib.log import Logger

pymysql.install_as_MySQLdb()

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

Expand Down
21 changes: 21 additions & 0 deletions airone/tests/test_db.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import unittest

from airone.lib.db import get_slave_db
from django.conf import settings


class AirOneDBTest(unittest.TestCase):

def setUp(self):
# this saves original configurations to be able to retrieve them
self.orig_conf_db_slaves = settings.AIRONE['DB_SLAVES']

# this enables do profiling
settings.AIRONE['DB_SLAVES'] = ['slave1', 'slave2']

def tearDown(self):
# this retrieves original configurations
settings.AIRONE['ENABLE_PROFILE'] = self.orig_conf_db_slaves

def test_get_slave_db(self):
self.assertIn(get_slave_db(), settings.AIRONE['DB_SLAVES'])
8 changes: 4 additions & 4 deletions airone/tests/test_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ def mock_handler(request):

test_suites = [
{'get_url': '/test',
'resp_url': ['/dashboard/login?next=/test?']},
'resp_url': ['/auth/login?next=/test?']},
{'get_url': '/日本語',
'resp_url': ['/dashboard/login?next=/%E6%97%A5%E6%9C%AC%E8%AA%9E?']},
'resp_url': ['/auth/login?next=/%E6%97%A5%E6%9C%AC%E8%AA%9E?']},
{'get_url': '/test?query1=1&query2=test',
'resp_url': ['/dashboard/login?next=/test?query1%3D1%26query2%3Dtest',
'/dashboard/login?next=/test?query2%3Dtest%26query1%3D1']},
'resp_url': ['/auth/login?next=/test?query1%3D1%26query2%3Dtest',
'/auth/login?next=/test?query2%3Dtest%26query1%3D1']},
]

for i in test_suites:
Expand Down
19 changes: 10 additions & 9 deletions airone/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,21 @@

urlpatterns = [
url(r'^$', RedirectView.as_view(url='dashboard/')),
url(r'^acl/', include('acl.urls', namespace='acl')),
url(r'^user/', include('user.urls', namespace='user')),
url(r'^group/', include('group.urls', namespace='group')),
url(r'^entity/', include('entity.urls', namespace='entity')),
url(r'^dashboard/', include('dashboard.urls', namespace='dashboard')),
url(r'^entry/', include('entry.urls', namespace='entry')),
url(r'^acl/', include(('acl.urls', 'acl'))),
url(r'^user/', include(('user.urls', 'user'))),
url(r'^group/', include(('group.urls', 'group'))),
url(r'^entity/', include(('entity.urls', 'entity'))),
url(r'^dashboard/', include(('dashboard.urls', 'dashboard'))),
url(r'^entry/', include(('entry.urls', 'entry'))),
url(r'^admin/', admin.site.urls),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^api-auth/', include(('rest_framework.urls', 'rest_framework'))),
url(r'^api/v1/', include(api_v1_urlpatterns)),
url(r'^job/', include('job.urls', namespace='job')),
url(r'^job/', include(('job.urls', 'job'))),
url(r'^auth/', include(('django.contrib.auth.urls', 'auth'))),
]

for extension in settings.AIRONE['EXTENSIONS']:
urlpatterns.append(url(r'^extension/%s' % extension,
include('%s.urls' % extension, namespace=extension)))
include(('%s.urls' % extension, extension))))

urlpatterns += staticfiles_urlpatterns()
4 changes: 3 additions & 1 deletion api_v1/entry/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from api_v1.auth import AironeTokenAuth
from airone.lib.profile import airone_profile
from airone.lib.db import get_slave_db
from django.conf import settings
from django.db.models import Q

Expand Down Expand Up @@ -92,7 +93,8 @@ def get(self, request):
query &= Q(schema__name=param_entity)

ret_data = []
for entry in Entry.objects.filter(query):
slave_db = get_slave_db()
for entry in Entry.objects.using(slave_db).filter(query):
ret_data.append({
'id': entry.id,
'entity': {'id': entry.schema.id, 'name': entry.schema.name},
Expand Down
Loading

0 comments on commit c7f996b

Please sign in to comment.