Commit 023cab33 authored by Kostas Papadimitriou's avatar Kostas Papadimitriou

astakos: Split settings in separate modules

parent ee3baa07
# Copyright 2011 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# conditions are met:
#
# 1. Redistributions of source code must retain the above
# copyright notice, this list of conditions and the following
# disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and
# documentation are those of the authors and should not be
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
from astakos.im.tests.auth import *
from astakos.im.tests.projects import *
from astakos.im.tests.api import *
# Copyright 2011 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# conditions are met:
#
# 1. Redistributions of source code must retain the above
# copyright notice, this list of conditions and the following
# disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and
# documentation are those of the authors and should not be
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
from astakos.im.tests.common import *
ROOT = '/astakos/api/'
u = lambda url: ROOT + url
class QuotaAPITest(TestCase):
def test_0(self):
client = Client()
# custom service resources
service1 = Service.objects.create(
name="service1", api_url="http://service1.api")
resource11 = {"name": "service1.resource11",
"desc": "resource11 desc",
"allow_in_projects": True}
r, _ = resources.add_resource(service1, resource11)
resources.update_resource(r, 100)
resource12 = {"name": "service1.resource12",
"desc": "resource11 desc",
"unit": "bytes"}
r, _ = resources.add_resource(service1, resource12)
resources.update_resource(r, 1024)
# create user
user = get_local_user('test@grnet.gr')
quotas.qh_sync_user(user)
# create another service
service2 = Service.objects.create(
name="service2", api_url="http://service2.api")
resource21 = {"name": "service2.resource21",
"desc": "resource11 desc",
"allow_in_projects": False}
r, _ = resources.add_resource(service2, resource21)
resources.update_resource(r, 3)
resource_names = [r['name'] for r in
[resource11, resource12, resource21]]
# get resources
r = client.get(u('resources'))
self.assertEqual(r.status_code, 200)
body = json.loads(r.content)
for name in resource_names:
assertIn(name, body)
# get quota
r = client.get(u('quotas'))
self.assertEqual(r.status_code, 401)
headers = {'HTTP_X_AUTH_TOKEN': user.auth_token}
r = client.get(u('quotas/'), **headers)
self.assertEqual(r.status_code, 200)
body = json.loads(r.content)
system_quota = body['system']
assertIn('system', body)
for name in resource_names:
assertIn(name, system_quota)
r = client.get(u('service_quotas'))
self.assertEqual(r.status_code, 401)
s1_headers = {'HTTP_X_AUTH_TOKEN': service1.auth_token}
r = client.get(u('service_quotas'), **s1_headers)
self.assertEqual(r.status_code, 200)
body = json.loads(r.content)
assertIn(user.uuid, body)
r = client.get(u('commissions'), **s1_headers)
self.assertEqual(r.status_code, 200)
body = json.loads(r.content)
self.assertEqual(body, [])
# issue some commissions
commission_request = {
"force": False,
"auto_accept": False,
"name": "my commission",
"provisions": [
{
"holder": user.uuid,
"source": "system",
"resource": resource11['name'],
"quantity": 1
},
{
"holder": user.uuid,
"source": "system",
"resource": resource12['name'],
"quantity": 30000
}]}
post_data = json.dumps(commission_request)
r = client.post(u('commissions'), post_data,
content_type='application/json', **s1_headers)
self.assertEqual(r.status_code, 413)
commission_request = {
"force": False,
"auto_accept": False,
"name": "my commission",
"provisions": [
{
"holder": user.uuid,
"source": "system",
"resource": resource11['name'],
"quantity": 1
},
{
"holder": user.uuid,
"source": "system",
"resource": resource12['name'],
"quantity": 100
}]}
post_data = json.dumps(commission_request)
r = client.post(u('commissions'), post_data,
content_type='application/json', **s1_headers)
self.assertEqual(r.status_code, 201)
body = json.loads(r.content)
serial = body['serial']
self.assertEqual(serial, 1)
post_data = json.dumps(commission_request)
r = client.post(u('commissions'), post_data,
content_type='application/json', **s1_headers)
self.assertEqual(r.status_code, 201)
body = json.loads(r.content)
self.assertEqual(body['serial'], 2)
post_data = json.dumps(commission_request)
r = client.post(u('commissions'), post_data,
content_type='application/json', **s1_headers)
self.assertEqual(r.status_code, 201)
body = json.loads(r.content)
self.assertEqual(body['serial'], 3)
r = client.get(u('commissions'), **s1_headers)
self.assertEqual(r.status_code, 200)
body = json.loads(r.content)
self.assertEqual(body, [1, 2, 3])
r = client.get(u('commissions/' + str(serial)), **s1_headers)
self.assertEqual(r.status_code, 200)
body = json.loads(r.content)
self.assertEqual(body['serial'], serial)
assertIn('issue_time', body)
self.assertEqual(body['provisions'], commission_request['provisions'])
self.assertEqual(body['name'], commission_request['name'])
r = client.get(u('service_quotas?user=' + user.uuid), **s1_headers)
self.assertEqual(r.status_code, 200)
body = json.loads(r.content)
user_quota = body[user.uuid]
system_quota = user_quota['system']
r11 = system_quota[resource11['name']]
self.assertEqual(r11['usage'], 3)
self.assertEqual(r11['pending'], 3)
# resolve pending commissions
resolve_data = {
"accept": [1, 3],
"reject": [2, 3, 4],
}
post_data = json.dumps(resolve_data)
r = client.post(u('commissions/action'), post_data,
content_type='application/json', **s1_headers)
self.assertEqual(r.status_code, 200)
body = json.loads(r.content)
self.assertEqual(body['accepted'], [1])
self.assertEqual(body['rejected'], [2])
failed = body['failed']
self.assertEqual(len(failed), 2)
r = client.get(u('commissions/' + str(serial)), **s1_headers)
self.assertEqual(r.status_code, 404)
# auto accept
commission_request = {
"auto_accept": True,
"name": "my commission",
"provisions": [
{
"holder": user.uuid,
"source": "system",
"resource": resource11['name'],
"quantity": 1
},
{
"holder": user.uuid,
"source": "system",
"resource": resource12['name'],
"quantity": 100
}]}
post_data = json.dumps(commission_request)
r = client.post(u('commissions'), post_data,
content_type='application/json', **s1_headers)
self.assertEqual(r.status_code, 201)
body = json.loads(r.content)
serial = body['serial']
self.assertEqual(serial, 4)
r = client.get(u('commissions/' + str(serial)), **s1_headers)
self.assertEqual(r.status_code, 404)
# malformed
commission_request = {
"auto_accept": True,
"name": "my commission",
"provisions": [
{
"holder": user.uuid,
"source": "system",
"resource": resource11['name'],
}
]}
post_data = json.dumps(commission_request)
r = client.post(u('commissions'), post_data,
content_type='application/json', **s1_headers)
self.assertEqual(r.status_code, 400)
commission_request = {
"auto_accept": True,
"name": "my commission",
"provisions": "dummy"}
post_data = json.dumps(commission_request)
r = client.post(u('commissions'), post_data,
content_type='application/json', **s1_headers)
self.assertEqual(r.status_code, 400)
r = client.post(u('commissions'), commission_request,
content_type='application/json', **s1_headers)
self.assertEqual(r.status_code, 400)
# no holding
commission_request = {
"auto_accept": True,
"name": "my commission",
"provisions": [
{
"holder": user.uuid,
"source": "system",
"resource": "non existent",
"quantity": 1
},
{
"holder": user.uuid,
"source": "system",
"resource": resource12['name'],
"quantity": 100
}]}
post_data = json.dumps(commission_request)
r = client.post(u('commissions'), post_data,
content_type='application/json', **s1_headers)
self.assertEqual(r.status_code, 404)
# release
commission_request = {
"provisions": [
{
"holder": user.uuid,
"source": "system",
"resource": resource11['name'],
"quantity": -1
}
]}
post_data = json.dumps(commission_request)
r = client.post(u('commissions'), post_data,
content_type='application/json', **s1_headers)
self.assertEqual(r.status_code, 201)
body = json.loads(r.content)
serial = body['serial']
accept_data = {'accept': ""}
post_data = json.dumps(accept_data)
r = client.post(u('commissions/' + str(serial) + '/action'), post_data,
content_type='application/json', **s1_headers)
self.assertEqual(r.status_code, 200)
reject_data = {'reject': ""}
post_data = json.dumps(accept_data)
r = client.post(u('commissions/' + str(serial) + '/action'), post_data,
content_type='application/json', **s1_headers)
self.assertEqual(r.status_code, 404)
# force
commission_request = {
"force": True,
"provisions": [
{
"holder": user.uuid,
"source": "system",
"resource": resource11['name'],
"quantity": 100
}]}
post_data = json.dumps(commission_request)
r = client.post(u('commissions'), post_data,
content_type='application/json', **s1_headers)
self.assertEqual(r.status_code, 201)
commission_request = {
"force": True,
"provisions": [
{
"holder": user.uuid,
"source": "system",
"resource": resource11['name'],
"quantity": -200
}]}
post_data = json.dumps(commission_request)
r = client.post(u('commissions'), post_data,
content_type='application/json', **s1_headers)
self.assertEqual(r.status_code, 413)
r = client.get(u('quotas'), **headers)
self.assertEqual(r.status_code, 200)
body = json.loads(r.content)
system_quota = body['system']
r11 = system_quota[resource11['name']]
self.assertEqual(r11['usage'], 102)
self.assertEqual(r11['pending'], 101)
# Copyright 2011 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# conditions are met:
#
# 1. Redistributions of source code must retain the above
# copyright notice, this list of conditions and the following
# disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and
# documentation are those of the authors and should not be
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
from contextlib import contextmanager
import copy
import datetime
import functools
from snf_django.utils.testing import with_settings, override_settings, assertIn
from django.test import Client
from django.test import TransactionTestCase as TestCase
from django.core import mail
from django.http import SimpleCookie, HttpRequest, QueryDict
from django.utils.importlib import import_module
from django.utils import simplejson as json
from astakos.im.activation_backends import *
from astakos.im.target.shibboleth import Tokens as ShibbolethTokens
from astakos.im.models import *
from astakos.im import functions
from astakos.im import settings as astakos_settings
from astakos.im import forms
from astakos.im import activation_backends
from urllib import quote
from datetime import timedelta
from astakos.im import messages
from astakos.im import auth_providers
from astakos.im import quotas
from astakos.im import resources
from django.conf import settings
# set some common settings
astakos_settings.EMAILCHANGE_ENABLED = True
astakos_settings.RECAPTCHA_ENABLED = False
settings.LOGGING_SETUP['disable_existing_loggers'] = False
# shortcut decorators to override provider settings
# e.g. shibboleth_settings(ENABLED=True) will set
# ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_ENABLED = True in global synnefo settings
prefixes = {'providers': 'AUTH_PROVIDER_',
'shibboleth': 'ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_',
'local': 'ASTAKOS_AUTH_PROVIDER_LOCAL_'}
im_settings = functools.partial(with_settings, astakos_settings)
shibboleth_settings = functools.partial(with_settings,
settings,
prefix=prefixes['shibboleth'])
localauth_settings = functools.partial(with_settings, settings,
prefix=prefixes['local'])
class AstakosTestClient(Client):
pass
class ShibbolethClient(AstakosTestClient):
"""
A shibboleth agnostic client.
"""
VALID_TOKENS = filter(lambda x: not x.startswith("_"),
dir(ShibbolethTokens))
def __init__(self, *args, **kwargs):
self.tokens = kwargs.pop('tokens', {})
super(ShibbolethClient, self).__init__(*args, **kwargs)
def set_tokens(self, **kwargs):
for key, value in kwargs.iteritems():
key = 'SHIB_%s' % key.upper()
if not key in self.VALID_TOKENS:
raise Exception('Invalid shibboleth token')
self.tokens[key] = value
def unset_tokens(self, *keys):
for key in keys:
key = 'SHIB_%s' % param.upper()
if key in self.tokens:
del self.tokens[key]
def reset_tokens(self):
self.tokens = {}
def get_http_token(self, key):
http_header = getattr(ShibbolethTokens, key)
return http_header
def request(self, **request):
"""
Transform valid shibboleth tokens to http headers
"""
for token, value in self.tokens.iteritems():
request[self.get_http_token(token)] = value
for param in request.keys():
key = 'SHIB_%s' % param.upper()
if key in self.VALID_TOKENS:
request[self.get_http_token(key)] = request[param]
del request[param]
return super(ShibbolethClient, self).request(**request)
def get_user_client(username, password="password"):
client = Client()
client.login(username=username, password=password)
return client
def get_local_user(username, **kwargs):
try:
return AstakosUser.objects.get(email=username)
except:
user_params = {
'username': username,
'email': username,
'is_active': True,
'activation_sent': datetime.now(),
'email_verified': True
}
user_params.update(kwargs)
user = AstakosUser(**user_params)
user.set_password(kwargs.get('password', 'password'))
user.renew_verification_code()
user.save()
user.add_auth_provider('local', auth_backend='astakos')
if kwargs.get('is_active', True):
user.is_active = True
else:
user.is_active = False
user.save()
return user
def get_mailbox(email):
mails = []
for sent_email in mail.outbox:
for recipient in sent_email.recipients():
if email in recipient:
mails.append(sent_email)
return mails
# Copyright 2011 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# conditions are met:
#
# 1. Redistributions of source code must retain the above
# copyright notice, this list of conditions and the following
# disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,