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 testNominal(self): volume_uuid = 'foovolumeuuid' passphrase = 'foopassphrase' mock_entity = self.mox.CreateMockAnything() mock_entity.passphrase = passphrase 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) self.mox.StubOutWithMock(models, 'GetCurrentUser') models.GetCurrentUser().AndReturn('mock_user') self.mox.StubOutWithMock(self.c, 'VerifyXsrfToken') self.c.VerifyXsrfToken('RetrieveSecret') self.mox.StubOutWithMock(self.c, 'VerifyPermissions') self.c.VerifyPermissions(permissions.RETRIEVE, user='******') self.mox.StubOutWithMock(models.LuksVolume, 'get_by_key_name') models.LuksVolume.get_by_key_name(volume_uuid).AndReturn(mock_entity) 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 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 VerifyAllPermissionTypes(self, required_permission, user=None): """Verifies if a user has the required_permission for all permission types. Args: required_permission: permission string from permissions.*. user: optional, models.User entity; default current user. Returns: Dict. Keys are permissions.TYPES values, and value booleans, True when the user has the required_permission for the permission type, False otherwise. """ if user is None: user = models.GetCurrentUser() perms = {} for permission_type in permissions.TYPES: try: user = self.VerifyPermissions(required_permission, user=user, permission_type=permission_type) perms[permission_type] = True except models.AccessDeniedError: perms[permission_type] = False # TODO(user): if use of this method widens, consider returning a # collections.namedtuple instead of a basic dict. return perms
def get(self): params = collections.defaultdict(dict) search_perms = handlers.VerifyAllPermissionTypes(permissions.SEARCH) 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 can_retrieve_own = False retrieve_own_perms = handlers.VerifyAllPermissionTypes( permissions.RETRIEVE_OWN) for volume_type in retrieve_own_perms: if retrieve_own_perms[volume_type]: params[volume_type][permissions.RETRIEVE_OWN] = True can_retrieve_own = True if can_retrieve_own: params['user'] = models.GetCurrentUser().user.nickname() self.response.out.write(util.ToSafeJson(params))
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 RetrieveSecret(self, volume_uuid): """Handles a GET request to retrieve a secret.""" self.VerifyXsrfToken(base_settings.GET_PASSPHRASE_ACTION) if self.request.get('id'): try: entity = self.SECRET_MODEL.get(db.Key(self.request.get('id'))) except datastore_errors.BadKeyError: raise models.AccessError('volume id is malformed') else: entity = self.SECRET_MODEL.GetLatestByUuid(volume_uuid, tag=self.request.get( 'tag', 'default')) if not entity: raise models.AccessError('Volume not found: %s' % volume_uuid) user = models.GetCurrentUser() self.CheckRetrieveAuthorization(entity=entity, user=user) self.AUDIT_LOG_MODEL.Log(message='GET', entity=entity, request=self.request) # Send retrieval email if user is not retrieving their own secret. if entity.owner not in (user.user.email(), user.user.nickname()): SendRetrievalEmail(self.PERMISSION_TYPE, entity, user) escrow_secret = str(entity.secret).strip() if isinstance(entity, models.ProvisioningVolume): # We don't want to display barcodes for users retrieving provisioning # passwords as seeing the barcodes frightens and confuses them. escrow_barcode_svg = None qr_img_url = None else: escrow_barcode_svg = None if len(escrow_secret) <= 100: qr_img_url = ( 'https://chart.googleapis.com/chart?chs=245x245&cht=qr&chl=' + cgi.escape(escrow_secret)) else: qr_img_url = None if entity.ESCROW_TYPE_NAME == models.ProvisioningVolume.ESCROW_TYPE_NAME: recovery_str = 'Temporary password' else: recovery_str = '%s key' % entity.ESCROW_TYPE_NAME params = { 'volume_type': self.SECRET_MODEL.ESCROW_TYPE_NAME, 'volume_uuid': entity.volume_uuid, 'qr_img_url': qr_img_url, 'escrow_secret': escrow_secret, 'checksum': entity.checksum, 'recovery_str': recovery_str, } params[self.JSON_SECRET_NAME] = escrow_secret self.response.out.write(util.ToSafeJson(params))
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. """ # TODO(user): Consider making the method accept a list of checks # to be performed, making CheckRetrieveAuthorization simpler. permission_type = permission_type or self.PERMISSION_TYPE if user is None: user = models.GetCurrentUser() VerifyPermissions(required_permission, user, permission_type) return user
def XsrfTokenValidate(token, action, user=None, timestamp=None, time_=time): """Generate an XSRF token.""" if not token: return False if not user: # TODO(user): drop the unused user arg, find a way to cache user. user = models.GetCurrentUser().email if not timestamp: try: # Request objects return Unicode encoded tokens. token = token.encode('utf-8') _, timestr = base64.urlsafe_b64decode(token).split( XSRF_DELIMITER, 1) timestamp = float(timestr) except ValueError: logging.exception('ValueError obtaining timestamp from token: %s', token) return False if timestamp + XSRF_VALID_TIME < time_.time(): return False if token != XsrfTokenGenerate(action, user, timestamp): return False return True
def testGaia(self): self.mox.StubOutWithMock(models.users, 'get_current_user') models.users.get_current_user().AndReturn('user') self.mox.ReplayAll() self.assertEqual('user', models.GetCurrentUser()) self.mox.VerifyAll()
def testGetCurrentUser(self): self.mox.StubOutWithMock(models.User, 'get_by_key_name') mock_user_entity = self.mox.CreateMockAnything() models.User.get_by_key_name(self.user_email).AndReturn(mock_user_entity) self.mox.ReplayAll() self.assertEqual(mock_user_entity, models.GetCurrentUser()) self.mox.VerifyAll()
def testGetCurrentUser(self): self.testbed.setup_env(user_email='*****@*****.**', overwrite=True) user = models.GetCurrentUser() self.assertEqual('*****@*****.**', user.user.email()) self.assertEqual(0, len(user.bitlocker_perms)) self.assertEqual(0, len(user.duplicity_perms)) self.assertEqual(0, len(user.filevault_perms)) self.assertEqual(0, len(user.luks_perms))
def _CreateNewSecretEntity(self, owner, volume_uuid, secret): user = models.GetCurrentUser() platform = self.request.get('platform') # Set default platform to Mac if not platform: platform = 'Mac' return models.ProvisioningVolume(owner=owner, volume_uuid=volume_uuid, passphrase=str(secret))
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 XsrfTokenGenerate(action, user=None, timestamp=None): """Generate an XSRF token.""" if not user: # TODO(user): drop the unused user arg, find a way to cache user. user = models.GetCurrentUser().email if not timestamp: timestamp = time.time() timestr = str(timestamp) secret = crypto.ENCRYPTION_KEY_TYPES[settings.KEY_TYPE_DEFAULT_XSRF]() h = hmac.new(secret, XSRF_DELIMITER.join((user, action, timestr))) return base64.b64encode(''.join((h.digest(), XSRF_DELIMITER, timestr)))
def RetrieveSecret(self, secret_id): """Handles a GET request to retrieve a secret.""" try: self.VerifyXsrfToken(base_settings.GET_PASSPHRASE_ACTION) except models.AccessDeniedError as er: # Send the exception message for non-JSON requests. if self.request.get('json', '1') == '0': self.response.out.write(str(er)) return raise entity = self.SECRET_MODEL.get_by_key_name(secret_id) if not entity: raise models.AccessError('Secret not found: %s' % secret_id) user = models.GetCurrentUser() self.CheckRetrieveAuthorization(entity=entity, user=user) self.AUDIT_LOG_MODEL.Log(message='GET', entity=entity, request=self.request) # Send retrieval email if user is not retrieving their own secret. if entity.owner not in (user.user.email(), user.user.nickname()): self.SendRetrievalEmail(entity, user) escrow_secret = str(entity.secret).strip() if self.request.get('json', '1') == '0': if isinstance(entity, models.ProvisioningVolume): # We don't want to display barcodes for users retrieving provisioning # passwords as seeing the barcodes frightens and confuses them. escrow_barcode_svg = None qr_img_url = None else: escrow_barcode_svg = None if len(escrow_secret) <= 100: qr_img_url = ( 'https://chart.googleapis.com/chart?chs=245x245&cht=qr&chl=' + cgi.escape(escrow_secret)) else: qr_img_url = None params = { 'qr_img_url': qr_img_url, 'escrow_secret': escrow_secret, 'escrow_entity': entity, } self.RenderTemplate('barcode_result.html', params) else: data = {self.JSON_SECRET_NAME: escrow_secret} self.response.out.write(JSON_PREFIX + json.dumps(data))
def RetrieveSecret(self, secret_id): """Handles a GET request to retrieve a secret.""" try: self.VerifyXsrfToken(base_settings.GET_PASSPHRASE_ACTION) except models.AccessDeniedError as er: # Send the exception message for non-JSON requests. if self.request.get('json', '1') == '0': self.response.out.write(str(er)) return raise user = models.GetCurrentUser() try: self.VerifyPermissions(permissions.RETRIEVE, user=user) verify_owner = False except models.AccessDeniedError: self.VerifyPermissions(permissions.RETRIEVE_OWN, user=user) verify_owner = True entity = self.SECRET_MODEL.get_by_key_name(secret_id) if not entity: raise models.AccessError('Secret not found: %s' % secret_id) if verify_owner: if entity.owner not in (user.email, user.user.nickname()): raise models.AccessError( 'Attempt to access unowned secret: %s' % secret_id) self.AUDIT_LOG_MODEL.Log(message='GET', entity=entity, request=self.request) self.SendRetrievalEmail(entity, user) escrow_secret = str(entity.passphrase).strip() if self.request.get('json', '1') == '0': escrow_barcode_svg = None if len(escrow_secret) <= 100: qr_img_url = ( 'https://chart.googleapis.com/chart?chs=245x245&cht=qr&chl=' + cgi.escape(escrow_secret)) else: qr_img_url = None params = { 'escrow_secret': escrow_secret, 'qr_img_url': qr_img_url, } self.RenderTemplate('barcode_result.html', params) else: data = {self.JSON_SECRET_NAME: escrow_secret} self.response.out.write(JSON_PREFIX + json.dumps(data))
def testGetCurrentUserWhenNewAdmin(self): self.testbed.setup_env(user_email='*****@*****.**', user_is_admin='1', overwrite=True) self.mox.ReplayAll() user = models.GetCurrentUser() self.mox.VerifyAll() self.assertEqual('*****@*****.**', user.user.email()) self.assertNotEqual(0, len(user.bitlocker_perms)) self.assertNotEqual(0, len(user.duplicity_perms)) self.assertNotEqual(0, len(user.filevault_perms)) self.assertNotEqual(0, len(user.luks_perms))
def get(self, action=None): """Handles GET requests.""" if not action: self.error(httplib.NOT_FOUND) return try: models.GetCurrentUser() except models.AccessDeniedError: self.error(httplib.UNAUTHORIZED) return self.response.headers['Content-Type'] = 'text/plain' self.response.out.write(util.XsrfTokenGenerate(action))
def testGetModelUser(self): self.mox.StubOutWithMock(models.users, 'get_current_user') self.mox.StubOutWithMock(models.User, 'get_by_key_name') mock_user = self.mox.CreateMockAnything() mock_user_entity = self.mox.CreateMockAnything() models.users.get_current_user().AndReturn(mock_user) mock_user.email().AndReturn('*****@*****.**') models.User.get_by_key_name('*****@*****.**').AndReturn( mock_user_entity) self.mox.ReplayAll() self.assertEqual(mock_user_entity, models.GetCurrentUser(get_model_user=True)) 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 testGetCurrentUserWhenNewAdmin(self): self.testbed.setup_env(user_is_admin='1', overwrite=True) mock_user = models.users.get_current_user() self.mox.StubOutWithMock(models, 'User') mock_user_entity = self.mox.CreateMockAnything() models.User.get_by_key_name(self.user_email).AndReturn(None) models.User(key_name=self.user_email, user=mock_user).AndReturn( mock_user_entity) for permission_type in models.permissions.TYPES: mock_user_entity.SetPerms( models.permissions.SET_REGULAR, permission_type).AndReturn(None) mock_user_entity.put().AndReturn(None) self.mox.ReplayAll() self.assertEqual(mock_user_entity, models.GetCurrentUser()) self.mox.VerifyAll()
def VerifyDomainUser(self): """Verifies the current user is of the expected domain. Returns: users.User object of the current user. Raises: models.FileVaultAccessDeniedError: the user was unknown or not a member of the expected domain. """ user = models.GetCurrentUser() if not user: raise models.FileVaultAccessDeniedError('User is unknown.', self.request) elif not user.email().endswith('@%s' % settings.AUTH_DOMAIN): raise models.FileVaultAccessDeniedError( 'User (%s) is not a member of the expected domain (%s)' % (user.email(), settings.AUTH_DOMAIN), self.request) return user
def testInvalidVolumeUUID(self): self.mox.StubOutWithMock(models, 'GetCurrentUser') models.GetCurrentUser().AndReturn('mock_user') self.mox.StubOutWithMock(self.c, 'VerifyXsrfToken') self.c.VerifyXsrfToken('RetrieveSecret') self.mox.StubOutWithMock(self.c, 'VerifyPermissions') self.c.VerifyPermissions(permissions.RETRIEVE, user='******').AndReturn('user') self.mox.StubOutWithMock(models.LuksVolume, 'get_by_key_name') volume_uuid = 'does-not-exist' models.LuksVolume.get_by_key_name(volume_uuid).AndReturn(None) self.mox.ReplayAll() self.assertRaises(models.AccessError, self.c.RetrieveSecret, volume_uuid) self.mox.VerifyAll()
def RenderTemplate(self, template_path, params, response_out=True): """Renders a template of a given path and optionally writes to response. Args: template_path: str, template name or relative path to the base template dir as defined in settings. params: dictionary, key/values to send to the template.render(). response_out: boolean, True to write to self.response.out(), False to simply return the rendered HTML str. Returns: String rendered HTML if response_out == False, otherwise None. """ user = models.GetCurrentUser() params['user'] = user html = template.render(os.path.join(TEMPLATE_DIR, template_path), params) if response_out: self.response.out.write(html) else: return html
def VerifyPermissions(self, required_permission, user=None): """Verifies a valid user is logged in. Args: required_permission: permission string from permissions.*. user: optional, models.User entity; default current user. Returns: models.User object of the current user. Raises: models.FileVaultAccessDeniedError: there was a permissions issue. """ if user is None: user = models.GetCurrentUser(get_model_user=True) if not user: raise models.FileVaultAccessDeniedError('Unknown user', self.request) elif not user.HasPerm(required_permission): raise models.FileVaultAccessDeniedError( 'User lacks %s permission' % required_permission, self.request) return user
def testGetModelUserWhenNewAdmin(self): self.mox.StubOutWithMock(models.users, 'get_current_user') self.mox.StubOutWithMock(models.User, 'get_by_key_name') self.mox.StubOutWithMock(models.users, 'is_current_user_admin') self.mox.StubOutWithMock(models, 'User') email = '*****@*****.**' mock_user = self.mox.CreateMockAnything() mock_user_entity = self.mox.CreateMockAnything() models.users.get_current_user().AndReturn(mock_user) mock_user.email().AndReturn(email) models.User.get_by_key_name(email).AndReturn(None) models.users.is_current_user_admin().AndReturn(True) mock_user.email().AndReturn(email) models.User(key_name=email).AndReturn(mock_user_entity) mock_user.email().AndReturn(email) mock_user_entity.put().AndReturn(None) self.mox.ReplayAll() self.assertEqual(mock_user_entity, models.GetCurrentUser(get_model_user=True)) self.mox.VerifyAll()
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)
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))