예제 #1
0
    def VerifyPermissions(self,
                          required_permission,
                          user=None,
                          permission_type=None):
        """Verifies a valid user is logged in.

    Args:
      required_permission: permission string from permissions.*.
      user: optional, models.User entity; default current user.
      permission_type: optional, string, one of permission.TYPE_* variables. if
          omitted, self.PERMISSION_TYPE is used.
    Returns:
      models.User object of the current user.
    Raises:
      models.AccessDeniedError: there was a permissions issue.
    """
        permission_type = permission_type or self.PERMISSION_TYPE
        if not permission_type:
            raise models.AccessDeniedError('permission_type not specified')

        if user is None:
            user = models.GetCurrentUser()

        try:
            if not user.HasPerm(required_permission,
                                permission_type=permission_type):
                raise models.AccessDeniedError('User lacks %s permission' %
                                               required_permission)
        except ValueError:
            raise models.AccessDeniedError('unknown permission_type: %s' %
                                           permission_type)

        return user
예제 #2
0
    def testByPermReadUserWithNoOwner(self):
        mock_user = self.mox.CreateMockAnything(models.User)
        mock_user.user = self.mox.CreateMockAnything(users.User)
        mock_user.user.email = lambda: '*****@*****.**'

        mock_entity = models.LuksVolume
        mock_entity.owner = None

        self.mox.StubOutWithMock(self.c, 'RenderTemplate')
        data = self._GetDataDict(mock_entity, mock_user)
        self.c.RenderTemplate('retrieval_email.txt', data,
                              response_out=False).AndReturn('body')

        self.mox.StubOutWithMock(util, 'SendEmail')
        self.mox.StubOutWithMock(settings, 'RETRIEVE_AUDIT_ADDRESSES')
        settings.RETRIEVE_AUDIT_ADDRESSES = ['*****@*****.**']
        self.mox.StubOutWithMock(self.c, 'VerifyPermissions')

        self.c.VerifyPermissions(permissions.SILENT_RETRIEVE,
                                 user=mock_user).AndRaise(
                                     models.AccessDeniedError('test'))
        owner_email = '%s@%s' % (mock_entity.owner,
                                 settings.DEFAULT_EMAIL_DOMAIN)
        user_email = mock_user.user.email()
        util.SendEmail([user_email] + settings.RETRIEVE_AUDIT_ADDRESSES,
                       settings.LUKS_RETRIEVAL_EMAIL_SUBJECT, 'body')
        self.mox.ReplayAll()
        self.c.SendRetrievalEmail(mock_entity, mock_user)
        self.mox.VerifyAll()
예제 #3
0
    def testProvisioningAsNonOwner(self):
        self.c = handlers.ProvisioningAccessHandler()
        self.mox.StubOutWithMock(self.c, 'VerifyXsrfToken')
        self.c.VerifyXsrfToken('RetrieveSecret')

        mock_user = self.mox.CreateMockAnything()
        mock_user.email = '*****@*****.**'
        self.mox.StubOutWithMock(models, 'GetCurrentUser')
        models.GetCurrentUser().AndReturn(mock_user)

        self.mox.StubOutWithMock(self.c, 'VerifyPermissions')
        self.c.VerifyPermissions(
            permissions.RETRIEVE, user=mock_user).AndRaise(
                models.AccessDeniedError('user is not an admin'))
        self.c.VerifyPermissions(permissions.RETRIEVE_OWN, user=mock_user)

        uuid = 'foovolumeuuid'
        passphrase = 'foopassphrase'
        mock_entity = self.mox.CreateMockAnything()
        mock_entity.passphrase = passphrase
        mock_entity.owner = 'mock_user_foo'

        self.mox.StubOutWithMock(models.ProvisioningVolume, 'get_by_key_name')
        models.ProvisioningVolume.get_by_key_name(uuid).AndReturn(mock_entity)

        mock_user.user = self.mox.CreateMockAnything()
        self.mox.StubOutWithMock(mock_user.user, 'nickname')
        mock_user.user.nickname().AndReturn('mock_user_bar')

        self.mox.ReplayAll()
        self.assertRaises(models.AccessError, self.c.RetrieveSecret, uuid)
        self.mox.VerifyAll()
