Example #1
0
    def test_delegation_token(self):
        peer_ident = model.Identity.from_bytes('user:[email protected]')

        class Handler(handler.AuthenticatingHandler):
            @classmethod
            def get_auth_methods(cls, conf):
                return [lambda _request: peer_ident]

            @api.public
            def get(self):
                self.response.write(
                    json.dumps({
                        'peer_id': api.get_peer_identity().to_bytes(),
                        'cur_id': api.get_current_identity().to_bytes(),
                    }))

        app = self.make_test_app('/request', Handler)

        def call(headers=None):
            return json.loads(app.get('/request', headers=headers).body)

        # No delegation.
        self.assertEqual(
            {
                u'cur_id': u'user:[email protected]',
                u'peer_id': u'user:[email protected]'
            }, call())

        # TODO(vadimsh): Mint token via some high-level function call.
        subtoken = delegation_pb2.Subtoken(
            delegated_identity='user:[email protected]',
            audience=['*'],
            services=['*'],
            creation_time=int(utils.time_time()),
            validity_duration=3600)
        tok = delegation.serialize_token(delegation.seal_token(subtoken))

        # With valid delegation token.
        self.assertEqual(
            {
                u'cur_id': u'user:[email protected]',
                u'peer_id': u'user:[email protected]'
            }, call({'X-Delegation-Token-V1': tok}))

        # With invalid delegation token.
        r = app.get('/request',
                    headers={'X-Delegation-Token-V1': tok + 'blah'},
                    expect_errors=True)
        self.assertEqual(403, r.status_int)

        # Transient error.
        def mocked_check(*_args):
            raise delegation.TransientError('Blah')

        self.mock(delegation, 'check_bearer_delegation_token', mocked_check)
        r = app.get('/request',
                    headers={'X-Delegation-Token-V1': tok},
                    expect_errors=True)
        self.assertEqual(500, r.status_int)
Example #2
0
 def test_works(self):
     api.reset_local_state()  # to clear request-cached AuthDB
     # Subtoken proto.
     tok = fake_subtoken_proto('user:[email protected]',
                               audience=['user:[email protected]'])
     # Sign, serialize.
     blob = delegation.serialize_token(delegation.seal_token(tok))
     # Deserialize, check sig, validate.
     make_id = model.Identity.from_bytes
     ident = delegation.check_bearer_delegation_token(
         blob, make_id('user:[email protected]'))
     self.assertEqual(make_id('user:[email protected]'), ident)
Example #3
0
  def test_delegation_token(self):
    peer_ident = model.Identity.from_bytes('user:[email protected]')

    class Handler(handler.AuthenticatingHandler):
      @classmethod
      def get_auth_methods(cls, conf):
        return [lambda _request: peer_ident]

      @api.public
      def get(self):
        self.response.write(json.dumps({
          'peer_id': api.get_peer_identity().to_bytes(),
          'cur_id': api.get_current_identity().to_bytes(),
        }))

    app = self.make_test_app('/request', Handler)
    def call(headers=None):
      return json.loads(app.get('/request', headers=headers).body)

    # No delegation.
    self.assertEqual(
        {u'cur_id': u'user:[email protected]', u'peer_id': u'user:[email protected]'}, call())

    # TODO(vadimsh): Mint token via some high-level function call.
    subtokens = delegation_pb2.SubtokenList(subtokens=[
        delegation_pb2.Subtoken(
            issuer_id='user:[email protected]',
            creation_time=int(utils.time_time()),
            validity_duration=3600),
    ])
    tok = delegation.serialize_token(delegation.seal_token(subtokens))

    # With valid delegation token.
    self.assertEqual(
        {u'cur_id': u'user:[email protected]', u'peer_id': u'user:[email protected]'},
        call({'X-Delegation-Token-V1': tok}))

    # With invalid delegation token.
    r = app.get(
        '/request',
        headers={'X-Delegation-Token-V1': tok + 'blah'},
        expect_errors=True)
    self.assertEqual(403, r.status_int)

    # Transient error.
    def mocked_check(*_args):
      raise delegation.TransientError('Blah')
    self.mock(delegation, 'check_delegation_token', mocked_check)
    r = app.get(
        '/request',
        headers={'X-Delegation-Token-V1': tok},
        expect_errors=True)
    self.assertEqual(500, r.status_int)
