app/soc/views/helper/access.py
changeset 2534 c880489123fc
parent 2523 9d9d1ded30ee
child 2536 9f1b7aba026f
equal deleted inserted replaced
2533:941732c52b67 2534:c880489123fc
    39 from soc.logic import rights as rights_logic
    39 from soc.logic import rights as rights_logic
    40 from soc.logic.helper import timeline as timeline_helper
    40 from soc.logic.helper import timeline as timeline_helper
    41 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
    42 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
    43 from soc.logic.models.document import logic as document_logic
    43 from soc.logic.models.document import logic as document_logic
    44 from soc.logic.models.survey import logic as survey_logic
       
    45 from soc.logic.models.host import logic as host_logic
    44 from soc.logic.models.host import logic as host_logic
    46 from soc.logic.models.mentor import logic as mentor_logic
    45 from soc.logic.models.mentor import logic as mentor_logic
    47 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
    48 from soc.logic.models.organization import logic as org_logic
    47 from soc.logic.models.organization import logic as org_logic
    49 from soc.logic.models.program import logic as program_logic
    48 from soc.logic.models.program import logic as program_logic
  1551       survey = survey_logic.getFromKeyFieldsOr404(django_args)
  1550       survey = survey_logic.getFromKeyFieldsOr404(django_args)
  1552 
  1551 
  1553     self.checkMembership('write', survey.prefix,
  1552     self.checkMembership('write', survey.prefix,
  1554                          survey.write_access, django_args)
  1553                          survey.write_access, django_args)
  1555 
  1554 
  1556 
       
  1557   @allowSidebar
       
  1558   @allowDeveloper
       
  1559   def checkIsDocumentReadable(self, django_args, key_name_field=None):
       
  1560     """Checks whether a document is readable by the current user.
       
  1561 
       
  1562     Args:
       
  1563       django_args: a dictionary with django's arguments
       
  1564       key_name_field: key name field
       
  1565     """
       
  1566 
       
  1567     if key_name_field:
       
  1568       key_name = django_args[key_name_field]
       
  1569       document = document_logic.getFromKeyNameOr404(key_name)
       
  1570     else:
       
  1571       document = document_logic.getFromKeyFieldsOr404(django_args)
       
  1572 
       
  1573     self.checkMembership('read', document.prefix,
       
  1574                          document.read_access, django_args)
       
  1575 
       
  1576   @denySidebar
  1555   @denySidebar
  1577   @allowDeveloper
  1556   @allowDeveloper
  1578   def checkIsDocumentWritable(self, django_args, key_name_field=None):
  1557   def checkIsSurveyTakeable(self, django_args, survey_logic):
  1579     """Checks whether a document is writable by the current user.
       
  1580 
       
  1581     Args:
       
  1582       django_args: a dictionary with django's arguments
       
  1583       key_name_field: key name field
       
  1584     """
       
  1585 
       
  1586     if key_name_field:
       
  1587       key_name = django_args[key_name_field]
       
  1588       document = document_logic.getFromKeyNameOr404(key_name)
       
  1589     else:
       
  1590       document = document_logic.getFromKeyFieldsOr404(django_args)
       
  1591 
       
  1592     self.checkMembership('write', document.prefix,
       
  1593                          document.write_access, django_args)
       
  1594 
       
  1595   @allowDeveloper
       
  1596   def checkDocumentList(self, django_args):
       
  1597     """Checks whether the user is allowed to list documents.
       
  1598     
       
  1599     Args:
       
  1600       django_args: a dictionary with django's arguments
       
  1601     """
       
  1602 
       
  1603     filter = django_args['filter']
       
  1604     prefix = filter['prefix']
       
  1605 
       
  1606     checker = rights_logic.Checker(prefix)
       
  1607     roles = checker.getMembership('list')
       
  1608 
       
  1609     if not self.hasMembership(roles, filter):
       
  1610       raise out_of_band.AccessViolation(message_fmt=DEF_NO_LIST_ACCESS_MSG)
       
  1611 
       
  1612   @allowDeveloper
       
  1613   def checkDocumentPick(self, django_args):
       
  1614     """Checks whether the user has access to the specified pick url.
       
  1615 
       
  1616     Will update the 'read_access' field of django_args['GET'].
       
  1617     
       
  1618     Args:
       
  1619       django_args: a dictionary with django's arguments
       
  1620     """
       
  1621 
       
  1622     get_args = django_args['GET']
       
  1623     # make mutable in order to inject the proper read_access filter
       
  1624     mutable = get_args._mutable
       
  1625     get_args._mutable = True
       
  1626 
       
  1627     if 'prefix' not in get_args:
       
  1628       raise out_of_band.AccessViolation(message_fmt=DEF_PREFIX_NOT_IN_ARGS_MSG)
       
  1629 
       
  1630     prefix = get_args['prefix']
       
  1631     django_args['prefix'] = prefix
       
  1632     django_args['scope_path'] = get_args['scope_path']
       
  1633 
       
  1634     checker = rights_logic.Checker(prefix)
       
  1635     memberships = checker.getMemberships()
       
  1636 
       
  1637     roles = []
       
  1638     for key, value in memberships.iteritems():
       
  1639       if self.hasMembership(value, django_args):
       
  1640         roles.append(key)
       
  1641 
       
  1642     if not roles:
       
  1643       roles = ['deny']
       
  1644 
       
  1645     get_args.setlist('read_access', roles)
       
  1646     get_args._mutable = mutable
       
  1647 
       
  1648   def checkCanEditTimeline(self, django_args):
       
  1649     """Checks whether this program's timeline may be edited.
       
  1650     
       
  1651     Args:
       
  1652       django_args: a dictionary with django's arguments
       
  1653     """
       
  1654     
       
  1655     time_line_keyname = timeline_logic.getKeyFieldsFromFields(django_args)
       
  1656     timeline_entity = timeline_logic.getFromKeyName(time_line_keyname)
       
  1657 
       
  1658     if not timeline_entity:
       
  1659       # timeline does not exists so deny
       
  1660       self.deny(django_args)
       
  1661 
       
  1662     fields = program_logic.getKeyFieldsFromFields(django_args)
       
  1663     self.checkIsHostForProgram(fields)
       
  1664 
       
  1665   def checkHasSurveyAccess(self, django_args):
       
  1666     """Checks if the survey specified in django_args can be taken.
  1558     """Checks if the survey specified in django_args can be taken.
  1667 
  1559 
  1668     Uses survey.taking_access to map that string onto a check. Also checks for
  1560     Uses survey.taking_access to map that string onto a check. Also checks for
  1669     deadline start and end.
  1561     survey start and end.
  1670 
  1562 
  1671     If the prefix is 'program', the scope of the survey is the program and
  1563     If the prefix is 'program', the scope of the survey is the program and
  1672     the taking_acccess attribute means:
  1564     the taking_acccess attribute means:
  1673       mentor: user is mentor for the program
  1565       mentor: user is mentor for the program
  1674       org_admin: user is org_admin for the program
  1566       org_admin: user is org_admin for the program
  1675       student: user is student for the program
  1567       student: user is student for the program
  1676       user: valid user on the website
  1568       user: valid user on the website
  1677       public: anyone can participate in the survey
  1569 
       
  1570     Args:
       
  1571       survey_logic: SurveyLogic instance (or subclass)
  1678     """
  1572     """
  1679 
  1573 
  1680     if django_args['prefix'] != 'program':
  1574     if django_args['prefix'] != 'program':
  1681       # TODO: update when generic surveys are allowe
  1575       # TODO: update when generic surveys are allowed
  1682       return self.deny(django_args)
  1576       return self.deny(django_args)
  1683 
  1577 
       
  1578     # get the survey from django_args
  1684     survey = survey_logic.getFromKeyFieldsOr404(django_args)
  1579     survey = survey_logic.getFromKeyFieldsOr404(django_args)
  1685 
  1580 
       
  1581     # check if the survey can be taken now
  1686     if not timeline_helper.isActivePeriod(survey, 'survey'):
  1582     if not timeline_helper.isActivePeriod(survey, 'survey'):
  1687       raise out_of_band.AccessViolation(message_fmt=DEF_PAGE_INACTIVE_MSG)
  1583       raise out_of_band.AccessViolation(message_fmt=DEF_PAGE_INACTIVE_MSG)
  1688 
  1584 
       
  1585     # retrieve the role that is allowed to take this survey
  1689     role = survey.taking_access
  1586     role = survey.taking_access
  1690 
  1587 
  1691     if role == 'user':
  1588     if role == 'user':
       
  1589       # check if the current user is registered
  1692       return self.checkIsUser(django_args)
  1590       return self.checkIsUser(django_args)
  1693 
  1591 
  1694     django_args = django_args.copy()
  1592     django_args = django_args.copy()
  1695 
  1593 
       
  1594     # get the survey scope
       
  1595     survey_scope = survey_logic.getScope(survey)
       
  1596 
  1696     if role == 'mentor':
  1597     if role == 'mentor':
  1697       django_args['program'] = survey.scope
  1598       # check if the current user is a mentor for the program in survey.scope
       
  1599       django_args['program'] = survey_scope
  1698       # program is the 'program' attribute for mentors and org_admins
  1600       # program is the 'program' attribute for mentors and org_admins
  1699       entity = self._checkHasActiveRoleFor(django_args, mentor_logic, 'program')
  1601       return self._checkHasActiveRoleFor(django_args, mentor_logic, 'program')
  1700 
       
  1701       fields = {
       
  1702           'mentor': entity,
       
  1703           'program': survey.scope,
       
  1704           'status': ['accepted', 'mid_term_passed'],
       
  1705           }
       
  1706 
       
  1707       project = student_project_logic.getForFields(fields, unique=True)
       
  1708 
       
  1709       if project:
       
  1710         return
       
  1711 
       
  1712       raise out_of_band.AccessViolation(message_fmt=DEF_NO_ACTIVE_STUDENT_PROJECT_MSG)
       
  1713 
  1602 
  1714     if role == 'org_admin':
  1603     if role == 'org_admin':
       
  1604       # check if the current user is a mentor for the program in survey.scope
       
  1605       django_args['program'] = survey_scope
  1715       # program is the 'program' attribute for mentors and org_admins
  1606       # program is the 'program' attribute for mentors and org_admins
  1716       return self._checkHasActiveRoleFor(django_args, org_admin_logic, 'program')
  1607       return self._checkHasActiveRoleFor(django_args, org_admin_logic, 'program')
  1717 
  1608 
  1718     if role == 'student':
  1609     if role == 'student':
  1719       django_args['scope'] = survey.scope
  1610       # check if the current user is a student for the program in survey.scope
       
  1611       django_args['scope'] = survey_scope
  1720       # program is the 'scope' attribute for students
  1612       # program is the 'scope' attribute for students
  1721       entity = self.checkHasActiveRoleForScope(django_args, student_logic)
  1613       return self.checkHasActiveRoleForScope(django_args, student_logic)
  1722 
       
  1723       fields = {
       
  1724           'scope': entity,
       
  1725           'status': ['accepted', 'mid_term_passed'],
       
  1726           }
       
  1727 
       
  1728       # student is scope for student projects
       
  1729       project = student_project_logic.getForFields(fields, unique=True)
       
  1730 
       
  1731       if project:
       
  1732         return
       
  1733 
       
  1734       raise out_of_band.AccessViolation(message_fmt=DEF_NO_ACTIVE_STUDENT_PROJECT_MSG)
       
  1735 
  1614 
  1736     # unknown role
  1615     # unknown role
  1737     self.deny(django_args)
  1616     self.deny(django_args)
       
  1617 
       
  1618   @denySidebar
       
  1619   @allowDeveloper
       
  1620   def checkIsAllowedToTakeProjectSurveyAs(self, django_args, survey_logic,
       
  1621                                           role_name, project_key_location):
       
  1622     """Checks whether a ProjectSurvey can be taken by the current User.
       
  1623 
       
  1624     role_name argument determines wether the current user should be the
       
  1625     student or mentor specified by the project in GET dict.
       
  1626 
       
  1627     However if the project entry is not present in the dictionary this access
       
  1628     check passes.
       
  1629 
       
  1630     Args:
       
  1631       django_args: a dictionary with django's arguments
       
  1632       survey_logic: instance of ProjectSurveyLogic (or subclass)
       
  1633       role_name: String containing either "student" or "mentor"
       
  1634       project_key_location: String containing the key entry in the GET dict
       
  1635         where the key for the project can be located.
       
  1636     """
       
  1637 
       
  1638     # TODO(ljvderijk) implement this check
       
  1639     #raise out_of_band.AccessViolation(message_fmt=DEF_NO_ACTIVE_STUDENT_PROJECT_MSG)
       
  1640 
       
  1641     self.allow(django_args)
       
  1642 
       
  1643   @allowSidebar
       
  1644   @allowDeveloper
       
  1645   def checkIsDocumentReadable(self, django_args, key_name_field=None):
       
  1646     """Checks whether a document is readable by the current user.
       
  1647 
       
  1648     Args:
       
  1649       django_args: a dictionary with django's arguments
       
  1650       key_name_field: key name field
       
  1651     """
       
  1652 
       
  1653     if key_name_field:
       
  1654       key_name = django_args[key_name_field]
       
  1655       document = document_logic.getFromKeyNameOr404(key_name)
       
  1656     else:
       
  1657       document = document_logic.getFromKeyFieldsOr404(django_args)
       
  1658 
       
  1659     self.checkMembership('read', document.prefix,
       
  1660                          document.read_access, django_args)
       
  1661 
       
  1662   @denySidebar
       
  1663   @allowDeveloper
       
  1664   def checkIsDocumentWritable(self, django_args, key_name_field=None):
       
  1665     """Checks whether a document is writable by the current user.
       
  1666 
       
  1667     Args:
       
  1668       django_args: a dictionary with django's arguments
       
  1669       key_name_field: key name field
       
  1670     """
       
  1671 
       
  1672     if key_name_field:
       
  1673       key_name = django_args[key_name_field]
       
  1674       document = document_logic.getFromKeyNameOr404(key_name)
       
  1675     else:
       
  1676       document = document_logic.getFromKeyFieldsOr404(django_args)
       
  1677 
       
  1678     self.checkMembership('write', document.prefix,
       
  1679                          document.write_access, django_args)
       
  1680 
       
  1681   @allowDeveloper
       
  1682   def checkDocumentList(self, django_args):
       
  1683     """Checks whether the user is allowed to list documents.
       
  1684     
       
  1685     Args:
       
  1686       django_args: a dictionary with django's arguments
       
  1687     """
       
  1688 
       
  1689     filter = django_args['filter']
       
  1690     prefix = filter['prefix']
       
  1691 
       
  1692     checker = rights_logic.Checker(prefix)
       
  1693     roles = checker.getMembership('list')
       
  1694 
       
  1695     if not self.hasMembership(roles, filter):
       
  1696       raise out_of_band.AccessViolation(message_fmt=DEF_NO_LIST_ACCESS_MSG)
       
  1697 
       
  1698   @allowDeveloper
       
  1699   def checkDocumentPick(self, django_args):
       
  1700     """Checks whether the user has access to the specified pick url.
       
  1701 
       
  1702     Will update the 'read_access' field of django_args['GET'].
       
  1703     
       
  1704     Args:
       
  1705       django_args: a dictionary with django's arguments
       
  1706     """
       
  1707 
       
  1708     get_args = django_args['GET']
       
  1709     # make mutable in order to inject the proper read_access filter
       
  1710     mutable = get_args._mutable
       
  1711     get_args._mutable = True
       
  1712 
       
  1713     if 'prefix' not in get_args:
       
  1714       raise out_of_band.AccessViolation(message_fmt=DEF_PREFIX_NOT_IN_ARGS_MSG)
       
  1715 
       
  1716     prefix = get_args['prefix']
       
  1717     django_args['prefix'] = prefix
       
  1718     django_args['scope_path'] = get_args['scope_path']
       
  1719 
       
  1720     checker = rights_logic.Checker(prefix)
       
  1721     memberships = checker.getMemberships()
       
  1722 
       
  1723     roles = []
       
  1724     for key, value in memberships.iteritems():
       
  1725       if self.hasMembership(value, django_args):
       
  1726         roles.append(key)
       
  1727 
       
  1728     if not roles:
       
  1729       roles = ['deny']
       
  1730 
       
  1731     get_args.setlist('read_access', roles)
       
  1732     get_args._mutable = mutable
       
  1733 
       
  1734   def checkCanEditTimeline(self, django_args):
       
  1735     """Checks whether this program's timeline may be edited.
       
  1736 
       
  1737     Args:
       
  1738       django_args: a dictionary with django's arguments
       
  1739     """
       
  1740     
       
  1741     time_line_keyname = timeline_logic.getKeyFieldsFromFields(django_args)
       
  1742     timeline_entity = timeline_logic.getFromKeyName(time_line_keyname)
       
  1743 
       
  1744     if not timeline_entity:
       
  1745       # timeline does not exists so deny
       
  1746       self.deny(django_args)
       
  1747 
       
  1748     fields = program_logic.getKeyFieldsFromFields(django_args)
       
  1749     self.checkIsHostForProgram(fields)