Merge branch 'master' into stable

remotes/origin/issue/4217/improving-mail-design 3.1.0
Jesús Espino 2017-03-10 17:02:48 +01:00
commit 4bdb00a642
638 changed files with 37883 additions and 8565 deletions

1
.gitignore vendored
View File

@ -3,6 +3,7 @@
*.log *.log
taiga/search taiga/search
settings/local.py settings/local.py
settings/celery_local.py
database.sqlite database.sqlite
logs logs
media media

View File

@ -2,15 +2,17 @@ language: python
python: python:
- "3.4" - "3.4"
- "3.5" - "3.5"
addons:
postgresql: "9.4"
services: services:
- rabbitmq # will start rabbitmq-server - rabbitmq
- postgresql
cache: cache:
- apt - apt
- pip - pip
before_install: before_install:
- sudo apt-get -qq update - sudo apt-get -qq update
- sudo /etc/init.d/postgresql stop - sudo /etc/init.d/postgresql stop
- sudo apt-get install -y postgresql-9.4
- sudo apt-get install -y postgresql-plpython-9.4 - sudo apt-get install -y postgresql-plpython-9.4
- sudo /etc/init.d/postgresql start 9.4 - sudo /etc/init.d/postgresql start 9.4
- psql -c 'create database taiga;' -U postgres - psql -c 'create database taiga;' -U postgres

View File

@ -1,6 +1,35 @@
# Changelog # # Changelog #
## 3.1.0 Perovskia Atriplicifolia (2017-03-10)
### Features
- Contact with the project: if the projects have this module enabled Taiga users can contact them.
- Ability to create rich text custom fields in Epics, User Stories, Tasks and Isues.
- Full text search now use simple as tokenizer so search with non-english text are allowed.
- Duplicate project: allows creating a new project based on the structure of another (status, tags, colors, default values...)
- Add thumbnails and preview for PSD files.
- Add thumbnails and preview for SVG files (Cario lib is needed).
- i18n:
- Add japanese (ja) translation.
- Add korean (ko) translation.
- Add chinese simplified (zh-Hans) translation.
- Third party services project importers:
- Trello
- Jira 7
- Github
- Asana
### Misc
- API:
- Memberships API endpoints now allows using usernames and emails instead of using only emails.
- Contacts API allow full text search (by the username, full name or email).
- Filter milestones, user stories and tasks by estimated_start and estimated_finish dates.
- Add project_extra_info to epics, tasks, milestones, issues and wiki pages endpoints.
- Gogs integration: Adding new Gogs signature method.
- Lots of small and not so small bugfixes.
## 3.0.0 Stellaria Borealis (2016-10-02) ## 3.0.0 Stellaria Borealis (2016-10-02)
### Features ### Features

19
ISSUE_TEMPLATE.md Normal file
View File

