Ejemplo n.º 1
0
 def test_base64_encode_decode(self):
     # Encode a bunch of strings of different lengths to test all
     # possible paddings (to see how padding stripping works).
     msg = 'somewhat long message with binary \x00\x01\x02\x03 inside'
     for i in xrange(len(msg)):
         self.assertEqual(
             msg[:i], tokens.base64_decode(tokens.base64_encode(msg[:i])))
Ejemplo n.º 2
0
 def test_base64_encode_decode(self):
   # Encode a bunch of strings of different lengths to test all
   # possible paddings (to see how padding stripping works).
   msg = 'somewhat long message with binary \x00\x01\x02\x03 inside'
   for i in xrange(len(msg)):
     self.assertEqual(
         msg[:i], tokens.base64_decode(tokens.base64_encode(msg[:i])))
    def test_delegation_token(self):
        # No delegation.
        self.assertEqual(
            {
                'cur_id': 'user:[email protected]',
                'peer_id': 'user:[email protected]'
            }, self.call_with_tokens())

        # Grab a fake-signed delegation token.
        subtoken = delegation_pb2.Subtoken(
            delegated_identity='user:[email protected]',
            kind=delegation_pb2.Subtoken.BEARER_DELEGATION_TOKEN,
            audience=['*'],
            services=['*'],
            creation_time=int(utils.time_time()),
            validity_duration=3600)
        tok_pb = delegation_pb2.DelegationToken(
            serialized_subtoken=subtoken.SerializeToString(),
            signer_id='user:[email protected]',
            signing_key_id='signing-key',
            pkcs1_sha256_sig='fake-signature')
        tok = tokens.base64_encode(tok_pb.SerializeToString())

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

        # Invalid delegation token.
        with self.assertRaises(api.AuthorizationError):
            self.call_with_tokens(delegation_tok=tok + 'blah')
Ejemplo n.º 4
0
  def test_delegation_token(self):
    # Grab a fake-signed delegation token.
    subtoken = delegation_pb2.Subtoken(
        delegated_identity='user:[email protected]',
        kind=delegation_pb2.Subtoken.BEARER_DELEGATION_TOKEN,
        audience=['*'],
        services=['*'],
        creation_time=int(utils.time_time()),
        validity_duration=3600)
    tok_pb = delegation_pb2.DelegationToken(
      serialized_subtoken=subtoken.SerializeToString(),
      signer_id='user:[email protected]',
      signing_key_id='signing-key',
      pkcs1_sha256_sig='fake-signature')
    tok = tokens.base64_encode(tok_pb.SerializeToString())

    # Valid delegation token.
    state, ctx = self.call(
        'ipv4:127.0.0.1', '*****@*****.**', {'X-Delegation-Token-V1': tok})
    self.assertEqual(state, CapturedState(
        current_identity='user:[email protected]',
        is_superuser=False,
        peer_identity='user:[email protected]',
        peer_ip=ipaddr.ip_from_string('127.0.0.1'),
        delegation_token=subtoken,
    ))

    # Invalid delegation token.
    state, ctx = self.call(
        'ipv4:127.0.0.1', '*****@*****.**', {'X-Delegation-Token-V1': tok + 'blah'})
    self.assertIsNone(state)
    self.assertEqual(ctx.code, prpclib.StatusCode.PERMISSION_DENIED)
    self.assertEqual(
        ctx.details, 'Bad delegation token: Bad proto: Truncated message.')
Ejemplo n.º 5
0
 def test_works(self):
     # Note: we can't use verify_jwt in this test because tokens produced by
     # sign_jwt do not have 'kid' header field which is required by verify_jwt.
     expected_hdr = tokens.base64_encode('{"alg":"RS256","typ":"JWT"}')
     expected_claims = tokens.base64_encode(
         utils.encode_to_json({
             'aud': 'some audience',
             'email': '*****@*****.**',
             'exp': 1514772061,  # matches NOW+1h
             'iat': 1514768461,  # matches NOW
             'iss': '*****@*****.**',
             'sub': '*****@*****.**',
         }))
     expected_sig = tokens.base64_encode('signature')
     self.assertEqual(
         tokens.sign_jwt(u'some audience'), '.'.join(
             (expected_hdr, expected_claims, expected_sig)))
     self.assertEqual(self.signed[0], '.'.join(
         (expected_hdr, expected_claims)))