Example #4
0
    def post(self):
        # Forbid usage of delegation tokens for this particular call. Using
        # delegation when creating delegation tokens is too deep. Redelegation will
        # be done as separate explicit API call that accept existing delegation
        # token via request body, not via headers.
        if auth.get_current_identity() != auth.get_peer_identity():
            raise auth.AuthorizationError(
                'This API call must not be used with active delegation token')

        # Convert request body to proto (with validation). Verify IP format.
        try:
            body = self.parse_body()
            subtoken = subtoken_from_jsonish(body)
            intent = body.get('intent') or ''
            if not isinstance(intent, basestring):
                raise TypeError('"intent" must be string')
        except (TypeError, ValueError) as exc:
            self.abort_with_error(400, text=str(exc))

        # Fill in defaults.
        assert not subtoken.requestor_identity
        user_id = auth.get_current_identity().to_bytes()
        subtoken.requestor_identity = user_id
        if not subtoken.delegated_identity:
            subtoken.delegated_identity = user_id
        subtoken.creation_time = int(utils.time_time())
        if not subtoken.validity_duration:
            subtoken.validity_duration = DEF_VALIDITY_DURATION_SEC
        if '*' in subtoken.services:
            subtoken.services[:] = get_default_allowed_services(user_id)

        # Check ACL (raises auth.AuthorizationError on errors).
        rule = check_can_create_token(user_id, subtoken)

        # Register the token in the datastore, generate its ID.
        subtoken.subtoken_id = register_subtoken(subtoken, rule, intent,
                                                 auth.get_peer_ip())

        # Create and sign the token.
        try:
            token = delegation.serialize_token(delegation.seal_token(subtoken))
        except delegation.BadTokenError as exc:
            # This happens if resulting token is too large.
            self.abort_with_error(400, text=str(exc))

        self.send_response(response={
            'delegation_token': token,
            'subtoken_id': str(subtoken.subtoken_id),
            'validity_duration': subtoken.validity_duration,
        },
                           http_code=201)
Example #5
0
 def test_works(self):
   # Subtoken list proto.
   toks = delegation_pb2.SubtokenList(subtokens=[
     fake_subtoken_proto(
         'user:[email protected]', audience=['user:[email protected]']),
     fake_subtoken_proto(
         'user:[email protected]', audience=['user:[email protected]']),
   ])
   # Sign, serialize.
   blob = delegation.serialize_token(delegation.seal_token(toks))
   # Deserialize, check sig, validate.
   make_id = model.Identity.from_bytes
   ident = delegation.check_delegation_token(blob, make_id('user:[email protected]'))
   self.assertEqual(make_id('user:[email protected]'), ident)
Example #6
0
 def test_works(self):
     # Subtoken list proto.
     toks = delegation_pb2.SubtokenList(subtokens=[
         fake_subtoken_proto('user:[email protected]',
                             audience=['user:[email protected]']),
         fake_subtoken_proto('user:[email protected]',
                             audience=['user:[email protected]']),
     ])
     # Sign, serialize.
     blob = delegation.serialize_token(delegation.seal_token(toks))
     # Deserialize, check sig, validate.
     make_id = model.Identity.from_bytes
     ident = delegation.check_delegation_token(blob,
                                               make_id('user:[email protected]'))
     self.assertEqual(make_id('user:[email protected]'), ident)
