29 '"Lennard de Rijk" <ljvderijk@gmail.com>', |
29 '"Lennard de Rijk" <ljvderijk@gmail.com>', |
30 '"Pawel Solyga" <pawel.solyga@gmail.com>', |
30 '"Pawel Solyga" <pawel.solyga@gmail.com>', |
31 ] |
31 ] |
32 |
32 |
33 |
33 |
34 from google.appengine.api import users |
|
35 from google.appengine.api import memcache |
34 from google.appengine.api import memcache |
36 |
35 |
37 from django.core import urlresolvers |
|
38 from django.utils.translation import ugettext |
36 from django.utils.translation import ugettext |
39 |
37 |
40 from soc.logic import accounts |
|
41 from soc.logic import dicts |
38 from soc.logic import dicts |
42 from soc.logic import rights as rights_logic |
39 from soc.logic import rights as rights_logic |
43 from soc.logic.helper import timeline as timeline_helper |
40 from soc.logic.helper import timeline as timeline_helper |
44 from soc.logic.models.club_admin import logic as club_admin_logic |
41 from soc.logic.models.club_admin import logic as club_admin_logic |
45 from soc.logic.models.club_member import logic as club_member_logic |
42 from soc.logic.models.club_member import logic as club_member_logic |
46 from soc.logic.models.document import logic as document_logic |
43 from soc.logic.models.document import logic as document_logic |
47 from soc.logic.models.host import logic as host_logic |
44 from soc.logic.models.host import logic as host_logic |
48 from soc.logic.models.mentor import logic as mentor_logic |
45 from soc.logic.models.mentor import logic as mentor_logic |
49 from soc.logic.models.notification import logic as notification_logic |
|
50 from soc.logic.models.org_admin import logic as org_admin_logic |
46 from soc.logic.models.org_admin import logic as org_admin_logic |
51 from soc.logic.models.organization import logic as org_logic |
47 from soc.logic.models.organization import logic as org_logic |
52 from soc.logic.models.program import logic as program_logic |
48 from soc.logic.models.program import logic as program_logic |
53 from soc.logic.models.request import logic as request_logic |
49 from soc.logic.models.request import logic as request_logic |
54 from soc.logic.models.role import logic as role_logic |
50 from soc.logic.models.role import logic as role_logic |
57 from soc.logic.models.student import logic as student_logic |
53 from soc.logic.models.student import logic as student_logic |
58 from soc.logic.models.student_proposal import logic as student_proposal_logic |
54 from soc.logic.models.student_proposal import logic as student_proposal_logic |
59 from soc.logic.models.timeline import logic as timeline_logic |
55 from soc.logic.models.timeline import logic as timeline_logic |
60 from soc.logic.models.user import logic as user_logic |
56 from soc.logic.models.user import logic as user_logic |
61 from soc.views.helper import redirects |
57 from soc.views.helper import redirects |
62 from soc.views import helper |
|
63 from soc.views import out_of_band |
58 from soc.views import out_of_band |
64 |
59 |
65 |
60 |
66 DEF_NO_USER_LOGIN_MSG= ugettext( |
61 DEF_NO_USER_LOGIN_MSG = ugettext( |
67 'Please create <a href="/user/create_profile">User Profile</a>' |
62 'Please create <a href="/user/create_profile">User Profile</a>' |
68 ' in order to view this page.') |
63 ' in order to view this page.') |
69 |
64 |
70 DEF_AGREE_TO_TOS_MSG_FMT = ugettext( |
65 DEF_AGREE_TO_TOS_MSG_FMT = ugettext( |
71 'You must agree to the <a href="%(tos_link)s">site-wide Terms of' |
66 'You must agree to the <a href="%(tos_link)s">site-wide Terms of' |
114 'There is no application that would allow you to visit this page.') |
109 'There is no application that would allow you to visit this page.') |
115 |
110 |
116 DEF_NEED_PICK_ARGS_MSG = ugettext( |
111 DEF_NEED_PICK_ARGS_MSG = ugettext( |
117 'The "continue" and "field" args are not both present.') |
112 'The "continue" and "field" args are not both present.') |
118 |
113 |
119 DEF_REVIEW_COMPLETED_MSG = ugettext( |
114 DEF_REVIEW_COMPLETED_MSG = ugettext('This Application can not be reviewed ' |
120 'This Application can not be reviewed anymore (it has been completed or rejected).') |
115 'anymore (it has been completed or rejected).') |
121 |
116 |
122 DEF_REQUEST_COMPLETED_MSG = ugettext( |
117 DEF_REQUEST_COMPLETED_MSG = ugettext( |
123 'This request cannot be accepted (it is either completed or denied).') |
118 'This request cannot be accepted (it is either completed or denied).') |
124 |
119 |
125 DEF_SCOPE_INACTIVE_MSG = ugettext( |
120 DEF_SCOPE_INACTIVE_MSG = ugettext( |
126 'The scope for this request is not active.') |
121 'The scope for this request is not active.') |
127 |
122 |
128 DEF_SIGN_UP_AS_STUDENT_MSG = ugettext( |
123 DEF_SIGN_UP_AS_STUDENT_MSG = ugettext( |
129 'You need to sign up as a Student first.') |
124 'You need to sign up as a Student first.') |
130 |
125 |
131 DEF_NO_LIST_ACCESS_MSG = ugettext( |
126 DEF_NO_LIST_ACCESS_MSG = ugettext('You do not have the required rights to ' |
132 'You do not have the required rights to list documents for this scope and prefix.') |
127 'list documents for this scope and prefix.') |
133 |
128 |
134 DEF_PAGE_DENIED_MSG = ugettext( |
129 DEF_PAGE_DENIED_MSG = ugettext( |
135 'Access to this page has been restricted.') |
130 'Access to this page has been restricted.') |
136 |
131 |
137 DEF_PREFIX_NOT_IN_ARGS_MSG = ugettext( |
132 DEF_PREFIX_NOT_IN_ARGS_MSG = ugettext( |
444 for checker_name, args in checks: |
439 for checker_name, args in checks: |
445 try: |
440 try: |
446 self.doCheck(checker_name, django_args, args) |
441 self.doCheck(checker_name, django_args, args) |
447 # one check passed, all is well |
442 # one check passed, all is well |
448 return |
443 return |
449 except out_of_band.Error, e: |
444 except out_of_band.Error, exception: |
450 # store the first esception |
445 # store the first esception |
451 first = first if first else e |
446 first = first if first else exception |
452 |
447 |
453 # none passed, re-raise the first exception |
448 # none passed, re-raise the first exception |
454 raise first |
449 raise first |
455 |
450 |
456 def allow(self, django_args): |
451 def allow(self, django_args): |
667 def checkGroupIsActiveForScopeAndLinkId(self, django_args, logic): |
662 def checkGroupIsActiveForScopeAndLinkId(self, django_args, logic): |
668 """Checks that the specified group is active. |
663 """Checks that the specified group is active. |
669 |
664 |
670 Only group where both the link_id and the scope_path match the value |
665 Only group where both the link_id and the scope_path match the value |
671 of the link_id and the scope_path from the django_args are considered. |
666 of the link_id and the scope_path from the django_args are considered. |
|
667 |
|
668 Args: |
|
669 django_args: a dictionary with django's arguments |
|
670 logic: the logic that should be used to look up the entity |
672 """ |
671 """ |
673 |
672 |
674 fields = ['scope_path', 'link_id'] |
673 fields = ['scope_path', 'link_id'] |
675 self._checkIsActive(django_args, logic, fields) |
674 self._checkIsActive(django_args, logic, fields) |
676 |
675 |
677 def checkGroupIsActiveForLinkId(self, django_args, logic): |
676 def checkGroupIsActiveForLinkId(self, django_args, logic): |
678 """Checks that the specified group is active. |
677 """Checks that the specified group is active. |
679 |
678 |
680 Only group where the link_id matches the value of the link_id |
679 Only group where the link_id matches the value of the link_id |
681 from the django_args are considered. |
680 from the django_args are considered. |
|
681 |
|
682 Args: |
|
683 django_args: a dictionary with django's arguments |
|
684 logic: the logic that should be used to look up the entity |
682 """ |
685 """ |
683 |
686 |
684 self._checkIsActive(django_args, logic, ['link_id']) |
687 self._checkIsActive(django_args, logic, ['link_id']) |
685 |
688 |
686 def checkHasActiveRole(self, django_args, logic): |
689 def checkHasActiveRole(self, django_args, logic): |
687 """Checks that the user has the specified active role. |
690 """Checks that the user has the specified active role. |
|
691 |
|
692 Args: |
|
693 django_args: a dictionary with django's arguments |
|
694 logic: the logic that should be used to look up the entity |
688 """ |
695 """ |
689 |
696 |
690 django_args = django_args.copy() |
697 django_args = django_args.copy() |
691 django_args['user'] = self.user |
698 django_args['user'] = self.user |
692 self._checkIsActive(django_args, logic, ['user']) |
699 self._checkIsActive(django_args, logic, ['user']) |
694 def _checkHasActiveRoleFor(self, django_args, logic, field_name): |
701 def _checkHasActiveRoleFor(self, django_args, logic, field_name): |
695 """Checks that the user has the specified active role. |
702 """Checks that the user has the specified active role. |
696 |
703 |
697 Only roles where the field as specified by field_name matches the |
704 Only roles where the field as specified by field_name matches the |
698 scope_path from the django_args are considered. |
705 scope_path from the django_args are considered. |
|
706 |
|
707 Args: |
|
708 django_args: a dictionary with django's arguments |
|
709 logic: the logic that should be used to look up the entity |
699 """ |
710 """ |
700 |
711 |
701 fields = [field_name, 'user'] |
712 fields = [field_name, 'user'] |
702 django_args = django_args.copy() |
713 django_args = django_args.copy() |
703 django_args['user'] = self.user |
714 django_args['user'] = self.user |
714 def checkHasActiveRoleForScope(self, django_args, logic): |
725 def checkHasActiveRoleForScope(self, django_args, logic): |
715 """Checks that the user has the specified active role. |
726 """Checks that the user has the specified active role. |
716 |
727 |
717 Only roles where the scope_path matches the scope_path from the |
728 Only roles where the scope_path matches the scope_path from the |
718 django_args are considered. |
729 django_args are considered. |
|
730 |
|
731 Args: |
|
732 django_args: a dictionary with django's arguments |
|
733 logic: the logic that should be used to look up the entity |
719 """ |
734 """ |
720 |
735 |
721 self._checkHasActiveRoleFor(django_args, logic, 'scope_path') |
736 self._checkHasActiveRoleFor(django_args, logic, 'scope_path') |
722 |
737 |
723 def checkHasActiveRoleForLinkId(self, django_args, logic): |
738 def checkHasActiveRoleForLinkId(self, django_args, logic): |
724 """Checks that the user has the specified active role. |
739 """Checks that the user has the specified active role. |
725 |
740 |
726 Only roles where the link_id matches the link_id from the |
741 Only roles where the link_id matches the link_id from the |
727 django_args are considered. |
742 django_args are considered. |
|
743 |
|
744 Args: |
|
745 django_args: a dictionary with django's arguments |
|
746 logic: the logic that should be used to look up the entity |
728 """ |
747 """ |
729 |
748 |
730 self._checkHasActiveRoleFor(django_args, logic, 'link_id') |
749 self._checkHasActiveRoleFor(django_args, logic, 'link_id') |
731 |
750 |
732 def checkHasActiveRoleForLinkIdAsScope(self, django_args, logic): |
751 def checkHasActiveRoleForLinkIdAsScope(self, django_args, logic): |
733 """Checks that the user has the specified active role. |
752 """Checks that the user has the specified active role. |
734 |
753 |
735 Only roles where the scope_path matches the link_id from the |
754 Only roles where the scope_path matches the link_id from the |
736 django_args are considered. |
755 django_args are considered. |
|
756 |
|
757 Args: |
|
758 django_args: a dictionary with django's arguments |
|
759 logic: the logic that should be used to look up the entity |
737 """ |
760 """ |
738 |
761 |
739 django_args = django_args.copy() |
762 django_args = django_args.copy() |
740 django_args['scope_path'] = django_args['link_id'] |
763 django_args['scope_path'] = django_args['link_id'] |
741 self._checkHasActiveRoleFor(django_args, logic, 'scope_path') |
764 self._checkHasActiveRoleFor(django_args, logic, 'scope_path') |
742 |
765 |
743 def checkHasDocumentAccess(self, django_args, logic, target_scope): |
766 def checkHasDocumentAccess(self, django_args, logic, target_scope): |
744 """Checks that the user has access to the specified document scope. |
767 """Checks that the user has access to the specified document scope. |
|
768 |
|
769 Args: |
|
770 django_args: a dictionary with django's arguments |
|
771 logic: the logic that should be used to look up the entity |
745 """ |
772 """ |
746 |
773 |
747 prefix = django_args['prefix'] |
774 prefix = django_args['prefix'] |
748 if self.SCOPE_DEPTH.get(prefix): |
775 if self.SCOPE_DEPTH.get(prefix): |
749 scope_logic, depths = self.SCOPE_DEPTH[prefix] |
776 scope_logic, depths = self.SCOPE_DEPTH[prefix] |
804 |
832 |
805 def checkCanCreateFromRequest(self, django_args, role_name): |
833 def checkCanCreateFromRequest(self, django_args, role_name): |
806 """Raises an alternate HTTP response if the specified request does not exist |
834 """Raises an alternate HTTP response if the specified request does not exist |
807 or if it's status is not group_accepted. Also when the group this request |
835 or if it's status is not group_accepted. Also when the group this request |
808 is from is in an inactive or invalid status access will be denied. |
836 is from is in an inactive or invalid status access will be denied. |
|
837 |
|
838 Args: |
|
839 django_args: a dictionary with django's arguments |
|
840 role_name: name of the role |
809 """ |
841 """ |
810 |
842 |
811 self.checkIsUserSelf(django_args, 'link_id') |
843 self.checkIsUserSelf(django_args, 'link_id') |
812 |
844 |
813 fields = { |
845 fields = { |
824 |
856 |
825 raise out_of_band.AccessViolation(message_fmt=DEF_NO_REQUEST_MSG) |
857 raise out_of_band.AccessViolation(message_fmt=DEF_NO_REQUEST_MSG) |
826 |
858 |
827 def checkIsMyGroupAcceptedRequest(self, django_args): |
859 def checkIsMyGroupAcceptedRequest(self, django_args): |
828 """Checks whether the user can accept the specified request. |
860 """Checks whether the user can accept the specified request. |
|
861 |
|
862 Args: |
|
863 django_args: a dictionary with django's arguments |
829 """ |
864 """ |
830 |
865 |
831 self.checkCanCreateFromRequest(django_args, django_args['role']) |
866 self.checkCanCreateFromRequest(django_args, django_args['role']) |
832 |
867 |
833 def checkCanProcessRequest(self, django_args, role_name): |
868 def checkCanProcessRequest(self, django_args, role_name): |
834 """Raises an alternate HTTP response if the specified request does not exist |
869 """Raises an alternate HTTP response if the specified request does not exist |
835 or if it's status is completed or denied. Also Raises an alternate HTTP response |
870 or if it's status is completed or denied. Also Raises an alternate HTTP response |
836 whenever the group in the request is not active. |
871 whenever the group in the request is not active. |
|
872 |
|
873 Args: |
|
874 django_args: a dictionary with django's arguments |
|
875 role_name: name of the role |
837 """ |
876 """ |
838 |
877 |
839 self.checkIsUser(django_args) |
878 self.checkIsUser(django_args) |
840 |
879 |
841 fields = { |
880 fields = { |
886 @denySidebar |
931 @denySidebar |
887 def checkIsActivePeriod(self, django_args, period_name, key_name_arg): |
932 def checkIsActivePeriod(self, django_args, period_name, key_name_arg): |
888 """Checks if the given period is active for the given program. |
933 """Checks if the given period is active for the given program. |
889 |
934 |
890 Args: |
935 Args: |
891 django_args: a dictionary with django's arguments. |
936 django_args: a dictionary with django's arguments |
892 period_name: the name of the period which is checked. |
937 period_name: the name of the period which is checked |
893 key_name_arg: the entry in django_args that specifies the given program |
938 key_name_arg: the entry in django_args that specifies the given program |
894 keyname. If none is given the key_name is constructed from django_args |
939 keyname. If none is given the key_name is constructed from django_args |
895 itself. |
940 itself. |
896 |
941 |
897 Raises: |
942 Raises: |
916 |
961 |
917 raise out_of_band.AccessViolation(message_fmt=DEF_PAGE_INACTIVE_MSG) |
962 raise out_of_band.AccessViolation(message_fmt=DEF_PAGE_INACTIVE_MSG) |
918 |
963 |
919 def checkCanCreateOrgApp(self, django_args, period_name): |
964 def checkCanCreateOrgApp(self, django_args, period_name): |
920 """Checks to see if the program in the scope_path is accepting org apps |
965 """Checks to see if the program in the scope_path is accepting org apps |
|
966 |
|
967 Args: |
|
968 django_args: a dictionary with django's arguments |
|
969 period_name: the name of the period which is checked |
921 """ |
970 """ |
922 |
971 |
923 if 'seed' in django_args: |
972 if 'seed' in django_args: |
924 return self.checkIsActivePeriod(django_args['seed'], |
973 return self.checkIsActivePeriod(django_args['seed'], |
925 period_name, 'scope_path') |
974 period_name, 'scope_path') |
926 else: |
975 else: |
927 return |
976 return |
928 |
977 |
929 @allowDeveloper |
978 @allowDeveloper |
930 def checkCanEditGroupApp(self, django_args, group_app_logic): |
979 def checkCanEditGroupApp(self, django_args, group_app_logic): |
931 """Checks if the group_app in args is valid to be edited by the current user. |
980 """Checks if the group_app in args is valid to be edited by |
932 |
981 the current user. |
933 Args: |
982 |
|
983 Args: |
|
984 django_args: a dictionary with django's arguments |
934 group_app_logic: A logic instance for the Group Application |
985 group_app_logic: A logic instance for the Group Application |
935 """ |
986 """ |
936 |
987 |
937 self.checkIsUser(django_args) |
988 self.checkIsUser(django_args) |
938 |
989 |
955 @allowSidebar |
1006 @allowSidebar |
956 def checkCanReviewGroupApp(self, django_args, group_app_logic): |
1007 def checkCanReviewGroupApp(self, django_args, group_app_logic): |
957 """Checks if the group_app in args is valid to be reviewed. |
1008 """Checks if the group_app in args is valid to be reviewed. |
958 |
1009 |
959 Args: |
1010 Args: |
|
1011 django_args: a dictionary with django's arguments |
960 group_app_logic: A logic instance for the Group Application |
1012 group_app_logic: A logic instance for the Group Application |
961 """ |
1013 """ |
962 |
1014 |
963 if 'link_id' not in django_args: |
1015 if 'link_id' not in django_args: |
964 # calling review overview, so we can't check a specified entity |
1016 # calling review overview, so we can't check a specified entity |
1257 def checkIsMyEntity(self, django_args, logic, |
1310 def checkIsMyEntity(self, django_args, logic, |
1258 field_name='user', user=False): |
1311 field_name='user', user=False): |
1259 """Checks whether the entity belongs to the user. |
1312 """Checks whether the entity belongs to the user. |
1260 |
1313 |
1261 Args: |
1314 Args: |
|
1315 django_args: a dictionary with django's arguments |
1262 logic: the logic that should be used to fetch the entity |
1316 logic: the logic that should be used to fetch the entity |
1263 field_name: the name of the field the entity uses to store it's owner |
1317 field_name: the name of the field the entity uses to store it's owner |
1264 user: whether the entity stores the user's key name, or a reference |
1318 user: whether the entity stores the user's key name, or a reference |
1265 """ |
1319 """ |
1266 |
1320 |
1286 def checkIsAllowedToManageRole(self, django_args, role_logic, manage_role_logic): |
1340 def checkIsAllowedToManageRole(self, django_args, role_logic, manage_role_logic): |
1287 """Returns an alternate HTTP response if the user is not allowed to manage |
1341 """Returns an alternate HTTP response if the user is not allowed to manage |
1288 the role given in args. |
1342 the role given in args. |
1289 |
1343 |
1290 Args: |
1344 Args: |
|
1345 django_args: a dictionary with django's arguments |
1291 role_logic: determines the logic for the role in args. |
1346 role_logic: determines the logic for the role in args. |
1292 manage_role_logic: determines the logic for the role which is allowed |
1347 manage_role_logic: determines the logic for the role which is allowed |
1293 to manage this role. |
1348 to manage this role. |
1294 |
1349 |
1295 Raises: |
1350 Raises: |
1367 document.write_access, django_args) |
1424 document.write_access, django_args) |
1368 |
1425 |
1369 @allowDeveloper |
1426 @allowDeveloper |
1370 def checkDocumentList(self, django_args): |
1427 def checkDocumentList(self, django_args): |
1371 """Checks whether the user is allowed to list documents. |
1428 """Checks whether the user is allowed to list documents. |
|
1429 |
|
1430 Args: |
|
1431 django_args: a dictionary with django's arguments |
1372 """ |
1432 """ |
1373 |
1433 |
1374 filter = django_args['filter'] |
1434 filter = django_args['filter'] |
1375 |
|
1376 prefix = filter['prefix'] |
1435 prefix = filter['prefix'] |
1377 scope_path = filter['scope_path'] |
|
1378 |
1436 |
1379 checker = rights_logic.Checker(prefix) |
1437 checker = rights_logic.Checker(prefix) |
1380 roles = checker.getMembership('list') |
1438 roles = checker.getMembership('list') |
1381 |
1439 |
1382 if not self.hasMembership(roles, filter): |
1440 if not self.hasMembership(roles, filter): |
1385 @allowDeveloper |
1443 @allowDeveloper |
1386 def checkDocumentPick(self, django_args): |
1444 def checkDocumentPick(self, django_args): |
1387 """Checks whether the user has access to the specified pick url. |
1445 """Checks whether the user has access to the specified pick url. |
1388 |
1446 |
1389 Will update the 'read_access' field of django_args['GET']. |
1447 Will update the 'read_access' field of django_args['GET']. |
|
1448 |
|
1449 Args: |
|
1450 django_args: a dictionary with django's arguments |
1390 """ |
1451 """ |
1391 |
1452 |
1392 get_args = django_args['GET'] |
1453 get_args = django_args['GET'] |
1393 |
|
1394 # make mutable in order to inject the proper read_access filter |
1454 # make mutable in order to inject the proper read_access filter |
1395 mutable = get_args._mutable |
1455 mutable = get_args._mutable |
1396 get_args._mutable = True |
1456 get_args._mutable = True |
1397 |
1457 |
1398 if 'prefix' not in get_args: |
1458 if 'prefix' not in get_args: |
1416 get_args.setlist('read_access', roles) |
1476 get_args.setlist('read_access', roles) |
1417 get_args._mutable = mutable |
1477 get_args._mutable = mutable |
1418 |
1478 |
1419 def checkCanEditTimeline(self, django_args): |
1479 def checkCanEditTimeline(self, django_args): |
1420 """Checks whether this program's timeline may be edited. |
1480 """Checks whether this program's timeline may be edited. |
1421 """ |
1481 |
1422 |
1482 Args: |
|
1483 django_args: a dictionary with django's arguments |
|
1484 """ |
|
1485 |
1423 time_line_keyname = timeline_logic.getKeyFieldsFromFields(django_args) |
1486 time_line_keyname = timeline_logic.getKeyFieldsFromFields(django_args) |
1424 timeline_entity = timeline_logic.getFromKeyName(time_line_keyname) |
1487 timeline_entity = timeline_logic.getFromKeyName(time_line_keyname) |
1425 |
1488 |
1426 if not timeline_entity: |
1489 if not timeline_entity: |
1427 # timeline does not exists so deny |
1490 # timeline does not exists so deny |