Ejemplo n.º 6
0
  def test_delegation_token(self):
    call = self.make_test_app_with_peer('user:[email protected]')

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

    # Grab a fake-signed delegation token.
    subtoken = delegation_pb2.Subtoken(
        delegated_identity='user:[email protected]',
        kind=delegation_pb2.Subtoken.BEARER_DELEGATION_TOKEN,
        audience=['*'],
        services=['*'],
        creation_time=int(utils.time_time()),
        validity_duration=3600)
    tok_pb = delegation_pb2.DelegationToken(
        serialized_subtoken=subtoken.SerializeToString(),
        signer_id='user:[email protected]',
        signing_key_id='signing-key',
        pkcs1_sha256_sig='fake-signature')
    tok = tokens.base64_encode(tok_pb.SerializeToString())

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

    # With invalid delegation token.
    resp = call({'X-Delegation-Token-V1': tok+'blah'})
    self.assertEqual(403, resp['status'])
    self.assertIn('Bad delegation token', resp['body'])

    # Transient error.
    def mocked_check(*_args):
      raise delegation.TransientError('Blah')
    self.mock(delegation, 'check_bearer_delegation_token', mocked_check)
    resp = call({'X-Delegation-Token-V1': tok})
    self.assertEqual(500, resp['status'])
    self.assertIn('Blah', resp['body'])
Ejemplo n.º 7
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())

        # Grab a fake-signed delegation token.
        subtoken = delegation_pb2.Subtoken(
            delegated_identity='user:[email protected]',
            kind=delegation_pb2.Subtoken.BEARER_DELEGATION_TOKEN,
            audience=['*'],
            services=['*'],
            creation_time=int(utils.time_time()),
            validity_duration=3600)
        tok_pb = delegation_pb2.DelegationToken(
            serialized_subtoken=subtoken.SerializeToString(),
            signer_id='user:[email protected]',
            signing_key_id='signing-key',
            pkcs1_sha256_sig='fake-signature')
        tok = tokens.base64_encode(tok_pb.SerializeToString())

        # 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')
Ejemplo n.º 8
0
  def post(self, app_id):
    # On local dev server |app_id| may use @localhost:8080 to specify where
    # app is running.
    custom_host = None
    if utils.is_local_dev_server():
      app_id, _, custom_host = app_id.partition('@')

    # Generate an opaque ticket that would be passed back to /link_replica.
    # /link_replica will verify HMAC tag and will ensure the request came from
    # application with ID |app_id|.
    ticket = LinkTicketToken.generate([], {'app_id': app_id})

    # ServiceLinkTicket contains information that is needed for Replica
    # to figure out how to contact Primary.
    link_msg = replication_pb2.ServiceLinkTicket()
    link_msg.primary_id = app_identity.get_application_id()
    link_msg.primary_url = self.request.host_url
    link_msg.generated_by = auth.get_current_identity().to_bytes()
    link_msg.ticket = ticket

    # Special case for dev server to simplify local development.
    if custom_host:
      assert utils.is_local_dev_server()
      host = 'http://%s' % custom_host
    else:
      # Use same domain as auth_service. Usually it's just appspot.com.
      current_hostname = app_identity.get_default_version_hostname()
      domain = current_hostname.partition('.')[2]
      naked_app_id = app_id
      if ':' in app_id:
        naked_app_id = app_id[app_id.find(':')+1:]
      host = 'https://%s.%s' % (naked_app_id, domain)

    # URL to a handler on Replica that initiates Replica <-> Primary handshake.
    url = '%s/auth/link?t=%s' % (
        host, tokens.base64_encode(link_msg.SerializeToString()))
    self.send_response({'url': url}, http_code=201)
