Commit 8441dbf1 authored by Sofia Papagiannaki's avatar Sofia Papagiannaki
Browse files

Merge branch 'dev' of https://code.grnet.gr/git/astakos into dev

parents 6d1bb983 9430c9f4
......@@ -33,6 +33,10 @@
import socket
import logging
import itertools
from functools import wraps
from itertools import tee
from django.utils.translation import ugettext as _
......@@ -46,50 +50,72 @@ ENTITY_KEY = '1'
logger = logging.getLogger(__name__)
def register_users(users, client=None):
if not users:
return
if not QUOTA_HOLDER_URL:
return
c = client or QuotaholderHTTP(QUOTA_HOLDER_URL)
def call(func_name):
"""Decorator function for QuotaholderHTTP client calls."""
def decorator(payload_func):
@wraps(payload_func)
def wrapper(entities=(), client=None, **kwargs):
if not entities:
return ()
if not QUOTA_HOLDER_URL:
return ()
c = client or QuotaholderHTTP(QUOTA_HOLDER_URL)
func = c.__dict__.get(func_name)
if not func:
return c,
data = payload_func(entities, client, **kwargs)
if not data:
return c,
funcname = func.__name__
kwargs = {'context': {}, funcname: data}
rejected = func(**kwargs)
msg = _('%s: %s - Rejected: %s' % (funcname, data, rejected,))
logger.log(LOGGING_LEVEL, msg)
return c, rejected
return wrapper
return decorator
@call('set_quota')
def send_quota(users, client=None):
data = []
append = data.append
for user in users:
try:
entity = user.email
except AttributeError:
continue
else:
args = entity, owner, key, ownerkey = (
entity, 'system', ENTITY_KEY, ''
)
for resource, limit in user.quota.iteritems():
key = ENTITY_KEY
quantity = None
capacity = limit
import_limit = None
export_limit = None
flags = 0
args = (user.email, resource, key, quantity, capacity, import_limit,
export_limit, flags)
append(args)
return data
if not data:
return
rejected = c.create_entity(
context={},
create_entity=data,
)
msg = _('Create entities: %s - Rejected: %s' % (data, rejected,))
logger.log(LOGGING_LEVEL, msg)
created = filter(lambda u: unicode(u.email) not in rejected, users)
send_quota(created, c)
return rejected
def send_quota(users, client=None):
if not users:
return
if not QUOTA_HOLDER_URL:
return
c = client or QuotaholderHTTP(QUOTA_HOLDER_URL)
@call('set_quota')
def send_resource_quantities(resources, client=None):
data = []
append = data.append
for resource in resources:
key = ENTITY_KEY
quantity = resource.meta.filter(key='quantity') or None
capacity = None
import_limit = None
export_limit = None
flags = 0
args = (resource.service, resource, key, quantity, capacity,
import_limit, export_limit, flags)
append(args)
return data
@call('get_quota')
def get_quota(users, client=None):
data = []
append = data.append
for user in users:
......@@ -98,46 +124,42 @@ def send_quota(users, client=None):
except AttributeError:
continue
else:
for resource, limit in user.quota.iteritems():
args = entity, resource, key, quantity, capacity, import_limit, \
export_limit, flags = (
entity, resource, ENTITY_KEY, '0', str(limit), 0, 0, 0
)
for r in user.quota.keys():
args = entity, r, ENTITY_KEY
append(args)
return data
if not data:
return
rejected = c.set_quota(context={}, set_quota=data)
msg = _('Set quota: %s - Rejected: %s' % (data, rejected,))
logger.log(LOGGING_LEVEL, msg)
return rejected
def get_quota(users, client=None):
if not users:
return
if not QUOTA_HOLDER_URL:
return
c = client or QuotaholderHTTP(QUOTA_HOLDER_URL)
@call('create_entity')
def create_entities(entities, client=None, field=''):
data = []
append = data.append
for user in users:
for entity in entities:
try:
entity = user.email
entity = entity.__getattribute__(field)
except AttributeError:
continue
else:
for r in user.quota.keys():
args = entity, resource, key = entity, r, ENTITY_KEY
append(args)
owner = 'system'
key = ENTITY_KEY
ownerkey = ''
args = entity, owner, key, ownerkey
append(args)
return data
if not data:
return
r = c.get_quota(context={}, get_quota=data)
msg = _('Get quota: %s' % data)
logger.log(LOGGING_LEVEL, msg)
return r
def register_users(users, client=None):
users, copy = itertools.tee(users)
client, rejected = create_entities(entities=users,
client=client,
field='email')
created = (e for e in copy if unicode(e) not in rejected)
return send_quota(created, client)
def register_resources(resources, client=None):
resources, copy = itertools.tee(resources)
client, rejected = create_entities(entities=resources,
client=client,
field='service')
created = (e for e in copy if unicode(e) not in rejected)
return send_resource_quantities(created, client)
\ No newline at end of file
......@@ -34,8 +34,8 @@
from django.core.management.base import BaseCommand, CommandError
from django.db.utils import IntegrityError
from astakos.im.models import AstakosUser
from astakos.im.endpoints.quotaholder import register_users
from astakos.im.models import AstakosUser, Resource
from astakos.im.endpoints.quotaholder import register_users, register_resources
class Command(BaseCommand):
......@@ -43,8 +43,7 @@ class Command(BaseCommand):
def handle(self, *args, **options):
try:
r = register_users(AstakosUser.objects.all())
self.stdout.write("Rejected: %s\n" % r)
register_resources(Resource.objects.all())
register_users(AstakosUser.objects.all())
except BaseException, e:
print e
raise CommandError("Bootstrap failed.")
......@@ -4,7 +4,7 @@ from south.v2 import DataMigration
d = {
'cyclades': {'vm': 2},
'pithos+': {'diskspace': 10}
'pithos+': {'diskspace': 50 * 1024 * 1024 * 1024} # 5 GB
}
......
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
db.alter_column('im.astakosgroupquota', 'limit', models.BigIntegerField())
db.alter_column('im.astakosuserquota', 'limit', models.BigIntegerField())
def backwards(self, orm):
pass
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'im.additionalmail': {
'Meta': {'object_name': 'AdditionalMail'},
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosUser']"})
},
'im.approvalterms': {
'Meta': {'object_name': 'ApprovalTerms'},
'date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 9, 18, 11, 20, 5, 795917)', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'location': ('django.db.models.fields.CharField', [], {'max_length': '255'})
},
'im.astakosgroup': {
'Meta': {'object_name': 'AstakosGroup', '_ormbases': ['auth.Group']},
'approval_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'creation_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 9, 18, 11, 20, 5, 790126)'}),
'desc': ('django.db.models.fields.TextField', [], {'null': 'True'}),
'estimated_participants': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}),
'expiration_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'group_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.Group']", 'unique': 'True', 'primary_key': 'True'}),
'homepage': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'issue_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'kind': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.GroupKind']"}),
'moderation_enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'policy': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['im.Resource']", 'null': 'True', 'through': "orm['im.AstakosGroupQuota']", 'blank': 'True'})
},
'im.astakosgroupquota': {
'Meta': {'unique_together': "(('resource', 'group'),)", 'object_name': 'AstakosGroupQuota'},
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosGroup']", 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'limit': ('django.db.models.fields.PositiveIntegerField', [], {}),
'resource': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.Resource']"})
},
'im.astakosuser': {
'Meta': {'unique_together': "(('provider', 'third_party_identifier'),)", 'object_name': 'AstakosUser', '_ormbases': ['auth.User']},
'activation_sent': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'affiliation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'astakos_groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['im.AstakosGroup']", 'symmetrical': 'False', 'through': "orm['im.Membership']", 'blank': 'True'}),
'auth_token': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
'auth_token_created': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'auth_token_expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'date_signed_terms': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'email_verified': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'has_credits': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'has_signed_terms': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'invitations': ('django.db.models.fields.IntegerField', [], {'default': '100'}),
'is_verified': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'level': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'owner': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'owner'", 'null': 'True', 'to': "orm['im.AstakosGroup']"}),
'policy': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['im.Resource']", 'null': 'True', 'through': "orm['im.AstakosUserQuota']", 'symmetrical': 'False'}),
'provider': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'third_party_identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'updated': ('django.db.models.fields.DateTimeField', [], {}),
'user_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'})
},
'im.astakosuserquota': {
'Meta': {'unique_together': "(('resource', 'user'),)", 'object_name': 'AstakosUserQuota'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'limit': ('django.db.models.fields.PositiveIntegerField', [], {}),
'resource': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.Resource']"}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosUser']"})
},
'im.emailchange': {
'Meta': {'object_name': 'EmailChange'},
'activation_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '40', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'new_email_address': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'requested_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 9, 18, 11, 20, 5, 797455)'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'emailchange_user'", 'unique': 'True', 'to': "orm['im.AstakosUser']"})
},
'im.groupkind': {
'Meta': {'object_name': 'GroupKind'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'})
},
'im.invitation': {
'Meta': {'object_name': 'Invitation'},
'code': ('django.db.models.fields.BigIntegerField', [], {'db_index': 'True'}),
'consumed': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'inviter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'invitations_sent'", 'null': 'True', 'to': "orm['im.AstakosUser']"}),
'is_consumed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'realname': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
},
'im.membership': {
'Meta': {'unique_together': "(('person', 'group'),)", 'object_name': 'Membership'},
'date_joined': ('django.db.models.fields.DateField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
'date_requested': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 9, 18, 11, 20, 5, 793914)', 'blank': 'True'}),
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosGroup']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosUser']"})
},
'im.resource': {
'Meta': {'object_name': 'Resource'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'meta': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['im.ResourceMetadata']", 'symmetrical': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}),
'service': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.Service']"})
},
'im.resourcemetadata': {
'Meta': {'object_name': 'ResourceMetadata'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}),
'value': ('django.db.models.fields.CharField', [], {'max_length': '255'})
},
'im.service': {
'Meta': {'object_name': 'Service'},
'auth_token': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
'auth_token_created': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'auth_token_expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'icon': ('django.db.models.fields.FilePathField', [], {'max_length': '100', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}),
'url': ('django.db.models.fields.FilePathField', [], {'max_length': '100'})
}
}
complete_apps = ['im']
......@@ -51,9 +51,10 @@ from django.dispatch import Signal
from django.db.models import Q
from astakos.im.settings import (DEFAULT_USER_LEVEL, INVITATIONS_PER_LEVEL,
AUTH_TOKEN_DURATION, BILLING_FIELDS, EMAILCHANGE_ACTIVATION_DAYS, LOGGING_LEVEL
)
from astakos.im.endpoints.quotaholder import register_users, send_quota
AUTH_TOKEN_DURATION, BILLING_FIELDS,
EMAILCHANGE_ACTIVATION_DAYS, LOGGING_LEVEL)
from astakos.im.endpoints.quotaholder import (register_users, send_quota,
register_resources)
from astakos.im.endpoints.aquarium.producer import report_user_event
from astakos.im.tasks import propagate_groupmembers_quota
......@@ -616,6 +617,12 @@ def astakosuser_post_save(sender, instance, created, **kwargs):
register_users((instance,))
def resource_post_save(sender, instance, created, **kwargs):
if not created:
return
register_resources((instance,))
def send_quota_disturbed(sender, instance, **kwargs):
users = []
extend = users.extend
......@@ -645,6 +652,7 @@ post_syncdb.connect(fix_superusers)
post_save.connect(user_post_save, sender=User)
pre_save.connect(astakosuser_pre_save, sender=AstakosUser)
post_save.connect(astakosuser_post_save, sender=AstakosUser)
post_save.connect(resource_post_save, sender=Resource)
quota_disturbed = Signal(providing_args=["users"])
quota_disturbed.connect(on_quota_disturbed)
......
......@@ -365,8 +365,10 @@ def signup(request, template_name='im/signup.html', on_success='im/signup_comple
logger.log(LOGGING_LEVEL, msg)
if user and user.is_active:
next = request.POST.get('next', '')
transaction.commit()
return prepare_response(request, user, next=next)
messages.add_message(request, status, message)
transaction.commit()
return render_response(on_success,
context_instance=get_context(request, extra_context))
except SendMailError, e:
......@@ -378,8 +380,6 @@ def signup(request, template_name='im/signup.html', on_success='im/signup_comple
messages.error(request, message)
logger.exception(e)
transaction.rollback()
else:
transaction.commit()
return render_response(template_name,
signup_form=form,
provider=provider,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment