Merge branch 'versions/next' into feature/db_migration
Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
This commit is contained in:
@@ -2,6 +2,12 @@
|
|||||||
================
|
================
|
||||||
- Improve database vendor migration support
|
- Improve database vendor migration support
|
||||||
- Add convertdb management command.
|
- Add convertdb management command.
|
||||||
|
- Fix crop transformation argument parsing. Thanks to Jordan Wages
|
||||||
|
(@wagesj45). Closes GitLab issue #490
|
||||||
|
- Add error checking to the crop transformation arguments.
|
||||||
|
- Fix post login redirection to honor the ?next= URL query string
|
||||||
|
argument. Thanks go to K.C. Wong (@dvusboy1). Closes GitLab
|
||||||
|
issue #489.
|
||||||
|
|
||||||
3.0.1 (2018-07-08)
|
3.0.1 (2018-07-08)
|
||||||
=================
|
=================
|
||||||
|
|||||||
1733
contrib/scripts/install/dialog.sh
Normal file
1733
contrib/scripts/install/dialog.sh
Normal file
File diff suppressed because it is too large
Load Diff
@@ -6,11 +6,11 @@ set -e
|
|||||||
# $ sh get-mayan-edms.sh
|
# $ sh get-mayan-edms.sh
|
||||||
#
|
#
|
||||||
# NOTE: Make sure to verify the contents of the script
|
# NOTE: Make sure to verify the contents of the script
|
||||||
# you downloaded matches the contents of install.sh
|
# you downloaded matches the contents of docker.sh
|
||||||
# located at https://gitlab.com/mayan-edms/mayan-edms/blob/master/contrib/scripts/install/docker.sh
|
# located at https://gitlab.com/mayan-edms/mayan-edms/blob/master/contrib/scripts/install/docker.sh
|
||||||
# before executing.
|
# before executing.
|
||||||
|
|
||||||
: ${VERBOSE:=false}
|
: ${VERBOSE:=true}
|
||||||
: ${INSTALL_DOCKER:=false}
|
: ${INSTALL_DOCKER:=false}
|
||||||
: ${DELETE_VOLUMES:=false}
|
: ${DELETE_VOLUMES:=false}
|
||||||
: ${DATABASE_USER:=mayan}
|
: ${DATABASE_USER:=mayan}
|
||||||
@@ -19,6 +19,7 @@ set -e
|
|||||||
: ${DOCKER_POSTGRES_IMAGE:=postgres:9.5}
|
: ${DOCKER_POSTGRES_IMAGE:=postgres:9.5}
|
||||||
: ${DOCKER_POSTGRES_CONTAINER:=mayan-edms-postgres}
|
: ${DOCKER_POSTGRES_CONTAINER:=mayan-edms-postgres}
|
||||||
: ${DOCKER_POSTGRES_VOLUME:=/docker-volumes/mayan-edms/postgres}
|
: ${DOCKER_POSTGRES_VOLUME:=/docker-volumes/mayan-edms/postgres}
|
||||||
|
: ${DOCKER_POSTGRES_PORT:=5432}
|
||||||
: ${DOCKER_MAYAN_IMAGE:=mayanedms/mayanedms:latest}
|
: ${DOCKER_MAYAN_IMAGE:=mayanedms/mayanedms:latest}
|
||||||
: ${DOCKER_MAYAN_CONTAINER:=mayan-edms}
|
: ${DOCKER_MAYAN_CONTAINER:=mayan-edms}
|
||||||
: ${DOCKER_MAYAN_VOLUME:=/docker-volumes/mayan-edms/media}
|
: ${DOCKER_MAYAN_VOLUME:=/docker-volumes/mayan-edms/media}
|
||||||
@@ -33,6 +34,9 @@ cat << EOF
|
|||||||
╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝
|
╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝
|
||||||
Docker deploy script
|
Docker deploy script
|
||||||
|
|
||||||
|
NOTE: Make sure to verify the contents of this script
|
||||||
|
matches the contents of docker.sh located at https://gitlab.com/mayan-edms/mayan-edms/blob/master/contrib/scripts/install/docker.sh before executing.
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
if [ "$VERBOSE" = true ]; then
|
if [ "$VERBOSE" = true ]; then
|
||||||
@@ -46,17 +50,18 @@ echo "DATABASE_PASSWORD: $DATABASE_PASSWORD"
|
|||||||
echo "DOCKER_POSTGRES_IMAGE: $DOCKER_POSTGRES_IMAGE"
|
echo "DOCKER_POSTGRES_IMAGE: $DOCKER_POSTGRES_IMAGE"
|
||||||
echo "DOCKER_POSTGRES_CONTAINER: $DOCKER_POSTGRES_CONTAINER"
|
echo "DOCKER_POSTGRES_CONTAINER: $DOCKER_POSTGRES_CONTAINER"
|
||||||
echo "DOCKER_POSTGRES_VOLUME: $DOCKER_POSTGRES_VOLUME"
|
echo "DOCKER_POSTGRES_VOLUME: $DOCKER_POSTGRES_VOLUME"
|
||||||
|
echo "DOCKER_POSTGRES_PORT: $DOCKER_POSTGRES_PORT"
|
||||||
echo "DOCKER_MAYAN_IMAGE: $DOCKER_MAYAN_IMAGE"
|
echo "DOCKER_MAYAN_IMAGE: $DOCKER_MAYAN_IMAGE"
|
||||||
echo "DOCKER_MAYAN_CONTAINER: $DOCKER_MAYAN_CONTAINER"
|
echo "DOCKER_MAYAN_CONTAINER: $DOCKER_MAYAN_CONTAINER"
|
||||||
echo "DOCKER_MAYAN_VOLUME: $DOCKER_MAYAN_VOLUME"
|
echo "DOCKER_MAYAN_VOLUME: $DOCKER_MAYAN_VOLUME"
|
||||||
echo "\nStarting in 5 seconds."
|
echo "\nStarting in 10 seconds."
|
||||||
sleep 5
|
sleep 10
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$INSTALL_DOCKER" = true ]; then
|
if [ "$INSTALL_DOCKER" = true ]; then
|
||||||
echo -n "* Installing Docker..."
|
echo -n "* Installing Docker..."
|
||||||
curl -fsSL get.docker.com -o get-docker.sh >/dev/null
|
curl -fsSL get.docker.com -o get-docker.sh >/dev/null
|
||||||
sh get-docker.sh >/dev/null
|
sh get-docker.sh >/dev/null 2>&1
|
||||||
rm get-docker.sh
|
rm get-docker.sh
|
||||||
echo "Done"
|
echo "Done"
|
||||||
fi
|
fi
|
||||||
@@ -88,7 +93,7 @@ echo -n "* Deploying the PostgreSQL container..."
|
|||||||
docker run -d \
|
docker run -d \
|
||||||
--name $DOCKER_POSTGRES_CONTAINER \
|
--name $DOCKER_POSTGRES_CONTAINER \
|
||||||
--restart=always \
|
--restart=always \
|
||||||
-p 5432:5432 \
|
-p $DOCKER_POSTGRES_PORT:5432 \
|
||||||
-e POSTGRES_USER=$DATABASE_USER \
|
-e POSTGRES_USER=$DATABASE_USER \
|
||||||
-e POSTGRES_DB=$DATABASE_NAME \
|
-e POSTGRES_DB=$DATABASE_NAME \
|
||||||
-e POSTGRES_PASSWORD=$DATABASE_PASSWORD \
|
-e POSTGRES_PASSWORD=$DATABASE_PASSWORD \
|
||||||
@@ -110,6 +115,7 @@ docker run -d \
|
|||||||
-e MAYAN_DATABASE_NAME=$DATABASE_NAME \
|
-e MAYAN_DATABASE_NAME=$DATABASE_NAME \
|
||||||
-e MAYAN_DATABASE_PASSWORD=$DATABASE_PASSWORD \
|
-e MAYAN_DATABASE_PASSWORD=$DATABASE_PASSWORD \
|
||||||
-e MAYAN_DATABASE_USER=$DATABASE_USER \
|
-e MAYAN_DATABASE_USER=$DATABASE_USER \
|
||||||
|
-e MAYAN_DATABASE_PORT=$DOCKER_POSTGRES_PORT \
|
||||||
-e MAYAN_DATABASE_CONN_MAX_AGE=60 \
|
-e MAYAN_DATABASE_CONN_MAX_AGE=60 \
|
||||||
-v $DOCKER_MAYAN_VOLUME:/var/lib/mayan \
|
-v $DOCKER_MAYAN_VOLUME:/var/lib/mayan \
|
||||||
$DOCKER_MAYAN_IMAGE >/dev/null
|
$DOCKER_MAYAN_IMAGE >/dev/null
|
||||||
|
|||||||
@@ -72,6 +72,9 @@ ln -s /usr/lib/arm-linux-gnueabihf/libz.so /usr/lib/ && \
|
|||||||
ln -s /usr/lib/arm-linux-gnueabihf/libjpeg.so /usr/lib/ \
|
ln -s /usr/lib/arm-linux-gnueabihf/libjpeg.so /usr/lib/ \
|
||||||
; fi
|
; fi
|
||||||
|
|
||||||
|
# Discard data when Redis runs out of memory
|
||||||
|
echo "maxmemory-policy allkeys-lru" >> /etc/redis/redis.conf
|
||||||
|
|
||||||
#####################
|
#####################
|
||||||
# Build image start #
|
# Build image start #
|
||||||
#####################
|
#####################
|
||||||
|
|||||||
@@ -134,6 +134,11 @@ Create the supervisor file at ``/etc/supervisor/conf.d/mayan.conf``::
|
|||||||
stopwaitsecs = 1
|
stopwaitsecs = 1
|
||||||
user = mayan
|
user = mayan
|
||||||
|
|
||||||
|
Configure Redis to discard data when it runs out of memory::
|
||||||
|
|
||||||
|
echo "maxmemory-policy allkeys-lru" >> /etc/redis/redis.conf
|
||||||
|
systemctl restart redis
|
||||||
|
|
||||||
Enable and restart the services [1_]::
|
Enable and restart the services [1_]::
|
||||||
|
|
||||||
systemctl enable supervisor
|
systemctl enable supervisor
|
||||||
|
|||||||
@@ -205,3 +205,18 @@ class UserLoginTestCase(BaseTestCase):
|
|||||||
|
|
||||||
response = self.client.get(reverse('documents:document_list'))
|
response = self.client.get(reverse('documents:document_list'))
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
|
def test_username_login_redirect(self):
|
||||||
|
TEST_REDIRECT_URL = '/about/'
|
||||||
|
|
||||||
|
response = self.client.post(
|
||||||
|
'{}?next={}'.format(
|
||||||
|
reverse(settings.LOGIN_URL), TEST_REDIRECT_URL
|
||||||
|
), {
|
||||||
|
'username': TEST_ADMIN_USERNAME,
|
||||||
|
'password': TEST_ADMIN_PASSWORD,
|
||||||
|
'remember_me': False
|
||||||
|
}, follow=True
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(response.redirect_chain, [(TEST_REDIRECT_URL, 302)])
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from django.contrib.auth.views import (
|
|||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.shortcuts import redirect, resolve_url
|
from django.shortcuts import redirect, resolve_url
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
from django.utils.http import is_safe_url
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from stronghold.decorators import public
|
from stronghold.decorators import public
|
||||||
@@ -26,6 +27,7 @@ def login_view(request):
|
|||||||
Control how the use is to be authenticated, options are 'email' and
|
Control how the use is to be authenticated, options are 'email' and
|
||||||
'username'
|
'username'
|
||||||
"""
|
"""
|
||||||
|
success_url_allowed_hosts = set()
|
||||||
kwargs = {'template_name': 'authentication/login.html'}
|
kwargs = {'template_name': 'authentication/login.html'}
|
||||||
|
|
||||||
if setting_login_method.value == 'email':
|
if setting_login_method.value == 'email':
|
||||||
@@ -33,10 +35,25 @@ def login_view(request):
|
|||||||
else:
|
else:
|
||||||
kwargs['authentication_form'] = UsernameAuthenticationForm
|
kwargs['authentication_form'] = UsernameAuthenticationForm
|
||||||
|
|
||||||
|
allowed_hosts = {request.get_host()}
|
||||||
|
allowed_hosts.update(success_url_allowed_hosts)
|
||||||
|
|
||||||
|
redirect_to = request.POST.get(
|
||||||
|
REDIRECT_FIELD_NAME, request.GET.get(REDIRECT_FIELD_NAME, '')
|
||||||
|
)
|
||||||
|
|
||||||
|
url_is_safe = is_safe_url(
|
||||||
|
url=redirect_to,
|
||||||
|
allowed_hosts=allowed_hosts,
|
||||||
|
require_https=request.is_secure(),
|
||||||
|
)
|
||||||
|
|
||||||
|
url = redirect_to if url_is_safe else ''
|
||||||
|
|
||||||
if not request.user.is_authenticated:
|
if not request.user.is_authenticated:
|
||||||
extra_context = {
|
extra_context = {
|
||||||
'appearance_type': 'plain',
|
'appearance_type': 'plain',
|
||||||
REDIRECT_FIELD_NAME: resolve_url(settings.LOGIN_REDIRECT_URL)
|
REDIRECT_FIELD_NAME: url or resolve_url(settings.LOGIN_REDIRECT_URL)
|
||||||
}
|
}
|
||||||
|
|
||||||
result = login(request, extra_context=extra_context, **kwargs)
|
result = login(request, extra_context=extra_context, **kwargs)
|
||||||
|
|||||||
@@ -2,9 +2,12 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from documents.tests import GenericDocumentTestCase
|
||||||
|
|
||||||
|
from ..models import Transformation
|
||||||
from ..transformations import (
|
from ..transformations import (
|
||||||
BaseTransformation, TransformationResize, TransformationRotate,
|
BaseTransformation, TransformationCrop, TransformationResize,
|
||||||
TransformationZoom
|
TransformationRotate, TransformationZoom
|
||||||
)
|
)
|
||||||
|
|
||||||
TRANSFORMATION_RESIZE_WIDTH = 123
|
TRANSFORMATION_RESIZE_WIDTH = 123
|
||||||
@@ -20,7 +23,7 @@ TRANSFORMATION_ZOOM_PERCENT = 49
|
|||||||
TRANSFORMATION_ZOOM_CACHE_HASH = '1b333603674469e0'
|
TRANSFORMATION_ZOOM_CACHE_HASH = '1b333603674469e0'
|
||||||
|
|
||||||
|
|
||||||
class TransformationTestCase(TestCase):
|
class TransformationBaseTestCase(TestCase):
|
||||||
def test_cache_uniqness(self):
|
def test_cache_uniqness(self):
|
||||||
transformation_1 = TransformationResize(width=640, height=640)
|
transformation_1 = TransformationResize(width=640, height=640)
|
||||||
|
|
||||||
@@ -101,3 +104,50 @@ class TransformationTestCase(TestCase):
|
|||||||
(transformation_rotate, transformation_resize, transformation_zoom)
|
(transformation_rotate, transformation_resize, transformation_zoom)
|
||||||
), TRANSFORMATION_COMBINED_CACHE_HASH
|
), TRANSFORMATION_COMBINED_CACHE_HASH
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TransformationTestCase(GenericDocumentTestCase):
|
||||||
|
def test_crop_transformation_optional_arguments(self):
|
||||||
|
document_page = self.document.pages.first()
|
||||||
|
|
||||||
|
Transformation.objects.add_for_model(
|
||||||
|
obj=document_page, transformation=TransformationCrop,
|
||||||
|
arguments={'top': '10'}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(document_page.generate_image().startswith('page'))
|
||||||
|
|
||||||
|
def test_crop_transformation_invalid_arguments(self):
|
||||||
|
document_page = self.document.pages.first()
|
||||||
|
|
||||||
|
Transformation.objects.add_for_model(
|
||||||
|
obj=document_page, transformation=TransformationCrop,
|
||||||
|
arguments={'top': 'x', 'left': '-'}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(document_page.generate_image().startswith('page'))
|
||||||
|
|
||||||
|
def test_crop_transformation_non_valid_range_arguments(self):
|
||||||
|
document_page = self.document.pages.first()
|
||||||
|
|
||||||
|
Transformation.objects.add_for_model(
|
||||||
|
obj=document_page, transformation=TransformationCrop,
|
||||||
|
arguments={'top': '-1000', 'bottom': '100000000'}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(document_page.generate_image().startswith('page'))
|
||||||
|
|
||||||
|
def test_crop_transformation_overlapping_ranges_arguments(self):
|
||||||
|
document_page = self.document.pages.first()
|
||||||
|
|
||||||
|
Transformation.objects.add_for_model(
|
||||||
|
obj=document_page, transformation=TransformationCrop,
|
||||||
|
arguments={'top': '1000', 'bottom': '1000'}
|
||||||
|
)
|
||||||
|
|
||||||
|
Transformation.objects.add_for_model(
|
||||||
|
obj=document_page, transformation=TransformationCrop,
|
||||||
|
arguments={'left': '1000', 'right': '10000'}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(document_page.generate_image().startswith('page'))
|
||||||
|
|||||||
@@ -88,10 +88,48 @@ class TransformationCrop(BaseTransformation):
|
|||||||
def execute_on(self, *args, **kwargs):
|
def execute_on(self, *args, **kwargs):
|
||||||
super(TransformationCrop, self).execute_on(*args, **kwargs)
|
super(TransformationCrop, self).execute_on(*args, **kwargs)
|
||||||
|
|
||||||
return self.image.crop(
|
left = float(self.left or '0')
|
||||||
(self.left, self.top, self.right, self.bottom)
|
top = float(self.top or '0')
|
||||||
|
right = self.image.size[0] - float(self.right or '0')
|
||||||
|
bottom = self.image.size[1] - float(self.bottom or '0')
|
||||||
|
|
||||||
|
if left < 0:
|
||||||
|
left = 0
|
||||||
|
|
||||||
|
if left > self.image.size[0] - 1:
|
||||||
|
left = self.image.size[0] - 1
|
||||||
|
|
||||||
|
if top < 0:
|
||||||
|
top = 0
|
||||||
|
|
||||||
|
if top > self.image.size[1] - 1:
|
||||||
|
top = self.image.size[1] - 1
|
||||||
|
|
||||||
|
if right < 0:
|
||||||
|
right = 0
|
||||||
|
|
||||||
|
if right > self.image.size[0] - 1:
|
||||||
|
right = self.image.size[0] - 1
|
||||||
|
|
||||||
|
if bottom < 0:
|
||||||
|
bottom = 0
|
||||||
|
|
||||||
|
if bottom > self.image.size[1] - 1:
|
||||||
|
bottom = self.image.size[1] - 1
|
||||||
|
|
||||||
|
if left > right:
|
||||||
|
left = right - 1
|
||||||
|
|
||||||
|
if top > bottom:
|
||||||
|
top = bottom - 1
|
||||||
|
|
||||||
|
logger.debug(
|
||||||
|
'left: %f, top: %f, right: %f, bottom: %f', left, top, right,
|
||||||
|
bottom
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return self.image.crop((left, top, right, bottom))
|
||||||
|
|
||||||
|
|
||||||
class TransformationFlip(BaseTransformation):
|
class TransformationFlip(BaseTransformation):
|
||||||
arguments = ()
|
arguments = ()
|
||||||
|
|||||||
Reference in New Issue
Block a user