예제 #4
0
    def testPut(self, incr, get_current_user):
        incr.return_value = 1
        get_current_user.side_effect = models.AccessDeniedError('no user')

        log = models.AccessLog()
        log.put()

        incr.assert_called_once_with('AccessLogCounter', initial_value=0)
예제 #5
0
    def testPut(self):
        self.mox.StubOutWithMock(models.memcache, 'incr')
        self.mox.StubOutWithMock(models, 'GetCurrentUser')

        models.memcache.incr('AccessLogCounter', initial_value=0).AndReturn(1)
        models.GetCurrentUser().AndRaise(models.AccessDeniedError('no user'))

        self.mox.ReplayAll()
        log = models.AccessLog()
        log.put()
        self.mox.VerifyAll()
예제 #6
0
def VerifyPermissions(required_permission, user, permission_type):
    """Verifies a valid user is logged in.

  Args:
    required_permission: permission string from permissions.*.
    user: models.User entity; default current user.
    permission_type: string, one of permission.TYPE_* variables.
  Raises:
    models.AccessDeniedError: there was a permissions issue.
  """
    if not permission_type:
        raise models.AccessDeniedError('permission_type not specified')

    try:
        if not user.HasPerm(required_permission,
                            permission_type=permission_type):
            raise models.AccessDeniedError('User lacks %s permission' %
                                           required_permission)
    except ValueError:
        raise models.AccessDeniedError('unknown permission_type: %s' %
                                       permission_type)
예제 #7
0
    def testLuksAsOwnerBarcodeTooLong(self):
        self.mox.StubOutWithMock(self.c, 'VerifyXsrfToken')
        self.c.VerifyXsrfToken('RetrieveSecret')

        mock_user = self.mox.CreateMockAnything()
        mock_user.email = '*****@*****.**'
        mock_user.__getitem__('email').AndReturn(mock_user.email)
        self.mox.StubOutWithMock(models, 'GetCurrentUser')
        models.GetCurrentUser().AndReturn(mock_user)
        models.GetCurrentUser().AndReturn(mock_user)

        self.mox.StubOutWithMock(self.c, 'VerifyPermissions')
        self.c.VerifyPermissions(
            permissions.RETRIEVE, user=mock_user).AndRaise(
                models.AccessDeniedError('user is not an admin'))
        self.c.VerifyPermissions(permissions.RETRIEVE_OWN, user=mock_user)

        volume_uuid = 'foovolumeuuid'
        passphrase = '676ffb71232f71ee0ddf643876907f17' * 20

        self.c.request = {'json': '0'}
        self.c.response = self.mox.CreateMockAnything()
        self.c.response.out = self.mox.CreateMockAnything()
        self.c.response.out.write(
            mox.And(mox.Not(mox.Regex(r'<img class="qr_code" ')),
                    mox.Regex(passphrase)))

        mock_entity = self.mox.CreateMockAnything()
        mock_entity.passphrase = passphrase
        mock_entity.owner = '*****@*****.**'

        self.mox.StubOutWithMock(models.LuksVolume, 'get_by_key_name')
        models.LuksVolume.get_by_key_name(volume_uuid).AndReturn(mock_entity)

        mock_user.user = self.mox.CreateMockAnything()
        self.mox.StubOutWithMock(mock_user.user, 'nickname')
        mock_user.user.nickname().AndReturn('mock_user_foo')

        self.mox.StubOutWithMock(models.LuksAccessLog, 'Log')
        models.LuksAccessLog.Log(message='GET',
                                 entity=mock_entity,
                                 request=self.c.request)

        self.mox.StubOutWithMock(self.c, 'SendRetrievalEmail')
        self.c.SendRetrievalEmail(mock_entity, mock_user).AndReturn(None)

        self.mox.ReplayAll()
        self.c.RetrieveSecret(volume_uuid)
        self.mox.VerifyAll()
