Revision ff67242a

b/snf-astakos-app/astakos/im/forms.py
67 67
    PROJECT_MEMBER_LEAVE_POLICIES, EMAILCHANGE_ENABLED)
68 68
from astakos.im.widgets import DummyWidget, RecaptchaWidget
69 69
from astakos.im.functions import (
70
    send_change_email, submit_application, do_accept_membership_checks)
70
    send_change_email, submit_application, accept_membership_checks)
71 71

  
72 72
from astakos.im.util import reserved_email, reserved_verified_email, \
73 73
                            get_query, model_to_dict
......
877 877
        help_text=_(astakos_messages.ADD_PROJECT_MEMBERS_Q_HELP), required=True)
878 878

  
879 879
    def __init__(self, *args, **kwargs):
880
        application_id = kwargs.pop('application_id', None)
881
        if application_id:
882
            self.project = Project.objects.get(application__id=application_id)
880
        chain_id = kwargs.pop('chain_id', None)
881
        if chain_id:
882
            self.project = Project.objects.get(id=chain_id)
883 883
        self.request_user = kwargs.pop('request_user', None)
884 884
        super(AddProjectMembersForm, self).__init__(*args, **kwargs)
885 885

  
886 886
    def clean(self):
887 887
        try:
888
            do_accept_membership_checks(self.project, self.request_user)
888
            accept_membership_checks(self.project, self.request_user)
889 889
        except PermissionDenied, e:
890 890
            raise forms.ValidationError(e)
891 891

  
b/snf-astakos-app/astakos/im/functions.py
46 46
from django.contrib.auth.models import AnonymousUser
47 47
from django.core.exceptions import PermissionDenied
48 48
from django.db import IntegrityError
49
from django.http import Http404
49 50

  
50 51
from urllib import quote
51 52
from urlparse import urljoin
......
494 495
        raise PermissionDenied(
495 496
            _(astakos_messages.NOT_ALIVE_PROJECT) % project.__dict__)
496 497

  
497
def accept_membership(project_application_id, user, request_user=None):
498
    """
499
        Raises:
500
            django.core.exceptions.PermissionDenied
501
            IOError
502
    """
503
    project_id = get_project_id_of_application_id(project_application_id)
504
    return do_accept_membership(project_id, user, request_user)
505

  
506
def do_accept_membership_checks(project, request_user):
498
def accept_membership_checks(project, request_user):
507 499
    checkAllowed(project, request_user)
508 500
    checkAlive(project)
509 501

  
......
514 506
    if project.violates_members_limit(adding=1):
515 507
        raise PermissionDenied(_(astakos_messages.MEMBER_NUMBER_LIMIT_REACHED))
516 508

  
517
def do_accept_membership(project_id, user, request_user=None):
509
def accept_membership(project_id, user, request_user=None):
518 510
    project = get_project_for_update(project_id)
519
    do_accept_membership_checks(project, request_user)
511
    accept_membership_checks(project, request_user)
520 512

  
521 513
    membership = get_membership_for_update(project, user)
522 514
    if not membership.can_accept():
......
530 522

  
531 523
    return membership
532 524

  
533
def reject_membership(project_application_id, user, request_user=None):
534
    """
535
        Raises:
536
            django.core.exceptions.PermissionDenied
537
            IOError
538
    """
539
    project_id = get_project_id_of_application_id(project_application_id)
540
    return do_reject_membership(project_id, user, request_user)
541

  
542
def do_reject_membership_checks(project, request_user):
525
def reject_membership_checks(project, request_user):
543 526
    checkAllowed(project, request_user)
544 527
    checkAlive(project)
545 528

  
546
def do_reject_membership(project_id, user, request_user=None):
529
def reject_membership(project_id, user, request_user=None):
547 530
    project = get_project_for_update(project_id)
548
    do_reject_membership_checks(project, request_user)
531
    reject_membership_checks(project, request_user)