Ejemplo n.º 9
0
    def post(self, app_id):
        # On local dev server |app_id| may use @localhost:8080 to specify where
        # app is running.
        custom_host = None
        if utils.is_local_dev_server():
            app_id, _, custom_host = app_id.partition('@')

        # Generate an opaque ticket that would be passed back to /link_replica.
        # /link_replica will verify HMAC tag and will ensure the request came from
        # application with ID |app_id|.
        ticket = LinkTicketToken.generate([], {'app_id': app_id})

        # ServiceLinkTicket contains information that is needed for Replica
        # to figure out how to contact Primary.
        link_msg = replication_pb2.ServiceLinkTicket()
        link_msg.primary_id = app_identity.get_application_id()
        link_msg.primary_url = self.request.host_url
        link_msg.generated_by = auth.get_current_identity().to_bytes()
        link_msg.ticket = ticket

        # Special case for dev server to simplify local development.
        if custom_host:
            assert utils.is_local_dev_server()
            host = 'http://%s' % custom_host
        else:
            # Use same domain as auth_service. Usually it's just appspot.com.
            current_hostname = app_identity.get_default_version_hostname()
            domain = current_hostname.partition('.')[2]
            naked_app_id = app_id
            if ':' in app_id:
                naked_app_id = app_id[app_id.find(':') + 1:]
            host = 'https://%s.%s' % (naked_app_id, domain)

        # URL to a handler on Replica that initiates Replica <-> Primary handshake.
        url = '%s/auth/link?t=%s' % (
            host, tokens.base64_encode(link_msg.SerializeToString()))
        self.send_response({'url': url}, http_code=201)
Ejemplo n.º 10
0
 def test_deserialize_huge(self):
   msg = fake_token_proto()
   msg.serialized_subtoken_list = 'huge' * 10000
   tok = tokens.base64_encode(msg.SerializeToString())
   with self.assertRaises(delegation.BadTokenError):
     delegation.deserialize_token(tok)
Ejemplo n.º 11
0
 def make_jwt(self, hdr, payload, sig=SIG):
     return '%s.%s.%s' % (to_json_b64(hdr), to_json_b64(payload),
                          tokens.base64_encode(sig))
Ejemplo n.º 12
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, False)]

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

        # Grab a fake-signed delegation token.
        subtoken = delegation_pb2.Subtoken(
            delegated_identity='user:[email protected]',
            kind=delegation_pb2.Subtoken.BEARER_DELEGATION_TOKEN,
            audience=['*'],
            services=['*'],
            creation_time=int(utils.time_time()),
            validity_duration=3600)
        tok_pb = delegation_pb2.DelegationToken(
            serialized_subtoken=subtoken.SerializeToString(),
            signer_id='user:[email protected]',
            signing_key_id='signing-key',
            pkcs1_sha256_sig='fake-signature')
        tok = tokens.base64_encode(tok_pb.SerializeToString())

        # 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)
Ejemplo n.º 13
0
 def test_base64_encode_types(self):
     with self.assertRaises(TypeError):
         tokens.base64_encode(None)
     with self.assertRaises(TypeError):
         tokens.base64_encode(u'unicode')
Ejemplo n.º 14
0
 def test_base64_encode_is_url_safe(self):
   for a in xrange(255):
     original = chr(a)
     encoded = tokens.base64_encode(original)
     self.assertEqual(original, tokens.base64_decode(encoded))
     self.assertTrue(URL_SAFE_ALPHABET.issuperset(encoded), encoded)
Ejemplo n.º 15
0
 def test_base64_encode_types(self):
   with self.assertRaises(TypeError):
     tokens.base64_encode(None)
   with self.assertRaises(TypeError):
     tokens.base64_encode(u'unicode')
Ejemplo n.º 16
0
 def test_deserialize_bad_proto(self):
     tok = tokens.base64_encode('not a proto')
     with self.assertRaises(delegation.BadTokenError):
         delegation.deserialize_token(tok)
Ejemplo n.º 17
0
def serialize_token(tok):
    return tokens.base64_encode(tok.SerializeToString())
Ejemplo n.º 18
0
 def test_deserialize_huge(self):
     msg = fake_token_proto()
     msg.serialized_subtoken = 'huge' * 10000
     tok = tokens.base64_encode(msg.SerializeToString())
     with self.assertRaises(delegation.BadTokenError):
         delegation.deserialize_token(tok)
Ejemplo n.º 19
0
 def test_deserialize_bad_proto(self):
   tok = tokens.base64_encode('not a proto')
   with self.assertRaises(delegation.BadTokenError):
     delegation.deserialize_token(tok)
Ejemplo n.º 20
0
 def test_base64_encode_is_url_safe(self):
     for a in xrange(255):
         original = chr(a)
         encoded = tokens.base64_encode(original)
         self.assertEqual(original, tokens.base64_decode(encoded))
         self.assertTrue(URL_SAFE_ALPHABET.issuperset(encoded), encoded)
Ejemplo n.º 21
0
def to_json_b64(d):
    return tokens.base64_encode(json.dumps(d, sort_keys=True))