예제 #8
0
    def testProvisioningAsOwner(self):
        self.c = handlers.ProvisioningAccessHandler()
        self.mox.StubOutWithMock(self.c, 'VerifyXsrfToken')
        self.c.VerifyXsrfToken('RetrieveSecret')

        mock_user = self.mox.CreateMockAnything()
        mock_user.email = '*****@*****.**'
        self.mox.StubOutWithMock(models, 'GetCurrentUser')
        models.GetCurrentUser().AndReturn(mock_user)

        self.mox.StubOutWithMock(self.c, 'VerifyPermissions')
        self.c.VerifyPermissions(
            permissions.RETRIEVE, user=mock_user).AndRaise(
                models.AccessDeniedError('user is not an admin'))
        self.c.VerifyPermissions(permissions.RETRIEVE_OWN, user=mock_user)

        uuid = 'foovolumeuuid'
        passphrase = 'foopassphrase'

        self.c.request = {'json': '1'}
        self.c.response = self.mox.CreateMockAnything()
        self.c.response.out = self.mox.CreateMockAnything()
        self.c.response.out.write(handlers.JSON_PREFIX +
                                  '{"passphrase": "%s"}' % passphrase)

        mock_entity = self.mox.CreateMockAnything()
        mock_entity.passphrase = passphrase
        mock_entity.owner = 'mock_user_foo'

        self.mox.StubOutWithMock(models.ProvisioningVolume, 'get_by_key_name')
        models.ProvisioningVolume.get_by_key_name(uuid).AndReturn(mock_entity)

        mock_user.user = self.mox.CreateMockAnything()
        self.mox.StubOutWithMock(mock_user.user, 'nickname')
        mock_user.user.nickname().AndReturn('mock_user_foo')

        self.mox.StubOutWithMock(models.ProvisioningAccessLog, 'Log')
        models.ProvisioningAccessLog.Log(message='GET',
                                         entity=mock_entity,
                                         request=self.c.request)

        self.mox.StubOutWithMock(self.c, 'SendRetrievalEmail')
        self.c.SendRetrievalEmail(mock_entity, mock_user).AndReturn(None)

        self.mox.ReplayAll()
        self.c.RetrieveSecret(uuid)
        self.mox.VerifyAll()
예제 #9
0
    def VerifyXsrfToken(self, action):
        """Verifies a valid XSRF token was passed for the current request.

    Args:
      action: String, validate the token against this action.
    Returns:
      Boolean. True if the XSRF Token was valid.
    Raises:
      models.AccessDeniedError: the XSRF token was invalid or not supplied.
    """
        xsrf_token = self.request.get('xsrf-token', None)
        if settings.XSRF_PROTECTION_ENABLED:
            if not util.XsrfTokenValidate(xsrf_token, action):
                raise models.AccessDeniedError('Valid XSRF token not provided')
        elif not xsrf_token:
            logging.info(
                'Ignoring missing XSRF token; settings.XSRF_PROTECTION_ENABLED=False'
            )
        return True
