Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: appengine/chromium_build_logs/third_party/oauth2client/service_account.py

Issue 1260293009: make version of ts_mon compatible with appengine (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: clean up code Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2014 Google Inc. All rights reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 """A service account credentials class.
16
17 This credentials class is implemented on top of rsa library.
18 """
19
20 import base64
21 import six
22 import time
23
24 from pyasn1.codec.ber import decoder
25 from pyasn1_modules.rfc5208 import PrivateKeyInfo
26 import rsa
27
28 from oauth2client import GOOGLE_REVOKE_URI
29 from oauth2client import GOOGLE_TOKEN_URI
30 from oauth2client._helpers import _json_encode
31 from oauth2client._helpers import _urlsafe_b64encode
32 from oauth2client import util
33 from oauth2client.client import AssertionCredentials
34
35
36 class _ServiceAccountCredentials(AssertionCredentials):
37 """Class representing a service account (signed JWT) credential."""
38
39 MAX_TOKEN_LIFETIME_SECS = 3600 # 1 hour in seconds
40
41 def __init__(self, service_account_id, service_account_email, private_key_id,
42 private_key_pkcs8_text, scopes, user_agent=None,
43 token_uri=GOOGLE_TOKEN_URI, revoke_uri=GOOGLE_REVOKE_URI,
44 **kwargs):
45
46 super(_ServiceAccountCredentials, self).__init__(
47 None, user_agent=user_agent, token_uri=token_uri, revoke_uri=revoke_uri)
48
49 self._service_account_id = service_account_id
50 self._service_account_email = service_account_email
51 self._private_key_id = private_key_id
52 self._private_key = _get_private_key(private_key_pkcs8_text)
53 self._private_key_pkcs8_text = private_key_pkcs8_text
54 self._scopes = util.scopes_to_string(scopes)
55 self._user_agent = user_agent
56 self._token_uri = token_uri
57 self._revoke_uri = revoke_uri
58 self._kwargs = kwargs
59
60 def _generate_assertion(self):
61 """Generate the assertion that will be used in the request."""
62
63 header = {
64 'alg': 'RS256',
65 'typ': 'JWT',
66 'kid': self._private_key_id
67 }
68
69 now = int(time.time())
70 payload = {
71 'aud': self._token_uri,
72 'scope': self._scopes,
73 'iat': now,
74 'exp': now + _ServiceAccountCredentials.MAX_TOKEN_LIFETIME_SECS,
75 'iss': self._service_account_email
76 }
77 payload.update(self._kwargs)
78
79 first_segment = _urlsafe_b64encode(_json_encode(header)).encode('utf-8')
80 second_segment = _urlsafe_b64encode(_json_encode(payload)).encode('utf-8')
81 assertion_input = first_segment + b'.' + second_segment
82
83 # Sign the assertion.
84 rsa_bytes = rsa.pkcs1.sign(assertion_input, self._private_key, 'SHA-256')
85 signature = base64.urlsafe_b64encode(rsa_bytes).rstrip(b'=')
86
87 return assertion_input + b'.' + signature
88
89 def sign_blob(self, blob):
90 # Ensure that it is bytes
91 try:
92 blob = blob.encode('utf-8')
93 except AttributeError:
94 pass
95 return (self._private_key_id,
96 rsa.pkcs1.sign(blob, self._private_key, 'SHA-256'))
97
98 @property
99 def service_account_email(self):
100 return self._service_account_email
101
102 @property
103 def serialization_data(self):
104 return {
105 'type': 'service_account',
106 'client_id': self._service_account_id,
107 'client_email': self._service_account_email,
108 'private_key_id': self._private_key_id,
109 'private_key': self._private_key_pkcs8_text
110 }
111
112 def create_scoped_required(self):
113 return not self._scopes
114
115 def create_scoped(self, scopes):
116 return _ServiceAccountCredentials(self._service_account_id,
117 self._service_account_email,
118 self._private_key_id,
119 self._private_key_pkcs8_text,
120 scopes,
121 user_agent=self._user_agent,
122 token_uri=self._token_uri,
123 revoke_uri=self._revoke_uri,
124 **self._kwargs)
125
126
127 def _get_private_key(private_key_pkcs8_text):
128 """Get an RSA private key object from a pkcs8 representation."""
129
130 if not isinstance(private_key_pkcs8_text, six.binary_type):
131 private_key_pkcs8_text = private_key_pkcs8_text.encode('ascii')
132 der = rsa.pem.load_pem(private_key_pkcs8_text, 'PRIVATE KEY')
133 asn1_private_key, _ = decoder.decode(der, asn1Spec=PrivateKeyInfo())
134 return rsa.PrivateKey.load_pkcs1(
135 asn1_private_key.getComponentByName('privateKey').asOctets(),
136 format='DER')
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698