Example #7
0
  def post(self):
    # Forbid usage of delegation tokens for this particular call. Using
    # delegation when creating delegation tokens is too deep. Redelegation will
    # be done as separate explicit API call that accept existing delegation
    # token via request body, not via headers.
    if auth.get_current_identity() != auth.get_peer_identity():
      raise auth.AuthorizationError(
          'This API call must not be used with active delegation token')

    # Convert request body to proto (with validation).
    try:
      subtoken = subtoken_from_jsonish(self.parse_body())
    except (TypeError, ValueError) as exc:
      self.abort_with_error(400, text=str(exc))

    # Fill in defaults.
    assert not subtoken.impersonator_id
    user_id = auth.get_current_identity().to_bytes()
    if not subtoken.issuer_id:
      subtoken.issuer_id = user_id
    if subtoken.issuer_id != user_id:
      subtoken.impersonator_id = user_id
    subtoken.creation_time = int(utils.time_time())
    if not subtoken.validity_duration:
      subtoken.validity_duration = DEF_VALIDITY_DURATION_SEC
    if not subtoken.services or '*' in subtoken.services:
      subtoken.services[:] = get_default_allowed_services(user_id)

    # Check ACL (raises auth.AuthorizationError on errors).
    check_can_create_token(user_id, subtoken)

    # Create and sign the token.
    try:
      token = delegation.serialize_token(
          delegation.seal_token(
              delegation_pb2.SubtokenList(subtokens=[subtoken])))
    except delegation.BadTokenError as exc:
      # This happens if resulting token is too large.
      self.abort_with_error(400, text=str(exc))

    self.send_response(
        response={
          'delegation_token': token,
          'validity_duration': subtoken.validity_duration,
        },
        http_code=201)
Example #8
0
    def post(self):
        # Forbid usage of delegation tokens for this particular call. Using
        # delegation when creating delegation tokens is too deep. Redelegation will
        # be done as separate explicit API call that accept existing delegation
        # token via request body, not via headers.
        if auth.get_current_identity() != auth.get_peer_identity():
            raise auth.AuthorizationError(
                'This API call must not be used with active delegation token')

        # Convert request body to proto (with validation).
        try:
            subtoken = subtoken_from_jsonish(self.parse_body())
        except (TypeError, ValueError) as exc:
            self.abort_with_error(400, text=str(exc))

        # Fill in defaults.
        assert not subtoken.impersonator_id
        user_id = auth.get_current_identity().to_bytes()
        if not subtoken.issuer_id:
            subtoken.issuer_id = user_id
        if subtoken.issuer_id != user_id:
            subtoken.impersonator_id = user_id
        subtoken.creation_time = int(utils.time_time())
        if not subtoken.validity_duration:
            subtoken.validity_duration = DEF_VALIDITY_DURATION_SEC
        if not subtoken.services or '*' in subtoken.services:
            subtoken.services[:] = get_default_allowed_services(user_id)

        # Check ACL (raises auth.AuthorizationError on errors).
        check_can_create_token(user_id, subtoken)

        # Create and sign the token.
        try:
            token = delegation.serialize_token(
                delegation.seal_token(
                    delegation_pb2.SubtokenList(subtokens=[subtoken])))
        except delegation.BadTokenError as exc:
            # This happens if resulting token is too large.
            self.abort_with_error(400, text=str(exc))

        self.send_response(response={
            'delegation_token': token,
            'validity_duration': subtoken.validity_duration,
        },
                           http_code=201)
Example #9
0
    def test_delegation_token(self):
        def call(tok=None):
            headers = {'X-Delegation-Token-V1': tok} if tok else None
            self.call('127.0.0.1', '*****@*****.**', headers)
            return {
                'cur_id': api.get_current_identity().to_bytes(),
                'peer_id': api.get_current_identity().to_bytes(),
            }

        # No delegation.
        self.assertEqual(
            {
                'cur_id': 'user:[email protected]',
                'peer_id': 'user:[email protected]'
            }, call())

        # TODO(vadimsh): Mint token via some high-level function call.
        subtokens = delegation_pb2.SubtokenList(subtokens=[
            delegation_pb2.Subtoken(issuer_id='user:[email protected]',
                                    creation_time=int(utils.time_time()),
                                    validity_duration=3600),
        ])
        tok = delegation.serialize_token(delegation.seal_token(subtokens))

        # Valid delegation token.
        self.assertEqual(
            {
                'cur_id': 'user:[email protected]',
                'peer_id': 'user:[email protected]'
            }, call(tok))

        # Invalid delegation token.
        with self.assertRaises(api.AuthorizationError):
            call(tok + 'blah')

        # Transient error.
        def mocked_check(*_args):
            raise delegation.TransientError('Blah')

        self.mock(delegation, 'check_delegation_token', mocked_check)
        with self.assertRaises(endpoints.InternalServerErrorException):
            call(tok)
