+++ /dev/null
-# Copyright 2011-2012 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 django.db import IntegrityError, transaction
-from django.core.exceptions import ObjectDoesNotExist
-
-from functools import wraps
-from smtplib import SMTPException
-
-from astakos.im.models import (
- AstakosUser, AstakosGroup, GroupKind, Resource, Service, RESOURCE_SEPARATOR
-)
-from astakos.im.api.backends.base import BaseBackend, SuccessResult, FailureResult
-from astakos.im.api.backends.errors import (
- ItemNotExists, ItemExists, MissingIdentifier, MultipleItemsExist
-)
-from astakos.im.util import reserved_email, model_to_dict
-from astakos.im.endpoints.quotaholder import get_quota
-
-import logging
-
-logger = logging.getLogger(__name__)
-
-DEFAULT_CONTENT_TYPE = None
-
-
-def safe(func):
- """Decorator function for views that implement an API method."""
- @transaction.commit_manually
- @wraps(func)
- def wrapper(self, *args, **kwargs):
- logger.debug('%s %s %s' % (func, args, kwargs))
- try:
- data = func(self, *args, **kwargs) or ()
- except Exception, e:
- logger.exception(e)
- transaction.rollback()
- return FailureResult(getattr(e, 'message', e))
- else:
- transaction.commit()
- return SuccessResult(data)
- return wrapper
-
-
-class DjangoBackend(BaseBackend):
- def _lookup_object(self, model, **kwargs):
- """
- Returns an object of the specific model matching the given lookup
- parameters.
- """
- if not kwargs:
- raise MissingIdentifier
- try:
- return model.objects.get(**kwargs)
- except model.DoesNotExist:
- raise ItemNotExists(model._meta.verbose_name, **kwargs)
- except model.MultipleObjectsReturned:
- raise MultipleItemsExist(model._meta.verbose_name, **kwargs)
-
- def _lookup_user(self, id):
- """
- Returns an AstakosUser having this id.
- """
- if not isinstance(id, int):
- raise TypeError('User id should be of type int')
- return self._lookup_object(AstakosUser, id=id)
-
- def _lookup_service(self, id):
- """
- Returns an Service having this id.
- """
- if not isinstance(id, int):
- raise TypeError('Service id should be of type int')
- return self._lookup_object(Service, id=id)
-
- def _list(self, model, filter=()):
- q = model.objects.all()
- if filter:
- q = q.filter(id__in=filter)
- return map(lambda o: model_to_dict(o, exclude=[]), q)
-
- def _create_object(self, model, **kwargs):
- o = model.objects.create(**kwargs)
- o.save()
- return o
-
- def _update_object(self, model, id, save=True, **kwargs):
- o = self._lookup_object(model, id=id)
- if kwargs:
- o.__dict__.update(kwargs)
- if save:
- o.save()
- return o
-
- @safe
- def update_user(self, user_id, renew_token=False, **kwargs):
- user = self._update_object(AstakosUser, user_id, save=False, **kwargs)
- if renew_token:
- user.renew_token()
- if kwargs or renew_token:
- user.save()
-
- @safe
- def create_user(self, **kwargs):
- policies = kwargs.pop('policies', ())
- permissions = kwargs.pop('permissions', ())
- groups = kwargs.pop('groups', ())
- password = kwargs.pop('password', None)
-
- u = self._create_object(AstakosUser, **kwargs)
-
- if password:
- u.set_password(password)
- u.permissions = permissions
- u.policies = policies
- u.extended_groups = groups
- return self._list(AstakosUser, filter=(u.id,))
-
- @safe
- def add_policies(self, user_id, update=False, policies=()):
- user = self._lookup_user(user_id)
- rejected = []
- append = rejected.append
- for p in policies:
- service = p.get('service')
- resource = p.get('resource')
- uplimit = p.get('uplimit')
- try:
- user.add_policy(service, resource, uplimit, update)
- except (ObjectDoesNotExist, IntegrityError), e:
- append((service, resource, e))
- return rejected
-
- @safe
- def remove_policies(self, user_id, policies=()):
- user = self._lookup_user(user_id)
- if not user:
- return user_id
- rejected = []
- append = rejected.append
- for p in policies:
- service = p.get('service')
- resource = p.get('resource')
- try:
- user.delete_policy(service, resource)
- except ObjectDoesNotExist, e:
- append((service, resource, e))
- return rejected
- @safe
- def add_permissions(self, user_id, permissions=()):
- user = self._lookup_user(user_id)
- rejected = []
- append = rejected.append
- for p in permissions:
- try:
- user.add_permission(p)
- except IntegrityError, e:
- append((p, e))
- return rejected
-
- @safe
- def remove_permissions(self, user_id, permissions=()):
- user = self._lookup_user(user_id)
- rejected = []
- append = rejected.append
- for p in permissions:
- try:
- user.remove_permission(p)
- except (ObjectDoesNotExist, IntegrityError), e:
- append((p, e))
- return rejected
-
- @safe
- def invite_users(self, senderid, recipients=()):
- user = self._lookup_user(senderid)
- rejected = []
- append = rejected.append
- for r in recipients:
- try:
- user.invite(r.get('email'), r.get('realname'))
- except (IntegrityError, SMTPException), e:
- append((email, e))
- return rejected
-
- @safe
- def list_users(self, filter=()):
- return self._list(AstakosUser, filter=filter)
-
- @safe
- def get_resource_usage(self, user_id):
- user = self._lookup_user(user_id)
- c, data = get_quota((user,))
- resources = []
- append = resources.append
- for t in data:
- t = (i if i else 0 for i in t)
- (entity, name, quantity, capacity, importLimit, exportLimit,
- imported, exported, returned, released, flags) = t
- service, sep, resource = name.partition(RESOURCE_SEPARATOR)
- resource = Resource.objects.select_related().get(
- service__name=service, name=resource)
- d = dict(name=name,
- description=resource.desc,
- unit=resource.unit or '',
- maxValue=quantity + capacity,
- currValue=quantity + imported - released - exported + returned)
- append(d)
- return resources
-
- @safe
- def list_resources(self, filter=()):
- return self._list(Resource, filter=filter)
-
- @safe
- def create_service(self, **kwargs):
- resources = kwargs.pop('resources', ())
- s = self._create_object(Service, **kwargs)
- s.resources = resources
- return self._list(Service, filter=(s.id,))
-
- @safe
- def remove_services(self, ids=()):
- # TODO return information for unknown ids
- q = Service.objects.filter(id__in=ids)
- q.delete()
-
- @safe
- def update_service(self, service_id, renew_token=False, **kwargs):
- s = self._update_object(Service, service_id, save=False, **kwargs)
- if renew_token:
- s.renew_token()
-
- if kwargs or renew_token:
- s.save()
-
- @safe
- def add_resources(self, service_id, update=False, resources=()):
- s = self._lookup_service(service_id)
- rejected = []
- append = rejected.append
- for r in resources:
- try:
- rr = r.copy()
- resource_id = rr.pop('id', None)
- if update:
- if not resource_id:
- raise MissingIdentifier
- resource = self._update_object(Resource, resource_id, **rr)
- else:
- resource = self._create_object(Resource, service=s, **rr)
- except Exception, e:
- append((r, e))
- return rejected
-
- @safe
- def remove_resources(self, service_id, ids=()):
- # TODO return information for unknown ids
- q = Resource.objects.filter(service__id=service_id,
- id__in=ids)
- q.delete()
-
- @safe
- def create_group(self, **kwargs):
- policies = kwargs.pop('policies', ())
- permissions = kwargs.pop('permissions', ())
- members = kwargs.pop('members', ())
- owners = kwargs.pop('owners', ())
- kwargs['kind'] = self._lookup_object(
- GroupKind, name=kwargs.get('kind', 'course')
- )
-
- g = self._create_object(AstakosGroup, **kwargs)
-
- g.permissions = permissions
- g.policies = policies
-# g.members = members
- g.owners = owners
- return self._list(AstakosGroup, filter=(g.id,))
\ No newline at end of file