@ -0,0 +1,19 @@
**Before adding an issue**
Please ensure that your issue is not already reported in our [issues list](https://tree.taiga.io/project/taiga/issues?order_by=-created_date).
If this issue was already reported, remember that you can upvote it to raise its importance.
**Do you want to request a *feature* or report a *bug*?**
**What is the current behavior?**
**If the current behavior is a bug, please provide the steps to reproduce.**
**What is the expected behavior?**
**Is it happening in taiga.io or in your own instance?**
**What browser/version are you using?**
**Are there any console errors *(Ctrl + F12)* in red?**
Thanks for reporting!

View File

@ -1,10 +1,9 @@
# Taiga Backend # # Taiga Backend #
![Kaleidos Project](http://kaleidos.net/static/img/badge.png "Kaleidos Project") ![Kaleidos Project](http://kaleidos.net/static/img/badge.svg "Kaleidos Project")
[![Managed with Taiga.io](https://taiga.io/media/support/attachments/article-22/banner-gh.png)](https://taiga.io "Managed with Taiga.io") [![Managed with Taiga.io](https://img.shields.io/badge/managed%20with-TAIGA.io-709f14.svg)](https://tree.taiga.io/project/taiga/ "Managed with Taiga.io")
[![Build Status](https://travis-ci.org/taigaio/taiga-back.svg?branch=master)](https://travis-ci.org/taigaio/taiga-back "Build Status") [![Build Status](https://img.shields.io/travis/taigaio/taiga-back.svg)](https://travis-ci.org/taigaio/taiga-back "Build Status")
[![Coverage Status](https://coveralls.io/repos/taigaio/taiga-back/badge.svg?branch=master)](https://coveralls.io/r/taigaio/taiga-back?branch=master "Coverage Status") [![Coverage Status](https://img.shields.io/coveralls/taigaio/taiga-back/master.svg)](https://coveralls.io/r/taigaio/taiga-back?branch=master "Coverage Status")
[![Dependency Status](https://www.versioneye.com/user/projects/561bd091a193340f32001464/badge.svg?style=flat)](https://www.versioneye.com/user/projects/561bd091a193340f32001464)
## Contribute to Taiga ## ## Contribute to Taiga ##
@ -64,7 +63,7 @@ Currently, we have authored three main documentation hubs:
#### Translation #### #### Translation ####
We are ready now to accept your help translating Taiga. It's easy (and fun!) just access our team of translators with the link below, set up an account in Transifex and start contributing. Join us to make sure your language is covered! **[Help Taiga to translate content](https://www.transifex.com/signup/ "Help Taiga to trasnlatecontent")** We are ready now to accept your help translating Taiga. It's easy (and fun!) just access our team of translators with the link below, set up an account in Transifex and start contributing. Join us to make sure your language is covered! **[Help Taiga to translate content](https://www.transifex.com/taiga-agile-llc/taiga-back/ "Help Taiga to trasnlatecontent")**
#### Code patches #### #### Code patches ####
@ -80,7 +79,7 @@ Taiga is made for developers and designers. We care enormously about UI because
There are two possible ways to contribute to our UI: There are two possible ways to contribute to our UI:
- **Bugs**: If you find a bug regarding front-end, please report it as previously indicated in the Bug reports section or send a pull-request as indicated in the Code Patches section. - **Bugs**: If you find a bug regarding front-end, please report it as previously indicated in the Bug reports section or send a pull-request as indicated in the Code Patches section.
- **Enhancements**: If its a design or UX bug or enhancement we will love to receive your feedback. Please send us your enhancement, with the reason and, if possible, an example. Our design and UX team will review your enhancement and fix it as soon as possible. We recommend you to use our [mailing list](http://groups.google.co.uk/d/forum/taigaio){target="_blank"} so we can have a lot of different opinions and debate. - **Enhancements**: If its a design or UX bug or enhancement we will love to receive your feedback. Please send us your enhancement, with the reason and, if possible, an example. Our design and UX team will review your enhancement and fix it as soon as possible. We recommend you to use our [mailing list](http://groups.google.co.uk/d/forum/taigaio) so we can have a lot of different opinions and debate.
- **Language Localization**: We are eager to offer localized versions of Taiga. Some members of the community have already volunteered to work to provide a variety of languages. We are working to implement some changes to allow for this and expect to accept these requests in the near future. - **Language Localization**: We are eager to offer localized versions of Taiga. Some members of the community have already volunteered to work to provide a variety of languages. We are working to implement some changes to allow for this and expect to accept these requests in the near future.

View File

@ -1,10 +1,10 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,13 +1,13 @@
-r requirements.txt -r requirements.txt
factory_boy==2.8.1 factory_boy==2.8.1
py==1.4.31 py==1.4.32
pytest==2.8.7 pytest==3.0.6
pytest-django==2.9.1 pytest-django==3.1.2
pytest-pythonpath==0.7 pytest-pythonpath==0.7.1
coverage==4.0.3 coverage==4.3.4
coveralls==1.1 coveralls==1.1
django-slowdown==0.0.1 django-slowdown==0.0.1
transifex-client==0.11.1.beta transifex-client==0.12.4

View File

@ -1,38 +1,42 @@
Django==1.9.2 Django==1.10.6
#djangorestframework==2.3.13 # It's not necessary since Taiga 1.7 #djangorestframework==2.3.13 # It's not necessary since Taiga 1.7
django-picklefield==0.3.2 django-picklefield==0.3.2
django-sampledatahelper==0.4.0 django-sampledatahelper==0.4.1
gunicorn==19.4.5 gunicorn==19.6.0
psycopg2==2.6.1 psycopg2==2.7
Pillow==3.1.1 Pillow==3.4.2
pytz==2015.7 pytz==2016.10
six==1.10.0 six==1.10.0
amqp==1.4.9 amqp==2.1.4
djmail==0.12.0.post1 djmail==1.0.0
django-pgjson==0.3.1 django-jinja==2.2.2
djorm-pgarray==1.2 # Use until Taiga 2.1. Keep compatibility with old migrations jinja2==2.9.5
django-jinja==2.1.2 pygments==2.2.0
jinja2==2.8
pygments==2.0.2
django-sites==0.9 django-sites==0.9
Markdown==2.6.5 Markdown==2.6.8
fn==0.4.3 fn==0.4.3
diff-match-patch==20121119 diff-match-patch==20121119
requests==2.9.1 requests==2.13.0
requests-oauthlib==0.8.0
webcolors==1.7
django-sr==0.0.4 django-sr==0.0.4
easy-thumbnails==2.3 easy-thumbnails==2.3
celery==3.1.20 celery==4.0.2
redis==2.10.5 redis==2.10.5
Unidecode==0.04.19 Unidecode==0.4.20
raven==5.10.2 raven==6.0.0
bleach==1.4.3 bleach==1.5.0
django-ipware==1.1.3 django-ipware==1.1.6
premailer==2.9.7 premailer==3.0.1
cssutils==1.0.1 # Compatible with python 3.5 cssutils==1.0.1 # Compatible with python 3.5
lxml==3.5.0 lxml==3.7.3
git+https://github.com/Xof/django-pglocks.git@dbb8d7375066859f897604132bd437832d2014ea git+https://github.com/Xof/django-pglocks.git
pyjwkest==1.1.5 pyjwkest==1.3.2
python-dateutil==2.4.2 python-dateutil==2.6.0
netaddr==0.7.18 netaddr==0.7.19
serpy==0.1.1 serpy==0.1.1
psd-tools==1.4 psd-tools==1.4
CairoSVG==2.0.1
cryptography==1.7.1
PyJWT==1.4.2
asana==0.6.2

2
scripts/manage_translations.py Normal file → Executable file
View File

@ -246,7 +246,7 @@ You need transifex-client, install it.
or or
$ pip install --upgrade transifex-client==0.11.1.beta $ pip install --upgrade transifex-client==0.12.2
2. Create ~/.transifexrc file: 2. Create ~/.transifexrc file:

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the
@ -16,19 +16,22 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from kombu import Exchange, Queue from kombu import Queue
BROKER_URL = 'amqp://guest:guest@localhost:5672//' broker_url = 'amqp://guest:guest@localhost:5672//'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0' result_backend = 'redis://localhost:6379/0'
CELERY_TIMEZONE = 'Europe/Madrid' accept_content = ['pickle',] # Values are 'pickle', 'json', 'msgpack' and 'yaml'
CELERY_ENABLE_UTC = True task_serializer = "pickle"
result_serializer = "pickle"
CELERY_DEFAULT_QUEUE = 'tasks' timezone = 'Europe/Madrid'
CELERY_QUEUES = (
task_default_queue = 'tasks'
task_queues = (
Queue('tasks', routing_key='task.#'), Queue('tasks', routing_key='task.#'),
Queue('transient', routing_key='transient.#', delivery_mode=1) Queue('transient', routing_key='transient.#', delivery_mode=1)
) )
CELERY_DEFAULT_EXCHANGE = 'tasks' task_default_exchange = 'tasks'
CELERY_DEFAULT_EXCHANGE_TYPE = 'topic' task_default_exchange_type = 'topic'
CELERY_DEFAULT_ROUTING_KEY = 'task.default' task_default_routing_key = 'task.default'

View File

@ -0,0 +1,4 @@
from .celery import *
# To use celery in memory
#task_always_eager = True

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the
@ -110,12 +110,12 @@ LANGUAGES = [
#("io", "IDO"), # Ido #("io", "IDO"), # Ido
#("is", "Íslenska"), # Icelandic #("is", "Íslenska"), # Icelandic
("it", "Italiano"), # Italian ("it", "Italiano"), # Italian
#("ja", "日本語"), # Japanese ("ja", "日本語"), # Japanese
#("ka", "ქართული"), # Georgian #("ka", "ქართული"), # Georgian
#("kk", "Қазақша"), # Kazakh #("kk", "Қазақша"), # Kazakh
#("km", "ភាសាខ្មែរ"), # Khmer #("km", "ភាសាខ្មែរ"), # Khmer
#("kn", "ಕನ್ನಡ"), # Kannada #("kn", "ಕನ್ನಡ"), # Kannada
#("ko", "한국어"), # Korean ("ko", "한국어"), # Korean
#("lb", "Lëtzebuergesch"), # Luxembourgish #("lb", "Lëtzebuergesch"), # Luxembourgish
#("lt", "Lietuvių"), # Lithuanian #("lt", "Lietuvių"), # Lithuanian
#("lv", "Latviešu"), # Latvian #("lv", "Latviešu"), # Latvian
@ -151,7 +151,7 @@ LANGUAGES = [
#("uk", "Українська"), # Ukrainian #("uk", "Українська"), # Ukrainian
#("ur", "اردو‏"), # Urdu #("ur", "اردو‏"), # Urdu
#("vi", "Tiếng Việt"), # Vietnamese #("vi", "Tiếng Việt"), # Vietnamese
#("zh-hans", "中文(简体)"), # Simplified Chinese ("zh-hans", "中文(简体)"), # Simplified Chinese
("zh-hant", "中文(香港)"), # Traditional Chinese ("zh-hant", "中文(香港)"), # Traditional Chinese
] ]
@ -282,6 +282,7 @@ INSTALLED_APPS = [
"django.contrib.admin", "django.contrib.admin",
"django.contrib.staticfiles", "django.contrib.staticfiles",
"django.contrib.sitemaps", "django.contrib.sitemaps",
"django.contrib.postgres",
"taiga.base", "taiga.base",
"taiga.base.api", "taiga.base.api",
@ -305,6 +306,7 @@ INSTALLED_APPS = [
"taiga.projects.tasks", "taiga.projects.tasks",
"taiga.projects.issues", "taiga.projects.issues",
"taiga.projects.wiki", "taiga.projects.wiki",
"taiga.projects.contact",
"taiga.searches", "taiga.searches",
"taiga.timeline", "taiga.timeline",
"taiga.mdrender", "taiga.mdrender",
@ -316,6 +318,7 @@ INSTALLED_APPS = [
"taiga.hooks.bitbucket", "taiga.hooks.bitbucket",
"taiga.hooks.gogs", "taiga.hooks.gogs",
"taiga.webhooks", "taiga.webhooks",
"taiga.importers",
"djmail", "djmail",
"django_jinja", "django_jinja",
@ -345,6 +348,10 @@ LOGGING = {
"null": { "null": {
"format": "%(message)s", "format": "%(message)s",
}, },
"django.server": {
"()": "django.utils.log.ServerFormatter",
"format": "[%(server_time)s] %(message)s",
},
}, },
"handlers": { "handlers": {
"null": { "null": {
@ -360,7 +367,12 @@ LOGGING = {
"level": "ERROR", "level": "ERROR",
"filters": ["require_debug_false"], "filters": ["require_debug_false"],
"class": "django.utils.log.AdminEmailHandler", "class": "django.utils.log.AdminEmailHandler",
} },
"django.server": {
"level": "INFO",
"class": "logging.StreamHandler",
"formatter": "django.server",
},
}, },
"loggers": { "loggers": {
"django": { "django": {
@ -382,6 +394,11 @@ LOGGING = {
"handlers": ["console"], "handlers": ["console"],
"level": "DEBUG", "level": "DEBUG",
"propagate": False, "propagate": False,
},
"django.server": {
"handlers": ["django.server"],
"level": "INFO",
"propagate": False,
} }
} }
} }
@ -416,16 +433,21 @@ REST_FRAMEWORK = {
"taiga.external_apps.auth_backends.Token", "taiga.external_apps.auth_backends.Token",
), ),
"DEFAULT_THROTTLE_CLASSES": ( "DEFAULT_THROTTLE_CLASSES": (
"taiga.base.throttling.AnonRateThrottle", "taiga.base.throttling.CommonThrottle",
"taiga.base.throttling.UserRateThrottle"
), ),
"DEFAULT_THROTTLE_RATES": { "DEFAULT_THROTTLE_RATES": {
"anon": None, "anon-write": None,
"user": None, "user-write": None,
"anon-read": None,
"user-read": None,
"import-mode": None, "import-mode": None,
"import-dump-mode": "1/minute", "import-dump-mode": "1/minute",
"create-memberships": None "create-memberships": None,
"login-fail": None,
"register-success": None,
"user-detail": None,
}, },
"DEFAULT_THROTTLE_WHITELIST": [],
"FILTER_BACKEND": "taiga.base.filters.FilterBackend", "FILTER_BACKEND": "taiga.base.filters.FilterBackend",
"EXCEPTION_HANDLER": "taiga.base.exceptions.exception_handler", "EXCEPTION_HANDLER": "taiga.base.exceptions.exception_handler",
"PAGINATE_BY": 30, "PAGINATE_BY": 30,
@ -455,8 +477,6 @@ SOUTH_MIGRATION_MODULES = {
} }
THN_AVATAR_SIZE = 80 # 80x80 pixels THN_AVATAR_SIZE = 80 # 80x80 pixels
THN_AVATAR_BIG_SIZE = 300 # 300x300 pixels THN_AVATAR_BIG_SIZE = 300 # 300x300 pixels
THN_LOGO_SMALL_SIZE = 80 # 80x80 pixels THN_LOGO_SMALL_SIZE = 80 # 80x80 pixels
@ -464,6 +484,7 @@ THN_LOGO_BIG_SIZE = 300 # 300x300 pixels
THN_TIMELINE_IMAGE_SIZE = 640 # 640x??? pixels THN_TIMELINE_IMAGE_SIZE = 640 # 640x??? pixels
THN_CARD_IMAGE_WIDTH = 300 # 300 pixels THN_CARD_IMAGE_WIDTH = 300 # 300 pixels
THN_CARD_IMAGE_HEIGHT = 200 # 200 pixels THN_CARD_IMAGE_HEIGHT = 200 # 200 pixels
THN_PREVIEW_IMAGE_WIDTH = 800 # 800 pixels
THN_AVATAR_SMALL = "avatar" THN_AVATAR_SMALL = "avatar"
THN_AVATAR_BIG = "big-avatar" THN_AVATAR_BIG = "big-avatar"
@ -471,6 +492,7 @@ THN_LOGO_SMALL = "logo-small"
THN_LOGO_BIG = "logo-big" THN_LOGO_BIG = "logo-big"
THN_ATTACHMENT_TIMELINE = "timeline-image" THN_ATTACHMENT_TIMELINE = "timeline-image"
THN_ATTACHMENT_CARD = "card-image" THN_ATTACHMENT_CARD = "card-image"
THN_ATTACHMENT_PREVIEW = "preview-image"
THUMBNAIL_ALIASES = { THUMBNAIL_ALIASES = {
"": { "": {
@ -480,6 +502,7 @@ THUMBNAIL_ALIASES = {
THN_LOGO_BIG: {"size": (THN_LOGO_BIG_SIZE, THN_LOGO_BIG_SIZE), "crop": True}, THN_LOGO_BIG: {"size": (THN_LOGO_BIG_SIZE, THN_LOGO_BIG_SIZE), "crop": True},
THN_ATTACHMENT_TIMELINE: {"size": (THN_TIMELINE_IMAGE_SIZE, 0), "crop": True}, THN_ATTACHMENT_TIMELINE: {"size": (THN_TIMELINE_IMAGE_SIZE, 0), "crop": True},
THN_ATTACHMENT_CARD: {"size": (THN_CARD_IMAGE_WIDTH, THN_CARD_IMAGE_HEIGHT), "crop": True}, THN_ATTACHMENT_CARD: {"size": (THN_CARD_IMAGE_WIDTH, THN_CARD_IMAGE_HEIGHT), "crop": True},
THN_ATTACHMENT_PREVIEW: {"size": (THN_PREVIEW_IMAGE_WIDTH, 0), "crop": False},
}, },
} }
@ -538,6 +561,30 @@ MAX_PENDING_MEMBERSHIPS = 30 # Max number of unconfirmed memberships in a projec
from .sr import * from .sr import *
IMPORTERS = {
"github": {
"active": False,
"client_id": "",
"client_secret": "",
},
"trello": {
"active": False,
"api_key": "",
"secret_key": "",
},
"jira": {
"active": False,
"consumer_key": "",
"cert": "",
"pub_cert": "",
},
"asana": {
"active": False,
"callback_url": "",
"app_id": "",
"app_secret": "",
}
}
# NOTE: DON'T INSERT MORE SETTINGS AFTER THIS LINE # NOTE: DON'T INSERT MORE SETTINGS AFTER THIS LINE
TEST_RUNNER="django.test.runner.DiscoverRunner" TEST_RUNNER="django.test.runner.DiscoverRunner"

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the
@ -63,12 +63,23 @@ DATABASES = {
######################################### #########################################
#REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"] = { #REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"] = {
# "anon": "20/min", # "anon-write": "20/min",
# "user": "200/min", # "user-write": None,
# "import-mode": "20/sec", # "anon-read": None,
# "import-dump-mode": "1/minute" # "user-read": None,
# "import-mode": None,
# "import-dump-mode": "1/minute",
# "create-memberships": None,
# "login-fail": None,
# "register-success": None,
# "user-detail": None,
#} #}
# This list should containt:
# - Tiga users IDs
# - Valid clients IP addresses (X-Forwarded-For header)
#REST_FRAMEWORK["DEFAULT_THROTTLE_WHITELIST"] = []
######################################### #########################################
## MAIL SYSTEM SETTINGS ## MAIL SYSTEM SETTINGS
@ -146,10 +157,47 @@ DATABASES = {
######################################### #########################################
## CELERY ## CELERY
######################################### #########################################
# Set to True to enable celery and work in async mode or False
# to disable it and work in sync mode. You can find the celery
# settings in settings/celery.py and settings/celery-local.py
#CELERY_ENABLED = True
#from .celery import *
#CELERY_ENABLED = True #########################################
# ## IMPORTERS
# To use celery in memory #########################################
#CELERY_ENABLED = True
#CELERY_ALWAYS_EAGER = True # Configuration for the GitHub importer
# Remember to enable it in the front client too.
#IMPORTERS["github"] = {
# "active": True, # Enable or disable the importer
# "client_id": "XXXXXX_get_a_valid_client_id_from_github_XXXXXX",
# "client_secret": "XXXXXX_get_a_valid_client_secret_from_github_XXXXXX"
#}
# Configuration for the Trello importer
# Remember to enable it in the front client too.
#IMPORTERS["trello"] = {
# "active": True, # Enable or disable the importer
# "api_key": "XXXXXX_get_a_valid_api_key_from_trello_XXXXXX",
# "secret_key": "XXXXXX_get_a_valid_secret_key_from_trello_XXXXXX"
#}
# Configuration for the Jira importer
# Remember to enable it in the front client too.
#IMPORTERS["jira"] = {
# "active": True, # Enable or disable the importer
# "consumer_key": "XXXXXX_get_a_valid_consumer_key_from_jira_XXXXXX",
# "cert": "XXXXXX_get_a_valid_cert_from_jira_XXXXXX",
# "pub_cert": "XXXXXX_get_a_valid_pub_cert_from_jira_XXXXXX"
#}
# Configuration for the Asane importer
# Remember to enable it in the front client too.
#IMPORTERS["asana"] = {
# "active": True, # Enable or disable the importer
# "callback_url": "{}://{}/project/new/import/asana".format(SITES["front"]["scheme"],
# SITES["front"]["domain"]),
# "app_id": "XXXXXX_get_a_valid_app_id_from_asana_XXXXXX",
# "app_secret": "XXXXXX_get_a_valid_app_secret_from_asana_XXXXXX"
#}

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the
@ -19,7 +19,6 @@
from .development import * from .development import *
CELERY_ENABLED = False CELERY_ENABLED = False
CELERY_ALWAYS_EAGER = True
MEDIA_ROOT = "/tmp" MEDIA_ROOT = "/tmp"
@ -29,9 +28,20 @@ INSTALLED_APPS = INSTALLED_APPS + [
] ]
REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"] = { REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"] = {
"anon": None, "anon-write": None,
"user": None, "anon-read": None,
"user-write": None,
"user-read": None,
"import-mode": None, "import-mode": None,
"import-dump-mode": None, "import-dump-mode": None,
"create-memberships": None, "create-memberships": None,
"login-fail": None,
"register-success": None,
"user-detail": None,
} }
IMPORTERS['github']['active'] = True
IMPORTERS['jira']['active'] = True
IMPORTERS['asana']['active'] = True
IMPORTERS['trello']['active'] = True

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the
@ -30,16 +30,16 @@ from taiga.base import exceptions as exc
from taiga.base import response from taiga.base import response
from .validators import PublicRegisterValidator from .validators import PublicRegisterValidator
from .validators import PrivateRegisterForExistingUserValidator from .validators import PrivateRegisterValidator
from .validators import PrivateRegisterForNewUserValidator
from .services import private_register_for_existing_user
from .services import private_register_for_new_user from .services import private_register_for_new_user
from .services import public_register from .services import public_register
from .services import make_auth_response_data from .services import make_auth_response_data
from .services import get_auth_plugins from .services import get_auth_plugins
from .services import accept_invitation_by_existing_user
from .permissions import AuthPermission from .permissions import AuthPermission
from .throttling import LoginFailRateThrottle, RegisterSuccessRateThrottle
def _parse_data(data:dict, *, cls): def _parse_data(data:dict, *, cls):
@ -61,41 +61,13 @@ def _parse_data(data:dict, *, cls):
# Parse public register data # Parse public register data
parse_public_register_data = partial(_parse_data, cls=PublicRegisterValidator) parse_public_register_data = partial(_parse_data, cls=PublicRegisterValidator)
# Parse private register data for existing user
parse_private_register_for_existing_user_data = \
partial(_parse_data, cls=PrivateRegisterForExistingUserValidator)
# Parse private register data for new user # Parse private register data for new user
parse_private_register_for_new_user_data = \ parse_private_register_data = partial(_parse_data, cls=PrivateRegisterValidator)
partial(_parse_data, cls=PrivateRegisterForNewUserValidator)
class RegisterTypeEnum(Enum):
new_user = 1
existing_user = 2
def parse_register_type(userdata:dict) -> str:
"""
Parses user data and detects that register type is.
It returns RegisterTypeEnum value.
"""
# Create adhoc inner serializer for avoid parse
# manually the user data.
class _validator(validators.Validator):
existing = serializers.BooleanField()
instance = _validator(data=userdata)
if not instance.is_valid():
raise exc.RequestValidationError(instance.errors)
if instance.data["existing"]:
return RegisterTypeEnum.existing_user
return RegisterTypeEnum.new_user
class AuthViewSet(viewsets.ViewSet): class AuthViewSet(viewsets.ViewSet):
permission_classes = (AuthPermission,) permission_classes = (AuthPermission,)
throttle_classes = (LoginFailRateThrottle, RegisterSuccessRateThrottle)
def _public_register(self, request): def _public_register(self, request):
if not settings.PUBLIC_REGISTER_ENABLED: if not settings.PUBLIC_REGISTER_ENABLED:
@ -111,14 +83,8 @@ class AuthViewSet(viewsets.ViewSet):
return response.Created(data) return response.Created(data)
def _private_register(self, request): def _private_register(self, request):
register_type = parse_register_type(request.DATA) data = parse_private_register_data(request.DATA)
user = private_register_for_new_user(**data)
if register_type is RegisterTypeEnum.existing_user:
data = parse_private_register_for_existing_user_data(request.DATA)
user = private_register_for_existing_user(**data)
else:
data = parse_private_register_for_new_user_data(request.DATA)
user = private_register_for_new_user(**data)
data = make_auth_response_data(user) data = make_auth_response_data(user)
return response.Created(data) return response.Created(data)
@ -140,9 +106,12 @@ class AuthViewSet(viewsets.ViewSet):
auth_plugins = get_auth_plugins() auth_plugins = get_auth_plugins()
login_type = request.DATA.get("type", None) login_type = request.DATA.get("type", None)
invitation_token = request.DATA.get("invitation_token", None)
if login_type in auth_plugins: if login_type in auth_plugins:
data = auth_plugins[login_type]['login_func'](request) data = auth_plugins[login_type]['login_func'](request)
if invitation_token:
accept_invitation_by_existing_user(invitation_token, data['id'])
return response.Ok(data) return response.Ok(data)
raise exc.BadRequest(_("invalid login type")) raise exc.BadRequest(_("invalid login type"))

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the
@ -128,16 +128,9 @@ def public_register(username:str, password:str, email:str, full_name:str):
@tx.atomic @tx.atomic
def private_register_for_existing_user(token:str, username:str, password:str): def accept_invitation_by_existing_user(token:str, user_id:int):
""" user_model = get_user_model()
Register works not only for register users, also serves for accept user = user_model.objects.get(id=user_id)
inviatations for projects as existing user.
Given a invitation token with parsed parameters, accept inviation
as existing user.
"""
user = get_and_validate_user(username=username, password=password)
membership = get_membership_by_token(token) membership = get_membership_by_token(token)
try: try:
@ -145,8 +138,6 @@ def private_register_for_existing_user(token:str, username:str, password:str):
membership.save(update_fields=["user"]) membership.save(update_fields=["user"])
except IntegrityError: except IntegrityError:
raise exc.IntegrityError(_("This user is already a member of the project.")) raise exc.IntegrityError(_("This user is already a member of the project."))
send_register_email(user)
return user return user

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

46
taiga/auth/throttling.py Normal file
View File

@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from taiga.base import throttling
class LoginFailRateThrottle(throttling.GlobalThrottlingMixin, throttling.ThrottleByActionMixin, throttling.SimpleRateThrottle):
scope = "login-fail"
throttled_actions = ["create"]
def throttle_success(self, request, view):
return True
def finalize(self, request, response, view):
if response.status_code == 400:
self.history.insert(0, self.now)
self.cache.set(self.key, self.history, self.duration)
class RegisterSuccessRateThrottle(throttling.GlobalThrottlingMixin, throttling.ThrottleByActionMixin, throttling.SimpleRateThrottle):
scope = "register-success"
throttled_actions = ["register"]
def throttle_success(self, request, view):
return True
def finalize(self, request, response, view):
if response.status_code == 201:
self.history.insert(0, self.now)
self.cache.set(self.key, self.history, self.duration)

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the
@ -48,11 +48,5 @@ class PublicRegisterValidator(BaseRegisterValidator):
pass pass
class PrivateRegisterForNewUserValidator(BaseRegisterValidator): class PrivateRegisterValidator(BaseRegisterValidator):
token = serializers.CharField(max_length=255, required=True)
class PrivateRegisterForExistingUserValidator(validators.Validator):
username = serializers.CharField(max_length=255)
password = serializers.CharField(min_length=4)
token = serializers.CharField(max_length=255, required=True) token = serializers.CharField(max_length=255, required=True)

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the
@ -618,13 +618,24 @@ class ChoiceField(WritableField):
return value return value
class InvalidEmailValidationError(ValidationError):
pass
class InvalidDomainValidationError(ValidationError):
pass
def validate_user_email_allowed_domains(value): def validate_user_email_allowed_domains(value):
validators.validate_email(value) try:
validators.validate_email(value)
except ValidationError as e:
raise InvalidEmailValidationError(e)
domain_name = value.split("@")[1] domain_name = value.split("@")[1]
if settings.USER_EMAIL_ALLOWED_DOMAINS and domain_name not in settings.USER_EMAIL_ALLOWED_DOMAINS: if settings.USER_EMAIL_ALLOWED_DOMAINS and domain_name not in settings.USER_EMAIL_ALLOWED_DOMAINS:
raise ValidationError(_("You email domain is not allowed")) raise InvalidDomainValidationError(_("You email domain is not allowed"))
class EmailField(CharField): class EmailField(CharField):

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the
@ -817,8 +817,18 @@ class ModelSerializer((six.with_metaclass(SerializerMetaclass, BaseSerializer)))
else: else:
# Reverse relationships are only included if they are explicitly # Reverse relationships are only included if they are explicitly
# present in the `fields` option on the serializer # present in the `fields` option on the serializer
reverse_rels = opts.get_all_related_objects()
reverse_rels += opts.get_all_related_many_to_many_objects() # NOTE: Rewrite after Django 1.10 upgrade.
# See https://docs.djangoproject.com/es/1.10/ref/models/meta/#migrating-from-the-old-api
reverse_rels = [
f for f in opts.get_fields()
if (f.one_to_many or f.one_to_one)
and f.auto_created and not f.concrete
]
reverse_rels += [
f for f in opts.get_fields(include_hidden=True)
if f.many_to_many and f.auto_created
]
for relation in reverse_rels: for relation in reverse_rels:
accessor_name = relation.get_accessor_name() accessor_name = relation.get_accessor_name()
@ -1024,16 +1034,32 @@ class ModelSerializer((six.with_metaclass(SerializerMetaclass, BaseSerializer)))
m2m_data = {} m2m_data = {}
related_data = {} related_data = {}
nested_forward_relations = {} nested_forward_relations = {}
model = self.opts.model
meta = self.opts.model._meta meta = self.opts.model._meta
# Reverse fk or one-to-one relations # Reverse fk or one-to-one relations
for (obj, model) in meta.get_all_related_objects_with_model(): # NOTE: Rewrite after Django 1.10 upgrade.
# See https://docs.djangoproject.com/es/1.10/ref/models/meta/#migrating-from-the-old-api
related_objes_with_models = [
(f, f.model if f.model != model else None)
for f in meta.get_fields()
if (f.one_to_many or f.one_to_one)
and f.auto_created and not f.concrete
]
for (obj, model) in related_objes_with_models:
field_name = obj.get_accessor_name() field_name = obj.get_accessor_name()
if field_name in attrs: if field_name in attrs:
related_data[field_name] = attrs.pop(field_name) related_data[field_name] = attrs.pop(field_name)
# Reverse m2m relations # Reverse m2m relations
for (obj, model) in meta.get_all_related_m2m_objects_with_model(): # NOTE: Rewrite after Django 1.10 upgrade.
# See https://docs.djangoproject.com/es/1.10/ref/models/meta/#migrating-from-the-old-api
related_m2m_objects_with_model = [
(f, f.model if f.model != model else None)
for f in meta.get_fields(include_hidden=True)
if f.many_to_many and f.auto_created
]
for (obj, model) in related_m2m_objects_with_model:
field_name = obj.get_accessor_name() field_name = obj.get_accessor_name()
if field_name in attrs: if field_name in attrs:
m2m_data[field_name] = attrs.pop(field_name) m2m_data[field_name] = attrs.pop(field_name)

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the
@ -106,6 +106,7 @@ DEFAULTS = {
"user": None, "user": None,
"anon": None, "anon": None,
}, },
"DEFAULT_THROTTLE_WHITELIST": [],
# Pagination # Pagination
"PAGINATE_BY": None, "PAGINATE_BY": None,

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the
@ -64,6 +64,12 @@ class BaseThrottle(object):
""" """
raise NotImplementedError(".allow_request() must be overridden") raise NotImplementedError(".allow_request() must be overridden")
def finalize(self, request, response, view):
"""
Optionally, update the Trottling information based on de response.
"""
return None
def wait(self): def wait(self):
""" """
Optionally, return a recommended number of seconds to wait before Optionally, return a recommended number of seconds to wait before
@ -105,6 +111,12 @@ class SimpleRateThrottle(BaseThrottle):
""" """
raise NotImplementedError(".get_cache_key() must be overridden") raise NotImplementedError(".get_cache_key() must be overridden")
def has_to_finalize(self, request, response, view):
"""
Determine if the finalize method must be executed.
"""
return self.rate is not None
def get_rate(self): def get_rate(self):
""" """
Determine the string representation of the allowed request rate. Determine the string representation of the allowed request rate.

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the
@ -44,7 +44,7 @@
from django.core.urlresolvers import RegexURLResolver from django.core.urlresolvers import RegexURLResolver
from django.conf.urls import patterns, url, include from django.conf.urls import url, include
from .settings import api_settings from .settings import api_settings
@ -67,7 +67,7 @@ def apply_suffix_patterns(urlpatterns, suffix_pattern, suffix_required):
else: else:
# Regular URL pattern # Regular URL pattern
regex = urlpattern.regex.pattern.rstrip("$") + suffix_pattern regex = urlpattern.regex.pattern.rstrip("$") + suffix_pattern
view = urlpattern._callback or urlpattern._callback_str view = urlpattern.callback
kwargs = urlpattern.default_args kwargs = urlpattern.default_args
name = urlpattern.name name = urlpattern.name
# Add in both the existing and the new urlpattern # Add in both the existing and the new urlpattern

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the
@ -144,6 +144,8 @@ class APIView(View):
# Allow dependancy injection of other settings to make testing easier. # Allow dependancy injection of other settings to make testing easier.
settings = api_settings settings = api_settings
_trottle_instances = None
@classmethod @classmethod
def as_view(cls, **initkwargs): def as_view(cls, **initkwargs):
""" """
@ -286,7 +288,9 @@ class APIView(View):
""" """
Instantiates and returns the list of throttles that this view uses. Instantiates and returns the list of throttles that this view uses.
""" """
return [throttle() for throttle in self.throttle_classes] if self._trottle_instances is None:
self._trottle_instances = [throttle() for throttle in self.throttle_classes]
return self._trottle_instances
def get_content_negotiator(self): def get_content_negotiator(self):
""" """
@ -342,6 +346,15 @@ class APIView(View):
if not throttle.allow_request(request, self): if not throttle.allow_request(request, self):
self.throttled(request, throttle.wait()) self.throttled(request, throttle.wait())
def finalize_throttles(self, request, response):
"""
Check if request should be throttled.
Raises an appropriate exception if the request is throttled.
"""
for throttle in self.get_throttles():
if throttle.has_to_finalize(request, response, self):
throttle.finalize(request, response, self)
# Dispatch methods # Dispatch methods
def initialize_request(self, request, *args, **kwargs): def initialize_request(self, request, *args, **kwargs):
@ -391,6 +404,8 @@ class APIView(View):
for key, value in self.headers.items(): for key, value in self.headers.items():
response[key] = value response[key] = value
self.finalize_throttles(request, response)
return response return response
def handle_exception(self, exc): def handle_exception(self, exc):

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

View File

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from .json import JSONField

View File

@ -0,0 +1,82 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.core.serializers.json import DjangoJSONEncoder
from django.contrib.postgres.fields import JSONField as DjangoJSONField
# NOTE: After upgrade Django to the future release (1.11) change
# class JSONField(FutureDjangoJSONField):
# to
# class JSONField(DjangoJSONField):
# and remove the classes JsonAdapter and FutureDjangoJSONField
import json
from psycopg2.extras import Json
from django.core import exceptions
class JsonAdapter(Json):
"""
Customized psycopg2.extras.Json to allow for a custom encoder.
"""
def __init__(self, adapted, dumps=None, encoder=None):
self.encoder = encoder
super().__init__(adapted, dumps=dumps)
def dumps(self, obj):
options = {'cls': self.encoder} if self.encoder else {}
return json.dumps(obj, **options)
class FutureDjangoJSONField(DjangoJSONField):
def __init__(self, verbose_name=None, name=None, encoder=None, **kwargs):
if encoder and not callable(encoder):
raise ValueError("The encoder parameter must be a callable object.")
self.encoder = encoder
super().__init__(verbose_name, name, **kwargs)
def deconstruct(self):
name, path, args, kwargs = super().deconstruct()
if self.encoder is not None:
kwargs['encoder'] = self.encoder
return name, path, args, kwargs
def get_prep_value(self, value):
if value is not None:
return JsonAdapter(value, encoder=self.encoder)
return value
def validate(self, value, model_instance):
super().validate(value, model_instance)
options = {'cls': self.encoder} if self.encoder else {}
try:
json.dumps(value, **options)
except TypeError:
raise exceptions.ValidationError(
self.error_messages['invalid'],
code='invalid',
params={'value': value},
)
__all__ = ["JSONField"]
class JSONField(FutureDjangoJSONField):
def __init__(self, verbose_name=None, name=None, encoder=DjangoJSONEncoder, **kwargs):
super().__init__(verbose_name, name, encoder, **kwargs)

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the
@ -30,7 +30,7 @@ import serpy
# NOTE: This should be in other place, for example taiga.base.api.serializers # NOTE: This should be in other place, for example taiga.base.api.serializers
class JsonField(serializers.WritableField): class JSONField(serializers.WritableField):
""" """
Json objects serializer. Json objects serializer.
""" """
@ -95,12 +95,12 @@ class I18NField(Field):
return _(ret) return _(ret)
class I18NJsonField(Field): class I18NJSONField(Field):
""" """
Json objects serializer. Json objects serializer.
""" """
def __init__(self, i18n_fields=(), *args, **kwargs): def __init__(self, i18n_fields=(), *args, **kwargs):
super(I18NJsonField, self).__init__(*args, **kwargs) super(I18NJSONField, self).__init__(*args, **kwargs)
self.i18n_fields = i18n_fields self.i18n_fields = i18n_fields
def translate_values(self, d): def translate_values(self, d):

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the
@ -527,6 +527,22 @@ class FinishDateFilter(BaseDateFilter):
filter_name_base = "finish_date" filter_name_base = "finish_date"
class EstimatedStartFilter(BaseDateFilter):
filter_name_base = "estimated_start"
class EstimatedFinishFilter(BaseDateFilter):
filter_name_base = "estimated_finish"
class MilestoneEstimatedStartFilter(BaseDateFilter):
filter_name_base = "milestone__estimated_start"
class MilestoneEstimatedFinishFilter(BaseDateFilter):
filter_name_base = "milestone__estimated_finish"
##################################################################### #####################################################################
# Text search filters # Text search filters
##################################################################### #####################################################################
@ -537,11 +553,11 @@ class QFilter(FilterBackend):
if q: if q:
table = queryset.model._meta.db_table table = queryset.model._meta.db_table
where_clause = (""" where_clause = ("""
to_tsvector('english_nostop', to_tsvector('simple',
coalesce({table}.subject, '') || ' ' || coalesce({table}.subject, '') || ' ' ||
coalesce(array_to_string({table}.tags, ' '), '') || ' ' || coalesce(array_to_string({table}.tags, ' '), '') || ' ' ||
coalesce({table}.ref) || ' ' || coalesce({table}.ref) || ' ' ||
coalesce({table}.description, '')) @@ to_tsquery('english_nostop', %s) coalesce({table}.description, '')) @@ to_tsquery('simple', %s)
""".format(table=table)) """.format(table=table))
queryset = queryset.extra(where=[where_clause], params=[to_tsquery(q)]) queryset = queryset.extra(where=[where_clause], params=[to_tsquery(q)])

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the
@ -18,8 +18,6 @@
import datetime import datetime
from optparse import make_option
from django.apps import apps from django.apps import apps
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
@ -33,28 +31,27 @@ from taiga.projects.history.services import get_history_queryset_by_model_instan
class Command(BaseCommand): class Command(BaseCommand):
args = '<email>'
option_list = BaseCommand.option_list + (
make_option('--locale', '-l', default=None, dest='locale',
help='Send emails in an specific language.'),
)
help = 'Send an example of all emails' help = 'Send an example of all emails'
def handle(self, *args, **options): def add_arguments(self, parser):
if len(args) != 1: parser.add_argument('--locale', '-l',
print("Usage: ./manage.py test_emails <email-address>") default=None,
return dest='locale',
help='Send emails in an specific language.')
parser.add_argument('email',
help='Emeil address to send sample emails.')
def handle(self, *args, **options):
locale = options.get('locale') locale = options.get('locale')
test_email = args[0] email_address = options.get('email')
# Register email # Register email
context = {"lang": locale, context = {"lang": locale,
"user": get_user_model().objects.all().order_by("?").first(), "user": get_user_model().objects.all().order_by("?").first(),
"cancel_token": "cancel-token"} "cancel_token": "cancel-token"}
email = mail_builder.registered_user(test_email, context) email = mail_builder.registered_user(email_address, context)
email.send() email.send()
# Membership invitation # Membership invitation
@ -63,13 +60,13 @@ class Command(BaseCommand):
membership.invitation_extra_text = "Text example, Text example,\nText example,\n\nText example" membership.invitation_extra_text = "Text example, Text example,\nText example,\n\nText example"
context = {"lang": locale, "membership": membership} context = {"lang": locale, "membership": membership}
email = mail_builder.membership_invitation(test_email, context) email = mail_builder.membership_invitation(email_address, context)
email.send() email.send()
# Membership notification # Membership notification
context = {"lang": locale, context = {"lang": locale,
"membership": Membership.objects.order_by("?").filter(user__isnull=False).first()} "membership": Membership.objects.order_by("?").filter(user__isnull=False).first()}
email = mail_builder.membership_notification(test_email, context) email = mail_builder.membership_notification(email_address, context)
email.send() email.send()
# Feedback # Feedback
@ -85,17 +82,17 @@ class Command(BaseCommand):
"key2": "value2", "key2": "value2",
}, },
} }
email = mail_builder.feedback_notification(test_email, context) email = mail_builder.feedback_notification(email_address, context)
email.send() email.send()
# Password recovery # Password recovery
context = {"lang": locale, "user": get_user_model().objects.all().order_by("?").first()} context = {"lang": locale, "user": get_user_model().objects.all().order_by("?").first()}
email = mail_builder.password_recovery(test_email, context) email = mail_builder.password_recovery(email_address, context)
email.send() email.send()
# Change email # Change email
context = {"lang": locale, "user": get_user_model().objects.all().order_by("?").first()} context = {"lang": locale, "user": get_user_model().objects.all().order_by("?").first()}
email = mail_builder.change_email(test_email, context) email = mail_builder.change_email(email_address, context)
email.send() email.send()
# Export/Import emails # Export/Import emails
@ -106,7 +103,7 @@ class Command(BaseCommand):
"error_subject": "Error generating project dump", "error_subject": "Error generating project dump",
"error_message": "Error generating project dump", "error_message": "Error generating project dump",
} }
email = mail_builder.export_error(test_email, context) email = mail_builder.export_error(email_address, context)
email.send() email.send()
context = { context = {
"lang": locale, "lang": locale,
@ -114,7 +111,7 @@ class Command(BaseCommand):
"error_subject": "Error importing project dump", "error_subject": "Error importing project dump",
"error_message": "Error importing project dump", "error_message": "Error importing project dump",
} }
email = mail_builder.import_error(test_email, context) email = mail_builder.import_error(email_address, context)
email.send() email.send()
deletion_date = timezone.now() + datetime.timedelta(seconds=60*60*24) deletion_date = timezone.now() + datetime.timedelta(seconds=60*60*24)
@ -125,7 +122,7 @@ class Command(BaseCommand):
"project": Project.objects.all().order_by("?").first(), "project": Project.objects.all().order_by("?").first(),
"deletion_date": deletion_date, "deletion_date": deletion_date,
} }
email = mail_builder.dump_project(test_email, context) email = mail_builder.dump_project(email_address, context)
email.send() email.send()
context = { context = {
@ -133,7 +130,7 @@ class Command(BaseCommand):
"user": get_user_model().objects.all().order_by("?").first(), "user": get_user_model().objects.all().order_by("?").first(),
"project": Project.objects.all().order_by("?").first(), "project": Project.objects.all().order_by("?").first(),
} }
email = mail_builder.load_dump(test_email, context) email = mail_builder.load_dump(email_address, context)
email.send() email.send()
# Notification emails # Notification emails
@ -187,7 +184,7 @@ class Command(BaseCommand):
cls = type("InlineCSSTemplateMail", (InlineCSSTemplateMail,), {"name": notification_email[1]}) cls = type("InlineCSSTemplateMail", (InlineCSSTemplateMail,), {"name": notification_email[1]})
email = cls() email = cls()
email.send(test_email, context) email.send(email_address, context)
# Transfer Emails # Transfer Emails
@ -195,7 +192,7 @@ class Command(BaseCommand):
"project": Project.objects.all().order_by("?").first(), "project": Project.objects.all().order_by("?").first(),
"requester": User.objects.all().order_by("?").first(), "requester": User.objects.all().order_by("?").first(),
} }
email = mail_builder.transfer_request(test_email, context) email = mail_builder.transfer_request(email_address, context)
email.send() email.send()
context = { context = {
@ -204,7 +201,7 @@ class Command(BaseCommand):
"token": "test-token", "token": "test-token",
"reason": "Test reason" "reason": "Test reason"
} }
email = mail_builder.transfer_start(test_email, context) email = mail_builder.transfer_start(email_address, context)
email.send() email.send()
context = { context = {
@ -213,7 +210,7 @@ class Command(BaseCommand):
"new_owner": User.objects.all().order_by("?").first(), "new_owner": User.objects.all().order_by("?").first(),
"reason": "Test reason" "reason": "Test reason"
} }
email = mail_builder.transfer_accept(test_email, context) email = mail_builder.transfer_accept(email_address, context)
email.send() email.send()
context = { context = {
@ -221,5 +218,5 @@ class Command(BaseCommand):
"rejecter": User.objects.all().order_by("?").first(), "rejecter": User.objects.all().order_by("?").first(),
"reason": "Test reason" "reason": "Test reason"
} }
email = mail_builder.transfer_reject(test_email, context) email = mail_builder.transfer_reject(email_address, context)
email.send() email.send()

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Anler Hernández <hello@anler.me> # Copyright (C) 2014-2017 Anler Hernández <hello@anler.me>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Anler Hernández <hello@anler.me> # Copyright (C) 2014-2017 Anler Hernández <hello@anler.me>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the
@ -20,7 +20,7 @@
import itertools import itertools
from collections import namedtuple from collections import namedtuple
from django.conf.urls import patterns, url from django.conf.urls import url
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.core.urlresolvers import NoReverseMatch from django.core.urlresolvers import NoReverseMatch
@ -79,7 +79,7 @@ class BaseRouter(object):
@property @property
def urls(self): def urls(self):
if not hasattr(self, '_urls'): if not hasattr(self, '_urls'):
self._urls = patterns('', *self.get_urls()) self._urls = self.get_urls()
return self._urls return self._urls

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.be> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.be>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the
@ -18,20 +18,18 @@
from django.apps import apps from django.apps import apps
from django.db import models, connection from django.db import models, connection
from django.db.utils import DEFAULT_DB_ALIAS, ConnectionHandler
from django.db.models.signals import pre_save, post_delete from django.db.models.signals import pre_save, post_delete
from django.dispatch import Signal
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
from django.dispatch import Signal
cleanup_pre_delete = Signal(providing_args=["file"]) cleanup_pre_delete = Signal(providing_args=["file"])
cleanup_post_delete = Signal(providing_args=["file"]) cleanup_post_delete = Signal(providing_args=["file"])
def _find_models_with_filefield(): def _find_models_with_filefield():
result = [] result = []
for model in apps.get_models(): for model in apps.get_models():
@ -50,7 +48,7 @@ def _delete_file(file_obj):
cleanup_post_delete.send(sender=None, file=file_obj) cleanup_post_delete.send(sender=None, file=file_obj)
except Exception: except Exception:
logger.exception("Unexpected exception while attempting " logger.exception("Unexpected exception while attempting "
"to delete old file '%s'".format(file_obj.name)) "to delete old file '%s'".format(file_obj.name))
storage = file_obj.storage storage = file_obj.storage
if storage and storage.exists(file_obj.name): if storage and storage.exists(file_obj.name):
@ -90,9 +88,6 @@ def remove_files_on_delete(sender, instance, **kwargs):
def connect_cleanup_files_signals(): def connect_cleanup_files_signals():
connections = ConnectionHandler()
backend = connections[DEFAULT_DB_ALIAS]
for model in _find_models_with_filefield(): for model in _find_models_with_filefield():
pre_save.connect(remove_files_on_change, sender=model) pre_save.connect(remove_files_on_change, sender=model)
post_delete.connect(remove_files_on_delete, sender=model) post_delete.connect(remove_files_on_delete, sender=model)

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.be> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.be>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -157,7 +157,6 @@
padding-bottom:20px; padding-bottom:20px;
padding-left:20px; padding-left:20px;
padding-top:20px; padding-top:20px;
text-align:center;
} }
/** /**
@ -188,6 +187,13 @@
background: #aad400; background: #aad400;
} }
hr {
width: 90%;
margin: 0 auto;
border-bottom: 1px solid #e1e1e1;
border-top: 0;
}
.bodyContent img{ .bodyContent img{
display:inline; display:inline;
height:auto; height:auto;
@ -396,16 +402,25 @@
<a href="{{ resolve_front_url("home") }}" title="Taiga"> <a href="{{ resolve_front_url("home") }}" title="Taiga">
<img src="{{ static("emails/logo-color.png") }}" id="headerImage" alt="Taiga" /> <img src="{{ static("emails/logo-color.png") }}" id="headerImage" alt="Taiga" />
</a> </a>
{% block body %} </td>
{% endblock %} </tr>
</table>
</td>
</tr>
<tr>
<td align="center" valign="top">
<table border="0" cellpadding="0" cellspacing="0" width="100%" id="templateBody">
<tr>
<td valign="top" class="bodyContent">
{% block body %}{% endblock %}
</td> </td>
</tr> </tr>
{% block social %} {% block social %}
<tr> <tr>
<td valign="top" class="social-links"> <td valign="top" class="social-links">
<a href="{{ sr("social.twitter_url") }}" title="{{ _("Follow us on Twitter") }}" style="color: #9dce0a">{{ _("Twitter") }}</a> <a href="{{ sr('social.twitter_url') }}" title="{{ _('Follow us on Twitter') }}" style="color: #9dce0a">{{ _("Twitter") }}</a>
<a href="{{ sr("social.github_url") }}" title="{{ _("Get the code on GitHub") }}" style="color: #9dce0a">{{ _("GitHub") }}</a> <a href="{{ sr('social.github_url') }}" title="{{ _('Get the code on GitHub') }}" style="color: #9dce0a">{{ _("GitHub") }}</a>
<a href="{{ sr("taigaio_url") }}" title="{{ _("Visit our website") }}" style="color: #9dce0a">{{ _("Taiga.io") }}</a> <a href="{{ sr('taigaio_url') }}" title="{{ _('Visit our website') }}" style="color: #9dce0a">{{ _("Taiga.io") }}</a>
</td> </td>
</tr> </tr>
{% endblock %} {% endblock %}

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the
@ -16,24 +16,183 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from taiga.base.api import throttling from taiga.base.api import throttling
from ipware.ip import get_ip
from netaddr import all_matching_cidrs
from netaddr.core import AddrFormatError
class GlobalThrottlingMixin:
"""
Define the cache key based on the user IP independently if the user is
logged in or not.
"""
def get_cache_key(self, request, view):
ident = get_ip(request)
return self.cache_format % {
"scope": self.scope,
"ident": ident
}
class ThrottleByActionMixin:
throttled_actions = []
def has_to_finalize(self, request, response, view):
if super().has_to_finalize(request, response, view):
return view.action in self.throttled_actions
return False
def allow_request(self, request, view):
if view.action in self.throttled_actions:
return super().allow_request(request, view)
return True
class AnonRateThrottle(throttling.AnonRateThrottle): class AnonRateThrottle(throttling.AnonRateThrottle):
scope = "anon" scope = "anon"
throttled_methods = ["GET", "POST", "PUT", "DELETE", "PATCH"]
def allow_request(self, request, view):
if request.method not in self.throttled_methods:
return True
return super().allow_request(request, view)
class UserRateThrottle(throttling.UserRateThrottle): class UserRateThrottle(throttling.UserRateThrottle):
scope = "user" scope = "user"
throttled_methods = ["GET", "POST", "PUT", "DELETE", "PATCH"]
class CommonThrottle(throttling.SimpleRateThrottle):
cache_format = "throtte_%(scope)s_%(rate)s_%(ident)s"
def __init__(self):
pass
def has_to_finalize(self, request, response, view):
return False
def is_whitelisted(self, ident):
for whitelisted in settings.REST_FRAMEWORK['DEFAULT_THROTTLE_WHITELIST']:
if isinstance(whitelisted, int) and whitelisted == ident:
return True
elif isinstance(whitelisted, str):
try:
if all_matching_cidrs(ident, [whitelisted]) != []:
return True
except(AddrFormatError, ValueError):
pass
return False
def allow_request(self, request, view): def allow_request(self, request, view):
if request.method not in self.throttled_methods: scope = self.get_scope(request)
ident = self.get_ident(request)
rates = self.get_rates(scope)
if self.is_whitelisted(ident):
return True return True
return super().allow_request(request, view)
if rates is None or rates == []:
return True
now = self.timer()
waits = []
history_writes = []
for rate in rates:
rate_name = rate[0]
rate_num_requests = rate[1]
rate_duration = rate[2]
key = self.get_cache_key(ident, scope, rate_name)
history = self.cache.get(key, [])
while history and history[-1] <= now - rate_duration:
history.pop()
if len(history) >= rate_num_requests:
waits.append(self.wait_time(history, rate, now))
history_writes.append({
"key": key,
"history": history,
"rate_duration": rate_duration,
})
if waits:
self._wait = max(waits)
return False
for history_write in history_writes:
history_write['history'].insert(0, now)
self.cache.set(
history_write['key'],
history_write['history'],
history_write['rate_duration']
)
return True
def get_rates(self, scope):
try:
rates = self.THROTTLE_RATES[scope]
except KeyError:
msg = "No default throttle rate set for \"%s\" scope" % scope
raise ImproperlyConfigured(msg)
if rates is None:
return []
elif isinstance(rates, str):
return [self.parse_rate(rates)]
elif isinstance(rates, list):
return list(map(self.parse_rate, rates))
else:
msg = "No valid throttle rate set for \"%s\" scope" % scope
raise ImproperlyConfigured(msg)
def parse_rate(self, rate):
"""
Given the request rate string, return a two tuple of:
<allowed number of requests>, <period of time in seconds>
"""
if rate is None:
return None
num, period = rate.split("/")
num_requests = int(num)
duration = {"s": 1, "m": 60, "h": 3600, "d": 86400}[period[0]]
return (rate, num_requests, duration)
def get_scope(self, request):
scope_prefix = "user" if request.user.is_authenticated() else "anon"
scope_sufix = "write" if request.method in ["POST", "PUT", "PATCH", "DELETE"] else "read"
scope = "{}-{}".format(scope_prefix, scope_sufix)
return scope
def get_ident(self, request):
if request.user.is_authenticated():
return request.user.id
ident = get_ip(request)
return ident
def get_cache_key(self, ident, scope, rate):
return self.cache_format % { "scope": scope, "ident": ident, "rate": rate }
def wait_time(self, history, rate, now):
rate_num_requests = rate[1]
rate_duration = rate[2]
if history:
remaining_duration = rate_duration - (now - history[-1])
else:
remaining_duration = rate_duration
available_requests = rate_num_requests - len(history) + 1
if available_requests <= 0:
return remaining_duration
return remaining_duration / float(available_requests)
def wait(self):
return self._wait
class SimpleRateThrottle(throttling.SimpleRateThrottle):
pass

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.be> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.be>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Anler Hernández <hello@anler.me> # Copyright (C) 2014-2017 Anler Hernández <hello@anler.me>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Anler Hernández <hello@anler.me> # Copyright (C) 2014-2017 Anler Hernández <hello@anler.me>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Anler Hernández <hello@anler.me> # Copyright (C) 2014-2017 Anler Hernández <hello@anler.me>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.be> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.be>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the
@ -26,12 +26,28 @@ from taiga.base.utils.urls import get_absolute_url
from easy_thumbnails.files import get_thumbnailer from easy_thumbnails.files import get_thumbnailer
from easy_thumbnails.exceptions import InvalidImageFormatError from easy_thumbnails.exceptions import InvalidImageFormatError
from PIL import Image from PIL import Image
from PIL.PngImagePlugin import PngImageFile
from io import BytesIO
# SVG thumbnail generator
try:
from cairosvg.surface import PNGSurface
def svg_image_factory(data, *args):
png_data = PNGSurface.convert(data.read())
return PngImageFile(BytesIO(png_data))
Image.register_mime("SVG", "image/svg+xml")
Image.register_extension("SVG", ".svg")
Image.register_open("SVG", svg_image_factory)
except Exception:
pass
# PSD thumbnail generator
def psd_image_factory(data, *args): def psd_image_factory(data, *args):
return PSDImage.from_stream(data).as_PIL() return PSDImage.from_stream(data).as_PIL()
Image.init() Image.init()
Image.register_open("PSD", psd_image_factory) Image.register_open("PSD", psd_image_factory)

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Anler Hernández <hello@anler.me> # Copyright (C) 2014-2017 Anler Hernández <hello@anler.me>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the
@ -20,11 +20,15 @@ import os
from celery import Celery from celery import Celery
from django.conf import settings
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings') os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings')
app = Celery('taiga') from django.conf import settings
app.config_from_object('django.conf:settings') try:
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS, related_name="deferred") from settings import celery_local as celery_settings
except ImportError:
from settings import celery as celery_settings
app = Celery('taiga')
app.config_from_object(celery_settings)
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)

View File

@ -1,69 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.conf import settings
from .celery import app
def _send_task(task, args, kwargs, **options):
if settings.CELERY_ALWAYS_EAGER:
return app.tasks[task].apply(args, kwargs, **options)
return app.send_task(task, args, kwargs, **options)
def defer(task: str, *args, **kwargs):
"""Defer the execution of a task.
Defer the execution of a task and returns a future objects with the following methods among
others:
- `failed()` Returns `True` if the task failed.
- `ready()` Returns `True` if the task has been executed.
- `forget()` Forget about the result.
- `get()` Wait until the task is ready and return its result.
- `result` When the task has been executed the result is in this attribute.
More info at Celery docs on `AsyncResult` object.
:param task: Name of the task to execute.
:return: A future object.
"""
return _send_task(task, args, kwargs, routing_key="transient.deferred")
def call_async(task: str, *args, **kwargs):
"""Run a task and ignore its result.
This is just a star argument version of `apply_async`.
:param task: Name of the task to execute.
:param args: Arguments for the task.
:param kwargs: Keyword arguments for the task.
"""
apply_async(task, args, kwargs)
def apply_async(task: str, args=None, kwargs=None, **options):
"""Run a task and ignore its result.
:param task: Name of the task to execute.
:param args: Tupple of arguments for the task.
:param kwargs: Dict of keyword arguments for the task.
:param options: Celery-specific options when running the task. See Celery docs on `apply_async`
"""
_send_task(task, args, kwargs, **options)

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the # published by the Free Software Foundation, either version 3 of the

Some files were not shown because too many files have changed in this diff Show More