Example #10
0
  def test_delegation_token(self):
    def call(tok=None):
      headers = {'X-Delegation-Token-V1': tok} if tok else None
      self.call('127.0.0.1', '*****@*****.**', headers)
      return {
        'cur_id': api.get_current_identity().to_bytes(),
        'peer_id': api.get_current_identity().to_bytes(),
      }

    # No delegation.
    self.assertEqual(
        {'cur_id': 'user:[email protected]', 'peer_id': 'user:[email protected]'}, call())

    # TODO(vadimsh): Mint token via some high-level function call.
    subtokens = delegation_pb2.SubtokenList(subtokens=[
        delegation_pb2.Subtoken(
            issuer_id='user:[email protected]',
            creation_time=int(utils.time_time()),
            validity_duration=3600),
    ])
    tok = delegation.serialize_token(delegation.seal_token(subtokens))

    # Valid delegation token.
    self.assertEqual(
        {'cur_id': 'user:[email protected]', 'peer_id': 'user:[email protected]'},
        call(tok))

    # Invalid delegation token.
    with self.assertRaises(api.AuthorizationError):
      call(tok + 'blah')

    # Transient error.
    def mocked_check(*_args):
      raise delegation.TransientError('Blah')
    self.mock(delegation, 'check_delegation_token', mocked_check)
    with self.assertRaises(endpoints.InternalServerErrorException):
      call(tok)
Example #11
0
 def test_unknown_signer_id(self):
     checker = delegation.SignatureChecker()  # empty, no trusted signers
     self.mock(delegation, 'get_signature_checker', lambda: checker)
     with self.assertRaises(delegation.BadTokenError):
         delegation.unseal_token(
             delegation.seal_token(fake_subtoken_list_proto()))
Example #12
0
 def test_round_trip(self):
   toks = fake_subtoken_list_proto()
   self.assertEqual(toks, delegation.unseal_token(delegation.seal_token(toks)))
Example #13
0
 def test_unknown_signing_key_id(self):
   msg = delegation.seal_token(fake_subtoken_list_proto())
   msg.signing_key_id = 'blah'
   with self.assertRaises(delegation.BadTokenError):
     delegation.unseal_token(msg)
Example #14
0
 def test_bad_signature(self):
   msg = delegation.seal_token(fake_subtoken_list_proto())
   msg.pkcs1_sha256_sig = msg.pkcs1_sha256_sig[:-1] + 'A'
   with self.assertRaises(delegation.BadTokenError):
     delegation.unseal_token(msg)
Example #15
0
 def test_bad_signer_id(self):
   msg = delegation.seal_token(fake_subtoken_list_proto())
   msg.signer_id = 'not an identity'
   with self.assertRaises(delegation.BadTokenError):
     delegation.unseal_token(msg)
Example #16
0
 def test_unknown_signer_id(self):
   checker = delegation.SignatureChecker() # empty, no trusted signers
   self.mock(delegation, 'get_signature_checker', lambda: checker)
   with self.assertRaises(delegation.BadTokenError):
     delegation.unseal_token(delegation.seal_token(fake_subtoken_list_proto()))
Example #17
0
 def test_unknown_signing_key_id(self):
     msg = delegation.seal_token(fake_subtoken_proto())
     msg.signing_key_id = 'blah'
     with self.assertRaises(delegation.BadTokenError):
         delegation.unseal_token(msg)
Example #18
0
 def test_bad_signature(self):
     msg = delegation.seal_token(fake_subtoken_proto())
     msg.pkcs1_sha256_sig = msg.pkcs1_sha256_sig[:-1] + 'A'
     with self.assertRaises(delegation.BadTokenError):
         delegation.unseal_token(msg)
Example #19
0
 def test_unknown_signer_id(self):
     # Empty dict, no trusted signers.
     self.mock(delegation, 'get_trusted_signers', lambda: {})
     with self.assertRaises(delegation.BadTokenError):
         delegation.unseal_token(
             delegation.seal_token(fake_subtoken_proto()))
Example #20
0
 def test_bad_signer_id(self):
     msg = delegation.seal_token(fake_subtoken_proto())
     msg.signer_id = 'not an identity'
     with self.assertRaises(delegation.BadTokenError):
         delegation.unseal_token(msg)
Example #21
0
 def test_round_trip(self):
     tok = fake_subtoken_proto()
     self.assertEqual(tok,
                      delegation.unseal_token(delegation.seal_token(tok)))