549 532
    membership = get_membership_for_update(project, user)
550 533
    if not membership.can_reject():
551 534
        m = _(astakos_messages.NOT_MEMBERSHIP_REQUEST)
......
557 540

  
558 541
    return membership
559 542

  
560
def remove_membership(project_application_id, user, request_user=None):
561
    """
562
        Raises:
563
            django.core.exceptions.PermissionDenied
564
            IOError
565
    """
566
    project_id = get_project_id_of_application_id(project_application_id)
567
    return do_remove_membership(project_id, user, request_user)
568

  
569
def do_remove_membership_checks(project, request_user=None):
543
def remove_membership_checks(project, request_user=None):
570 544
    checkAllowed(project, request_user)
571 545
    checkAlive(project)
572 546

  
......
574 548
    if leave_policy == CLOSED_POLICY:
575 549
        raise PermissionDenied(_(astakos_messages.MEMBER_LEAVE_POLICY_CLOSED))
576 550

  
577
def do_remove_membership(project_id, user, request_user=None):
551
def remove_membership(project_id, user, request_user=None):
578 552
    project = get_project_for_update(project_id)
579
    do_remove_membership_checks(project, request_user)
553
    remove_membership_checks(project, request_user)
580 554
    membership = get_membership_for_update(project, user)
581 555
    if not membership.can_remove():
582 556
        m = _(astakos_messages.NOT_ACCEPTED_MEMBERSHIP)
......
589 563

  
590 564
    return membership
591 565

  
592
def enroll_member(project_application_id, user, request_user=None):
593
    project_id = get_project_id_of_application_id(project_application_id)
594
    return do_enroll_member(project_id, user, request_user)
595

  
596
def do_enroll_member(project_id, user, request_user=None):
566
def enroll_member(project_id, user, request_user=None):
597 567
    project = get_project_for_update(project_id)
598
    do_accept_membership_checks(project, request_user)
568
    accept_membership_checks(project, request_user)
599 569
    membership = create_membership(project_id, user)
600 570

  
601 571
    if not membership.can_accept():
......
608 578
    # TODO send proper notification
609 579
    return membership
610 580

  
611
def leave_project(project_application_id, user_id):
612
    """
613
        Raises:
614
            django.core.exceptions.PermissionDenied
615
            IOError
616
    """
617
    project_id = get_project_id_of_application_id(project_application_id)
618
    return do_leave_project(project_id, user_id)
619

  
620
def do_leave_project_checks(project):
581
def leave_project_checks(project):
621 582
    checkAlive(project)
622 583

  
623 584
    leave_policy = project.application.member_leave_policy
624 585
    if leave_policy == CLOSED_POLICY:
625 586
        raise PermissionDenied(_(astakos_messages.MEMBER_LEAVE_POLICY_CLOSED))
626 587

  
627
def do_leave_project(project_id, user_id):
588
def leave_project(project_id, user_id):
628 589
    project = get_project_for_update(project_id)
629
    do_leave_project_checks(project)
590
    leave_project_checks(project)
630 591
    membership = get_membership_for_update(project, user_id)
631 592
    if not membership.can_leave():
632 593
        m = _(astakos_messages.NOT_ACCEPTED_MEMBERSHIP)
......
641 602
        membership.save()
642 603
    return membership
643 604

  
644
def join_project(project_application_id, user_id):
645
    """
646
        Raises:
647
            django.core.exceptions.PermissionDenied
648
            IOError
649
    """
650
    project_id = get_project_id_of_application_id(project_application_id)
651
    return do_join_project(project_id, user_id)
652

  
653
def do_join_project_checks(project):
605
def join_project_checks(project):
654 606
    checkAlive(project)
655 607

  
656 608
    join_policy = project.application.member_join_policy
657 609
    if join_policy == CLOSED_POLICY:
658 610
        raise PermissionDenied(_(astakos_messages.MEMBER_JOIN_POLICY_CLOSED))
