get_model_and_form_class)
from django.views.generic.list_detail import object_list
from django.core.xheaders import populate_xheaders
-
+from django.core.exceptions import ValidationError, PermissionDenied
from django.template.loader import render_to_string
from django.views.decorators.http import require_http_methods
-from astakos.im.activation_backends import get_backend, SimpleBackend
+from django.db.models import Q
+from astakos.im.activation_backends import get_backend, SimpleBackend
from astakos.im.models import (AstakosUser, ApprovalTerms, AstakosGroup,
EmailChange, GroupKind, Membership,
- RESOURCE_SEPARATOR)
+ RESOURCE_SEPARATOR, AstakosUserAuthProvider)
from astakos.im.util import get_context, prepare_response, get_query, restrict_next
from astakos.im.forms import (LoginForm, InvitationForm, ProfileForm,
FeedbackForm, SignApprovalTermsForm,
EmailChangeForm,
AstakosGroupCreationForm, AstakosGroupSearchForm,
AstakosGroupUpdateForm, AddGroupMembersForm,
- MembersSortForm,
+ MembersSortForm, AstakosGroupSortForm,
TimelineForm, PickResourceForm,
AstakosGroupCreationSummaryForm)
from astakos.im.functions import (send_feedback, SendMailError,
from astakos.im.endpoints.qh import timeline_charge
from astakos.im.settings import (COOKIE_DOMAIN, LOGOUT_NEXT,
LOGGING_LEVEL, PAGINATE_BY, RESOURCES_PRESENTATION_DATA, PAGINATE_BY_ALL)
-from astakos.im.tasks import request_billing
+#from astakos.im.tasks import request_billing
from astakos.im.api.callpoint import AstakosCallpoint
import astakos.im.messages as astakos_messages
+from astakos.im import settings
+from astakos.im import auth_providers
logger = logging.getLogger(__name__)
-DB_REPLACE_GROUP_SCHEME = """REPLACE(REPLACE("auth_group".name, 'http://', ''),
- 'https://', '')"""
-
callpoint = AstakosCallpoint()
def render_response(template, tab=None, status=200, context_instance=None, **kwargs):
response = HttpResponse(html, status=status)
return response
+def requires_auth_provider(provider_id, **perms):
+ """
+ """
+ def decorator(func, *args, **kwargs):
+ @wraps(func)
+ def wrapper(request, *args, **kwargs):
+ provider = auth_providers.get_provider(provider_id)
+
+ if not provider or not provider.is_active():
+ raise PermissionDenied
+
+ if provider:
+ for pkey, value in perms.iteritems():
+ attr = 'is_available_for_%s' % pkey.lower()
+ if getattr(provider, attr)() != value:
+ raise PermissionDenied
+ return func(request, *args)
+ return wrapper
+ return decorator
+
def requires_anonymous(func):
"""
template_name = login_template_name
if request.user.is_authenticated():
return HttpResponseRedirect(reverse('astakos.im.views.edit_profile'))
-
+
return render_response(
template_name,
login_form = LoginForm(request=request),
except ValueError, ve:
messages.success(request, ve)
elif request.method == "GET":
- if not request.user.is_verified:
- request.user.is_verified = True
- request.user.save()
+ request.user.is_verified = True
+ request.user.save()
+
+ # existing providers
+ user_providers = request.user.get_active_auth_providers()
+
+ # providers that user can add
+ user_available_providers = request.user.get_available_auth_providers()
+
return render_response(template_name,
profile_form = form,
+ user_providers = user_providers,
+ user_available_providers = user_available_providers,
context_instance = get_context(request,
extra_context))
return HttpResponseRedirect(reverse('edit_profile'))
provider = get_query(request).get('provider', 'local')
+ if not auth_providers.get_provider(provider).is_available_for_create():
+ raise PermissionDenied
+
id = get_query(request).get('id')
try:
instance = AstakosUser.objects.get(id=id) if id else None
except AstakosUser.DoesNotExist:
instance = None
+ third_party_token = request.REQUEST.get('third_party_token', None)
+
try:
if not backend:
backend = get_backend(request)
result = backend.handle_activation(user)
status = messages.SUCCESS
message = result.message
- user.save()
+
+ form.store_user(user, request)
+
if 'additional_email' in form.cleaned_data:
additional_email = form.cleaned_data['additional_email']
if additional_email != user.email:
transaction.commit()
return response
messages.add_message(request, status, message)
+ transaction.commit()
return render_response(
on_success,
context_instance=get_context(
transaction.rollback()
return render_response(template_name,
signup_form=form,
+ third_party_token=third_party_token,
provider=provider,
context_instance=get_context(request, extra_context))
def send_activation(request, user_id, template_name='im/login.html', extra_context=None):
+
+ if settings.MODERATION_ENABLED:
+ raise PermissionDenied
+
extra_context = extra_context or {}
try:
u = AstakosUser.objects.get(id=user_id)
)
class ResourcePresentation():
-
+
def __init__(self, data):
self.data = data
-
+
def update_from_result(self, result):
if result.is_success:
for r in result.data:
rname = '%s%s%s' % (r.get('service'), RESOURCE_SEPARATOR, r.get('name'))
if not rname in self.data['resources']:
self.data['resources'][rname] = {}
-
+
self.data['resources'][rname].update(r)
self.data['resources'][rname]['id'] = rname
group = r.get('group')
if not group in self.data['groups']:
self.data['groups'][group] = {}
-
+
self.data['groups'][r.get('group')].update({'name': r.get('group')})
-
+
def test(self, quota_dict):
for k, v in quota_dict.iteritems():
rname = k
value = v
if not rname in self.data['resources']:
self.data['resources'][rname] = {}
-
-
+
+
self.data['resources'][rname]['value'] = value
-
-
+
+
def update_from_result_report(self, result):
if result.is_success:
for r in result.data:
rname = r.get('name')
if not rname in self.data['resources']:
self.data['resources'][rname] = {}
-
+
self.data['resources'][rname].update(r)
self.data['resources'][rname]['id'] = rname
group = r.get('group')
if not group in self.data['groups']:
self.data['groups'][group] = {}
-
+
self.data['groups'][r.get('group')].update({'name': r.get('group')})
-
+
def get_group_resources(self, group):
return dict(filter(lambda t: t[1].get('group') == group, self.data['resources'].iteritems()))
-
+
def get_groups_resources(self):
for g in self.data['groups']:
yield g, self.get_group_resources(g)
-
+
def get_quota(self, group_quotas):
for r, v in group_quotas.iteritems():
rname = str(r)
quota = self.data['resources'].get(rname)
quota['value'] = v
yield quota
-
-
+
+
def get_policies(self, policies_data):
for policy in policies_data:
rname = '%s%s%s' % (policy.get('service'), RESOURCE_SEPARATOR, policy.get('resource'))
policy.update(self.data['resources'].get(rname))
yield policy
-
+
def __repr__(self):
return self.data.__repr__()
-
+
def __iter__(self, *args, **kwargs):
return self.data.__iter__(*args, **kwargs)
-
+
def __getitem__(self, *args, **kwargs):
return self.data.__getitem__(*args, **kwargs)
-
+
def get(self, *args, **kwargs):
return self.data.get(*args, **kwargs)
-
-
+
+
@require_http_methods(["GET", "POST"])
@signed_terms_required
@login_required
def group_add(request, kind_name='default'):
-
+
result = callpoint.list_resources()
resource_catalog = ResourcePresentation(RESOURCES_PRESENTATION_DATA)
resource_catalog.update_from_result(result)
-
+
if not result.is_success:
messages.error(
request,
'Unable to retrieve system resources: %s' % result.reason
)
-
+
try:
kind = GroupKind.objects.get(name=kind_name)
except:
return HttpResponseBadRequest(_(astakos_messages.GROUPKIND_UNKNOWN))
-
-
+
+
post_save_redirect = '/im/group/%(id)s/'
context_processors = None
model=None,
form_class=AstakosGroupCreationForm
)
-
+
if request.method == 'POST':
form = form_class(request.POST, request.FILES)
if form.is_valid():
+ policies = form.policies()
return render_response(
template='im/astakosgroup_form_summary.html',
context_instance=get_context(request),
- form = AstakosGroupCreationSummaryForm(form.cleaned_data),
- policies = resource_catalog.get_policies(form.policies()),
- resource_catalog= resource_catalog,
+ form=AstakosGroupCreationSummaryForm(form.cleaned_data),
+ policies=resource_catalog.get_policies(policies)
)
-
else:
now = datetime.now()
data = {
data['is_selected_%s' % group] = False
for resource in resources:
data['%s_uplimit' % resource] = ''
-
+
form = form_class(data)
# Create the template, context, response
msg = _(astakos_messages.OBJECT_CREATED) %\
{"verbose_name": model._meta.verbose_name}
messages.success(request, msg, fail_silently=True)
-
+
# send notification
try:
send_group_creation_notification(
else:
d = {"verbose_name": model._meta.verbose_name,
"reason":result.reason}
- msg = _(astakos_messages.OBJECT_CREATED_FAILED) % d
+ msg = _(astakos_messages.OBJECT_CREATED_FAILED) % d
messages.error(request, msg, fail_silently=True)
return render_response(
template='im/astakosgroup_form_summary.html',
context_instance=get_context(request),
- form=form)
+ form=form,
+ policies=form.cleaned_data.get('policies')
+ )
#@require_http_methods(["GET"])
@login_required
def group_list(request):
none = request.user.astakos_groups.none()
- sorting = request.GET.get('sorting')
query = """
SELECT auth_group.id,
- %s AS groupname,
+ auth_group.name AS groupname,
im_groupkind.name AS kindname,
im_astakosgroup.*,
owner.email AS groupowner,
(SELECT CASE WHEN(
SELECT date_joined FROM im_membership
WHERE group_id = im_astakosgroup.group_ptr_id
- AND person_id = %s) IS NULL
+ AND person_id = %(id)s) IS NULL
THEN 0 ELSE 1 END) AS membership_status
FROM im_astakosgroup
INNER JOIN im_membership ON (
im_astakosuser_owner.astakosgroup_id = im_astakosgroup.group_ptr_id)
LEFT JOIN auth_user as owner ON (
im_astakosuser_owner.astakosuser_id = owner.id)
- WHERE im_membership.person_id = %s
- """ % (DB_REPLACE_GROUP_SCHEME, request.user.id, request.user.id)
-
- if sorting:
- query = query+" ORDER BY %s ASC" %sorting
- else:
- query = query+" ORDER BY groupname ASC"
- q = AstakosGroup.objects.raw(query)
+ WHERE im_membership.person_id = %(id)s
+ AND im_groupkind.name != 'default'
+ """ % request.user.__dict__
-
-
+ # validate sorting
+ sorting = 'groupname'
+ sort_form = AstakosGroupSortForm(request.GET)
+ if sort_form.is_valid():
+ sorting = sort_form.cleaned_data.get('sorting')
+ query = query+" ORDER BY %s ASC" %sorting
+
+ q = AstakosGroup.objects.raw(query)
+
# Create the template, context, response
template_name = "%s/%s_list.html" % (
q.model._meta.app_label,
extra_context = dict(
is_search=False,
q=q,
- sorting=request.GET.get('sorting'),
+ sorting=sorting,
page=request.GET.get('page', 1)
)
return render_response(template_name,
}, context_processors)
# validate sorting
- sorting = request.GET.get('sorting')
- if sorting:
- form = MembersSortForm({'sort_by': sorting})
- if form.is_valid():
- sorting = form.cleaned_data.get('sort_by')
-
- else:
- form = MembersSortForm({'sort_by': 'person_first_name'})
+ sorting = 'person__email'
+ form = MembersSortForm(request.GET)
+ if form.is_valid():
+ sorting = form.cleaned_data.get('sorting')
result = callpoint.list_resources()
resource_catalog = ResourcePresentation(RESOURCES_PRESENTATION_DATA)
resource_catalog.update_from_result(result)
-
+
if not result.is_success:
messages.error(
request,
'Unable to retrieve system resources: %s' % result.reason
)
-
+
extra_context = {'update_form': update_form,
'addmembers_form': addmembers_form,
'page': request.GET.get('page', 1),
@login_required
def group_search(request, extra_context=None, **kwargs):
q = request.GET.get('q')
- sorting = request.GET.get('sorting')
if request.method == 'GET':
form = AstakosGroupSearchForm({'q': q} if q else None)
else:
form = AstakosGroupSearchForm(get_query(request))
if form.is_valid():
q = form.cleaned_data['q'].strip()
+
+ sorting = 'groupname'
if q:
queryset = AstakosGroup.objects.select_related()
+ queryset = queryset.filter(~Q(kind__name='default'))
queryset = queryset.filter(name__contains=q)
queryset = queryset.filter(approval_date__isnull=False)
queryset = queryset.extra(select={
- 'groupname': DB_REPLACE_GROUP_SCHEME,
+ 'groupname': "auth_group.name",
'kindname': "im_groupkind.name",
'approved_members_num': """
SELECT COUNT(*) FROM im_membership
SELECT id FROM im_astakosuser_owner
WHERE astakosgroup_id = im_astakosgroup.group_ptr_id
AND astakosuser_id = %s)
- THEN 1 ELSE 0 END""" % request.user.id,
+ THEN 1 ELSE 0 END""" % request.user.id,
})
- if sorting:
- # TODO check sorting value
- queryset = queryset.order_by(sorting)
- else:
- queryset = queryset.order_by("groupname")
+
+ # validate sorting
+ sort_form = AstakosGroupSortForm(request.GET)
+ if sort_form.is_valid():
+ sorting = sort_form.cleaned_data.get('sorting')
+ queryset = queryset.order_by(sorting)
else:
queryset = AstakosGroup.objects.none()
@login_required
def group_all(request, extra_context=None, **kwargs):
q = AstakosGroup.objects.select_related()
+ q = q.filter(~Q(kind__name='default'))
q = q.filter(approval_date__isnull=False)
q = q.extra(select={
- 'groupname': DB_REPLACE_GROUP_SCHEME,
+ 'groupname': "auth_group.name",
'kindname': "im_groupkind.name",
'approved_members_num': """
SELECT COUNT(*) FROM im_membership
WHERE astakosgroup_id = im_astakosgroup.group_ptr_id
AND astakosuser_id = %s)
THEN 1 ELSE 0 END""" % request.user.id, })
- sorting = request.GET.get('sorting')
- if sorting:
- # TODO check sorting value
- q = q.order_by(sorting)
- else:
- q = q.order_by("groupname")
-
+
+ # validate sorting
+ sorting = 'groupname'
+ sort_form = AstakosGroupSortForm(request.GET)
+ if sort_form.is_valid():
+ sorting = sort_form.cleaned_data.get('sorting')
+ q = q.order_by(sorting)
+
return object_list(
request,
q,
try:
membership.disapprove()
realname = membership.person.realname
- msg = astakos_messages.MEMBER_REMOVED % realname
+ msg = astakos_messages.MEMBER_REMOVED % locals()
messages.success(request, msg)
except BaseException, e:
logger.exception(e)
@require_http_methods(["POST", "GET"])
@signed_terms_required
@login_required
-def resource_list(request):
+def resource_usage(request):
def with_class(entry):
entry['load_class'] = 'red'
max_value = float(entry['maxValue'])
if max_value > 0 :
entry['ratio'] = (curr_value / max_value) * 100
else:
- entry['ratio'] = 0
+ entry['ratio'] = 0
if entry['ratio'] < 66:
entry['load_class'] = 'yellow'
if entry['ratio'] < 33:
entry['plural'] = engine.plural(entry.get('name'))
return entry
- result = callpoint.get_user_status(request.user.id)
+ result = callpoint.get_user_usage(request.user.id)
if result.is_success:
backenddata = map(with_class, result.data)
data = map(pluralize, result.data)
messages.error(request, result.reason)
resource_catalog = ResourcePresentation(RESOURCES_PRESENTATION_DATA)
resource_catalog.update_from_result_report(result)
-
-
-
- return render_response('im/resource_list.html',
+ return render_response('im/resource_usage.html',
data=data,
context_instance=get_context(request),
resource_catalog=resource_catalog,
context_instance=get_context(request),)
-#@require_http_methods(["GET"])
-@require_http_methods(["POST", "GET"])
-@signed_terms_required
-@login_required
-def billing(request):
-
- today = datetime.today()
- month_last_day = calendar.monthrange(today.year, today.month)[1]
- start = request.POST.get('datefrom', None)
- if start:
- today = datetime.fromtimestamp(int(start))
- month_last_day = calendar.monthrange(today.year, today.month)[1]
-
- start = datetime(today.year, today.month, 1).strftime("%s")
- end = datetime(today.year, today.month, month_last_day).strftime("%s")
- r = request_billing.apply(args=('pgerakios@grnet.gr',
- int(start) * 1000,
- int(end) * 1000))
- data = {}
-
- try:
- status, data = r.result
- data = _clear_billing_data(data)
- if status != 200:
- messages.error(request, _(astakos_messages.BILLING_ERROR) % status)
- except:
- messages.error(request, r.result)
-
- return render_response(
- template='im/billing.html',
- context_instance=get_context(request),
- data=data,
- zerodate=datetime(month=1, year=1970, day=1),
- today=today,
- start=int(start),
- month_last_day=month_last_day)
-
-
-def _clear_billing_data(data):
-
- # remove addcredits entries
- def isnotcredit(e):
- return e['serviceName'] != "addcredits"
+##@require_http_methods(["GET"])
+#@require_http_methods(["POST", "GET"])
+#@signed_terms_required
+#@login_required
+#def billing(request):
+#
+# today = datetime.today()
+# month_last_day = calendar.monthrange(today.year, today.month)[1]
+# start = request.POST.get('datefrom', None)
+# if start:
+# today = datetime.fromtimestamp(int(start))
+# month_last_day = calendar.monthrange(today.year, today.month)[1]
+#
+# start = datetime(today.year, today.month, 1).strftime("%s")
+# end = datetime(today.year, today.month, month_last_day).strftime("%s")
+# r = request_billing.apply(args=('pgerakios@grnet.gr',
+# int(start) * 1000,
+# int(end) * 1000))
+# data = {}
+#
+# try:
+# status, data = r.result
+# data = _clear_billing_data(data)
+# if status != 200:
+# messages.error(request, _(astakos_messages.BILLING_ERROR) % status)
+# except:
+# messages.error(request, r.result)
+#
+# return render_response(
+# template='im/billing.html',
+# context_instance=get_context(request),
+# data=data,
+# zerodate=datetime(month=1, year=1970, day=1),
+# today=today,
+# start=int(start),
+# month_last_day=month_last_day)
- # separate services
- def servicefilter(service_name):
- service = service_name
- def fltr(e):
- return e['serviceName'] == service
- return fltr
+#def _clear_billing_data(data):
+#
+# # remove addcredits entries
+# def isnotcredit(e):
+# return e['serviceName'] != "addcredits"
+#
+# # separate services
+# def servicefilter(service_name):
+# service = service_name
+#
+# def fltr(e):
+# return e['serviceName'] == service
+# return fltr
+#
+# data['bill_nocredits'] = filter(isnotcredit, data['bill'])
+# data['bill_vmtime'] = filter(servicefilter('vmtime'), data['bill'])
+# data['bill_diskspace'] = filter(servicefilter('diskspace'), data['bill'])
+# data['bill_addcredits'] = filter(servicefilter('addcredits'), data['bill'])
+#
+# return data
- data['bill_nocredits'] = filter(isnotcredit, data['bill'])
- data['bill_vmtime'] = filter(servicefilter('vmtime'), data['bill'])
- data['bill_diskspace'] = filter(servicefilter('diskspace'), data['bill'])
- data['bill_addcredits'] = filter(servicefilter('addcredits'), data['bill'])
- return data
-
-
#@require_http_methods(["GET"])
@require_http_methods(["POST", "GET"])
@signed_terms_required
timeline_header=timeline_header,
timeline_body=timeline_body)
return data
+
+
+# TODO: action only on POST and user should confirm the removal
+@require_http_methods(["GET", "POST"])
+@login_required
+@signed_terms_required
+def remove_auth_provider(request, pk):
+ try:
+ provider = request.user.auth_providers.get(pk=pk)
+ except AstakosUserAuthProvider.DoesNotExist:
+ raise Http404
+
+ if provider.can_remove():
+ provider.delete()
+ return HttpResponseRedirect(reverse('edit_profile'))
+ else:
+ raise PermissionDenied
+
+
+def how_it_works(request):
+ return render_response(
+ template='im/how_it_works.html',
+ context_instance=get_context(request),)
+