Merge pull request #823 from taigaio/remove-secret-key-on-applications
Remove secret key on external appsremotes/origin/issue/4795/notification_even_they_are_disabled
commit
7754d315f0
|
@ -1,32 +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 Crypto.PublicKey import RSA
|
||||
from jwkest.jwk import SYMKey
|
||||
from jwkest.jwe import JWE
|
||||
|
||||
|
||||
def encrypt(content, key):
|
||||
sym_key = SYMKey(key=key, alg="A128KW")
|
||||
jwe = JWE(content, alg="A128KW", enc="A256GCM")
|
||||
return jwe.encrypt([sym_key])
|
||||
|
||||
|
||||
def decrypt(content, key):
|
||||
sym_key = SYMKey(key=key, alg="A128KW")
|
||||
return JWE().decrypt(content, keys=[sym_key])
|
|
@ -0,0 +1,33 @@
|
|||
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
|
||||
# Copyright (C) 2014 Jesús Espino <jespinog@gmail.com>
|
||||
# Copyright (C) 2014 David Barragán <bameda@dbarragan.com>
|
||||
# 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.management.base import BaseCommand
|
||||
from taiga.external_apps.models import Application
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
args = ''
|
||||
help = 'Create Taiga Tribe external app information'
|
||||
|
||||
def handle(self, *args, **options):
|
||||
Application.objects.get_or_create(
|
||||
id="8836b290-9f45-11e5-958e-52540016141a",
|
||||
name="Taiga Tribe",
|
||||
icon_url="https://tribe.taiga.io/static/common/graphics/logo/reindeer-color.png",
|
||||
web="https://tribe.taiga.io",
|
||||
description="A task-based employment marketplace for software development.",
|
||||
next_url="https://tribe.taiga.io/taiga-integration",
|
||||
)
|
|
@ -0,0 +1,19 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.2 on 2016-09-14 14:13
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('external_apps', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='application',
|
||||
name='key',
|
||||
),
|
||||
]
|
|
@ -40,8 +40,6 @@ class Application(models.Model):
|
|||
|
||||
next_url = models.TextField(null=False, blank=False, verbose_name=_("Next url"))
|
||||
|
||||
key = models.TextField(null=False, blank=False, verbose_name=_("secret key for ciphering the application tokens"))
|
||||
|
||||
class Meta:
|
||||
verbose_name = "application"
|
||||
verbose_name_plural = "applications"
|
||||
|
@ -71,10 +69,6 @@ class ApplicationToken(models.Model):
|
|||
def __str__(self):
|
||||
return "{application}: {user} - {token}".format(application=self.application.name, user=self.user.get_full_name(), token=self.token)
|
||||
|
||||
@property
|
||||
def cyphered_token(self):
|
||||
return services.cypher_token(self)
|
||||
|
||||
@property
|
||||
def next_url(self):
|
||||
return "{url}?auth_code={auth_code}".format(url=self.application.next_url, auth_code=self.auth_code)
|
||||
|
|
|
@ -48,4 +48,4 @@ class AuthorizationCodeSerializer(serializers.LightSerializer):
|
|||
|
||||
|
||||
class AccessTokenSerializer(serializers.LightSerializer):
|
||||
cyphered_token = Field()
|
||||
token = Field()
|
||||
|
|
|
@ -23,8 +23,6 @@ from taiga.base.api.utils import get_object_or_404
|
|||
from django.apps import apps
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from . import encryption
|
||||
|
||||
import json
|
||||
|
||||
def get_user_for_application_token(token:str) -> object:
|
||||
|
@ -46,11 +44,3 @@ def authorize_token(application_id:int, user:object, state:str) -> object:
|
|||
token.state = state
|
||||
token.save()
|
||||
return token
|
||||
|
||||
|
||||
def cypher_token(application_token:object) -> str:
|
||||
content = {
|
||||
"token": application_token.token
|
||||
}
|
||||
|
||||
return encryption.encrypt(json.dumps(content), application_token.application.key)
|
||||
|
|
|
@ -29,7 +29,7 @@ class ApplicationValidator(validators.ModelValidator):
|
|||
|
||||
|
||||
class ApplicationTokenValidator(validators.ModelValidator):
|
||||
cyphered_token = serializers.CharField(source="cyphered_token", read_only=True)
|
||||
token = serializers.CharField(source="token", read_only=True)
|
||||
next_url = serializers.CharField(source="next_url", read_only=True)
|
||||
application = ApplicationValidator(read_only=True)
|
||||
|
||||
|
@ -46,9 +46,9 @@ class AuthorizationCodeValidator(validators.ModelValidator):
|
|||
|
||||
|
||||
class AccessTokenValidator(validators.ModelValidator):
|
||||
cyphered_token = serializers.CharField(source="cyphered_token", read_only=True)
|
||||
token = serializers.CharField(source="token", read_only=True)
|
||||
next_url = serializers.CharField(source="next_url", read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = models.ApplicationToken
|
||||
fields = ("cyphered_token", )
|
||||
fields = ("token", )
|
||||
|
|
|
@ -560,7 +560,6 @@ class ApplicationFactory(Factory):
|
|||
model = "external_apps.Application"
|
||||
strategy = factory.CREATE_STRATEGY
|
||||
|
||||
key = "testingkey"
|
||||
|
||||
class ApplicationTokenFactory(Factory):
|
||||
class Meta:
|
||||
|
|
|
@ -115,7 +115,6 @@ def test_application_tokens_validate(client, data):
|
|||
|
||||
data = json.dumps({
|
||||
"application": data.token.application.id,
|
||||
"key": data.token.application.key,
|
||||
"auth_code": data.token.auth_code,
|
||||
"state": data.token.state
|
||||
})
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from taiga.external_apps import encryption
|
||||
from taiga.external_apps import models
|
||||
|
||||
|
||||
|
@ -116,9 +115,7 @@ def test_token_validate(client):
|
|||
assert response.status_code == 200
|
||||
|
||||
token = models.ApplicationToken.objects.get(id=token.id)
|
||||
decyphered_token = encryption.decrypt(response.data["cyphered_token"], token.application.key)[0]
|
||||
decyphered_token = json.loads(decyphered_token.decode("utf-8"))
|
||||
assert decyphered_token["token"] == token.token
|
||||
assert response.data["token"] == token.token
|
||||
|
||||
|
||||
def test_token_validate_validated(client):
|
||||
|
|
Loading…
Reference in New Issue