659 611

  
660
def do_join_project(project_id, user_id):
612
def join_project(project_id, user_id):
661 613
    project = get_project_for_update(project_id)
662
    do_join_project_checks(project)
614
    join_project_checks(project)
663 615
    membership = create_membership(project, user_id)
664 616

  
665 617
    join_policy = project.application.member_join_policy
......
778 730

  
779 731
    project.resume()
780 732
    sync_projects()
733

  
734
def get_by_chain_or_404(chain_id):
735
    try:
736
        project = Project.objects.get(id=chain_id)
737
        application = project.application
738
        return project, application
739
    except:
740
        application = ProjectApplication.objects.latest_of_chain(chain_id)
741
        if application is None:
742
            raise Http404
743
        else:
744
            return None, application
b/snf-astakos-app/astakos/im/models.py
1249 1249
            q = q | Q(name__icontains=s)
1250 1250
        return self.filter(q)
1251 1251

  
1252
    def latest_of_chain(self, chain_id):
1253
        try:
1254
            return self.filter(chain=chain_id).order_by('-id')[0]
1255
        except IndexError:
1256
            return None
1252 1257

  
1253 1258
USER_STATUS_DISPLAY = {
1254 1259
      0: _('Join requested'),
b/snf-astakos-app/astakos/im/tables.py
44 44

  
45 45
from astakos.im.models import *
46 46
from astakos.im.templatetags.filters import truncatename
47
from astakos.im.functions import do_join_project_checks, \
48
                                 do_leave_project_checks
47
from astakos.im.functions import join_project_checks, \
48
                                 leave_project_checks
49 49

  
50 50
DEFAULT_DATE_FORMAT = "d/m/Y"
51 51

  
......
190 190

  
191 191
    if project:
192 192
        try:
193
            do_join_project_checks(project)
193
            join_project_checks(project)
194 194
            can_join = True
195 195
        except PermissionDenied, e:
196 196
            pass
197 197

  
198 198
        try:
199
            do_leave_project_checks(project)
199
            leave_project_checks(project)
200 200
            can_leave = True
201 201
        except PermissionDenied:
202 202
            pass
b/snf-astakos-app/astakos/im/urls.py
62 62
    url(r'^projects/update/(?P<application_id>\d+)/?$', 'project_update', {}, name='project_update'),
63 63
    url(r'^projects/?$', 'project_list', {}, name='project_list'),
64 64
    url(r'^projects/search/?$', 'project_search', {}, name='project_search'),
65
    url(r'^projects/(?P<application_id>\d+)/?$', 'project_detail', {}, name='project_detail'),
66
    url(r'^projects/(?P<application_id>\d+)/join/?$', 'project_join', {}, name='project_join'),
67
    url(r'^projects/(?P<application_id>\d+)/leave/?$', 'project_leave', {}, name='project_leave'),
68
    url(r'^projects/(?P<application_id>\d+)/(?P<user_id>\d+)/accept/?$', 'project_accept_member', {}, name='project_accept_member'),
69
    url(r'^projects/(?P<application_id>\d+)/(?P<user_id>\d+)/reject/?$', 'project_reject_member', {}, name='project_reject_member'),
70
    url(r'^projects/(?P<application_id>\d+)/(?P<user_id>\d+)/remove/?$', 'project_remove_member', {}, name='project_remove_member'),
65
    url(r'^projects/(?P<chain_id>\d+)/?$', 'project_detail', {}, name='project_detail'),
66
    url(r'^projects/(?P<chain_id>\d+)/join/?$', 'project_join', {}, name='project_join'),
67
    url(r'^projects/(?P<chain_id>\d+)/leave/?$', 'project_leave', {}, name='project_leave'),
68
    url(r'^projects/(?P<chain_id>\d+)/(?P<user_id>\d+)/accept/?$', 'project_accept_member', {}, name='project_accept_member'),
69
    url(r'^projects/(?P<chain_id>\d+)/(?P<user_id>\d+)/reject/?$', 'project_reject_member', {}, name='project_reject_member'),
70
    url(r'^projects/(?P<chain_id>\d+)/(?P<user_id>\d+)/remove/?$', 'project_remove_member', {}, name='project_remove_member'),
71 71

  
72 72
    url(r'^projects/how_it_works/?$', 'how_it_works', {}, name='how_it_works'),
73 73
    url(r'^remove_auth_provider/(?P<pk>\d+)?$', 'remove_auth_provider', {}, name='remove_auth_provider'),
b/snf-astakos-app/astakos/im/views.py
96 96
    send_activation as send_activation_func,
97 97
    SendNotificationError,
98 98
    accept_membership, reject_membership, remove_membership,
99
    leave_project, join_project, enroll_member)