예제 #10
0
    def get(self):  # pylint: disable=g-bad-name
        """Handles GET requests."""
        # TODO(user): Users with retrieve_own should not need to search to
        # retrieve their escrowed secrets.
        if self.request.get('json', '0') != '1':
            search_type = self.request.get('search_type')
            field1 = urllib.quote(self.request.get('field1'))
            value1 = urllib.quote(self.request.get('value1').strip())
            prefix_search = urllib.quote(self.request.get(
                'prefix_search', '0'))

            if search_type and field1 and value1:
                self.redirect('/ui/#/search/%s/%s/%s/%s' %
                              (search_type, field1, value1, prefix_search))
            else:
                self.redirect('/ui/')
            return

        tag = self.request.get('tag', 'default')
        search_type = self.request.get('search_type')
        field1 = self.request.get('field1')
        value1 = self.request.get('value1').strip()
        prefix_search = self.request.get('prefix_search', '0') == '1'

        if search_type not in SEARCH_TYPES:
            raise handlers.InvalidArgumentError('Invalid search_type %s' %
                                                search_type)

        if not (field1 and value1):
            raise handlers.InvalidArgumentError('Missing field1 or value1')

        # Get the user's search and retrieve permissions for all permission types.
        search_perms = handlers.VerifyAllPermissionTypes(permissions.SEARCH)
        retrieve_perms = handlers.VerifyAllPermissionTypes(
            permissions.RETRIEVE_OWN)
        retrieve_created = handlers.VerifyAllPermissionTypes(
            permissions.RETRIEVE_CREATED_BY)

        # user is performing a search, ensure they have permissions.
        if (not search_perms.get(search_type)
                and not retrieve_perms.get(search_type)
                and not retrieve_created.get(search_type)):
            raise models.AccessDeniedError('User lacks %s permission' %
                                           search_type)

        # TODO(user): implement multi-field search by building query here
        #   or better yet using JavaScript.
        q = '%s:%s' % (field1, value1)
        try:
            volumes = VolumesForQuery(q, search_type, prefix_search)
        except ValueError:
            self.error(httplib.NOT_FOUND)
            return

        if not search_perms.get(search_type):
            username = models.GetCurrentUser().user.nickname()
            volumes = [x for x in volumes if x.owner == username]

        volumes = [v.ToDict(skip_secret=True) for v in volumes if v.tag == tag]
        if SEARCH_TYPES[search_type].ALLOW_OWNER_CHANGE:
            for volume in volumes:
                if not volume['active']:
                    continue
                volume[
                    'change_owner_link'] = '/api/internal/change-owner/%s/%s/' % (
                        search_type, volume['id'])

        self.response.out.write(util.ToSafeJson(volumes))
예제 #11
0
    def get(self):  # pylint: disable=g-bad-name
        """Handles GET requests."""
        # TODO(user): Users with retrieve_own should not need to search to
        # retrieve their escrowed secrets.

        # Get the user's search and retrieve permissions for all permission types.
        search_perms = self.VerifyAllPermissionTypes(permissions.SEARCH)
        retrieve_perms = self.VerifyAllPermissionTypes(
            permissions.RETRIEVE_OWN)
        retrieve_created = self.VerifyAllPermissionTypes(
            permissions.RETRIEVE_CREATED_BY)

        # If the user is performing a search, ensure they have permissions.
        search_type = self.request.get('search_type')
        if (search_type and not search_perms.get(search_type)
                and not retrieve_perms.get(search_type)
                and not retrieve_created.get(search_type)):
            raise models.AccessDeniedError('User lacks %s permission' %
                                           search_type)

        template_name = None
        queried = False
        params = {}

        if search_type in SEARCH_TYPES:
            field1 = self.request.get('field1')
            value1 = self.request.get('value1').strip()
            if field1 and value1:
                queried = True
                prefix_search = self.request.get('prefix_search', '0') == '1'
                # TODO(user): implement multi-field search by building query here
                #   or better yet using JavaScript.
                q = '%s:%s' % (field1, value1)
                try:
                    volumes = VolumesForQuery(q, search_type, prefix_search)
                except ValueError:
                    self.error(404)
                    return
                if not search_perms.get(search_type):
                    username = models.GetCurrentUser().user.nickname()
                    volumes = [x for x in volumes if x.owner == username]
                template_name = 'search_result.html'
                params = {
                    'q': q,
                    'search_type': search_type,
                    'volumes': volumes
                }

        if not queried:
            template_name = 'search_form.html'
            params = {}
            if search_perms[permissions.TYPE_BITLOCKER]:
                params[
                    'bitlocker_fields'] = models.BitLockerVolume.SEARCH_FIELDS
            if search_perms[permissions.TYPE_FILEVAULT]:
                params[
                    'filevault_fields'] = models.FileVaultVolume.SEARCH_FIELDS
            if search_perms[permissions.TYPE_LUKS]:
                params['luks_fields'] = models.LuksVolume.SEARCH_FIELDS
            if search_perms[permissions.TYPE_PROVISIONING]:
                provisioning_fields = models.ProvisioningVolume.SEARCH_FIELDS
                params['provisioning_fields'] = provisioning_fields

        params['xsrf_token'] = util.XsrfTokenGenerate(
            base_settings.GET_PASSPHRASE_ACTION)
        self.RenderTemplate(template_name, params)