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
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()
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()
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)
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()
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)
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()
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()
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
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))
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)