99
    leave_project, join_project, enroll_member,
100
    get_by_chain_or_404)
100 101
from astakos.im.settings import (
101 102
    COOKIE_DOMAIN, LOGOUT_NEXT,
102 103
    LOGGING_LEVEL, PAGINATE_BY,
......
1132 1133
@signed_terms_required
1133 1134
@login_required
1134 1135
@transaction.commit_on_success
1135
def project_detail(request, application_id):
1136
def project_detail(request, chain_id):
1136 1137
    addmembers_form = AddProjectMembersForm()
1137 1138
    if request.method == 'POST':
1138 1139
        addmembers_form = AddProjectMembersForm(
1139 1140
            request.POST,
1140
            application_id=int(application_id),
1141
            chain_id=int(chain_id),
1141 1142
            request_user=request.user)
1142 1143
        if addmembers_form.is_valid():
1143 1144
            try:
1144 1145
                rollback = False
1145
                application_id = int(application_id)
1146
                chain_id = int(chain_id)
1146 1147
                map(lambda u: enroll_member(
1147
                        application_id,
1148
                        chain_id,
1148 1149
                        u,
1149 1150
                        request_user=request.user),
1150 1151
                    addmembers_form.valid_users)
......
1162 1163

  
1163 1164
    rollback = False
1164 1165

  
1165
    application = get_object_or_404(ProjectApplication, pk=application_id)
1166
    try:
1167
        members = application.project.projectmembership_set.select_related()
1168
    except Project.DoesNotExist:
1166
    project, application = get_by_chain_or_404(chain_id)
1167
    if project:
1168
        members = project.projectmembership_set.select_related()
1169
    else:
1169 1170
        members = ProjectMembership.objects.none()
1170 1171

  
1171 1172
    members_table = tables.ProjectApplicationMembersTable(application,
......
1186 1187
    return object_detail(
1187 1188
        request,
1188 1189
        queryset=ProjectApplication.objects.select_related(),
1189
        object_id=application_id,
1190
        object_id=application.id,
1190 1191
        template_name='im/projects/project_detail.html',
1191 1192
        extra_context={
1192 1193
            'addmembers_form':addmembers_form,
......
1239 1240
@signed_terms_required
1240 1241
@login_required
1241 1242
@transaction.commit_manually
1242
def project_join(request, application_id):
1243
def project_join(request, chain_id):
1243 1244
    next = request.GET.get('next')
1244 1245
    if not next:
1245 1246
        next = reverse('astakos.im.views.project_detail',
1246
                       args=(application_id,))
1247
                       args=(chain_id,))
1247 1248

  
1248 1249
    rollback = False
1249 1250
    try:
1250
        application_id = int(application_id)
1251
        join_project(application_id, request.user)
1251
        chain_id = int(chain_id)
1252
        join_project(chain_id, request.user)
1252 1253
        # TODO: distinct messages for request/auto accept ???
1253 1254
        messages.success(request, _(astakos_messages.USER_JOIN_REQUEST_SUBMITED))
1254 1255
    except (IOError, PermissionDenied), e:
......
1269 1270
@signed_terms_required
1270 1271
@login_required
1271 1272
@transaction.commit_manually
1272
def project_leave(request, application_id):
1273
def project_leave(request, chain_id):
1273 1274
    next = request.GET.get('next')
1274 1275
    if not next:
1275 1276
        next = reverse('astakos.im.views.project_list')
1276 1277

  
1277 1278
    rollback = False
1278 1279
    try:
1279
        application_id = int(application_id)
1280
        leave_project(application_id, request.user)
1280
        chain_id = int(chain_id)
1281
        leave_project(chain_id, request.user)
1281 1282
    except (IOError, PermissionDenied), e:
1282 1283
        messages.error(request, e)
1283 1284
    except BaseException, e:
......
1297 1298
@signed_terms_required
1298 1299
@login_required
1299 1300
@transaction.commit_manually
1300
def project_accept_member(request, application_id, user_id):
1301
def project_accept_member(request, chain_id, user_id):
1301 1302
    rollback = False
1302 1303
    try:
1303
        application_id = int(application_id)
1304
        chain_id = int(chain_id)
1304 1305
        user_id = int(user_id)
1305
        m = accept_membership(application_id, user_id, request.user)
1306
        m = accept_membership(chain_id, user_id, request.user)
1306 1307
    except (IOError, PermissionDenied), e:
1307 1308
        messages.error(request, e)
1308 1309
    except BaseException, e:
......
1318 1319
            transaction.rollback()
1319 1320
        else:
1320 1321
            transaction.commit()
1321
    return redirect(reverse('project_detail', args=(application_id,)))
1322
    return redirect(reverse('project_detail', args=(chain_id,)))
1322 1323

  
1323 1324
@require_http_methods(["POST"])
1324 1325
@signed_terms_required
1325 1326
@login_required
1326 1327
@transaction.commit_manually
1327
def project_remove_member(request, application_id, user_id):
1328
def project_remove_member(request, chain_id, user_id):
1328 1329
    rollback = False
1329 1330
    try:
1330
        application_id = int(application_id)
1331
        chain_id = int(chain_id)
1331 1332
        user_id = int(user_id)
1332
        m = remove_membership(application_id, user_id, request.user)
1333
        m = remove_membership(chain_id, user_id, request.user)
1333 1334
    except (IOError, PermissionDenied), e:
1334 1335
        messages.error(request, e)
1335 1336
    except BaseException, e:
......
1345 1346
            transaction.rollback()
1346 1347
        else:
1347 1348
            transaction.commit()
1348
    return redirect(reverse('project_detail', args=(application_id,)))
1349
    return redirect(reverse('project_detail', args=(chain_id,)))
1349 1350

  
1350 1351
@require_http_methods(["POST"])
1351 1352
@signed_terms_required
1352 1353
@login_required
1353 1354
@transaction.commit_manually
1354
def project_reject_member(request, application_id, user_id):
1355
def project_reject_member(request, chain_id, user_id):
1355 1356
    rollback = False
1356 1357
    try:
1357
        application_id = int(application_id)
1358
        chain_id = int(chain_id)
1358 1359
        user_id = int(user_id)
1359
        m = reject_membership(application_id, user_id, request.user)
1360
        m = reject_membership(chain_id, user_id, request.user)
1360 1361
    except (IOError, PermissionDenied), e:
1361 1362
        messages.error(request, e)
1362 1363
    except BaseException, e:
......
1372 1373
            transaction.rollback()
1373 1374
        else:
1374 1375
            transaction.commit()
1375
    return redirect(reverse('project_detail', args=(application_id,)))
1376
    return redirect(reverse('project_detail', args=(chain_id,)))
1376 1377

  
1377 1378
def landing(request):
1378 1379
    return render_response(
1379 1380
        'im/landing.html',
1380
        context_instance=get_context(request))
1381
        context_instance=get_context(request))

Also available in: Unified diff