1.9.30 sync.
[gae.git] / python / google / appengine / api / user_service_stub.py
blobf8a3fb5460ab31f31a7062daf87a51ea4324642d
1 #!/usr/bin/env python
3 # Copyright 2007 Google Inc.
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
22 """Trivial implementation of the UserService."""
27 import os
28 import urllib
29 import urlparse
30 from google.appengine.api import apiproxy_stub
31 from google.appengine.api import user_service_pb
33 if os.environ.get('APPENGINE_RUNTIME') == 'python27':
34 from google.appengine.runtime import apiproxy_errors
35 else:
36 from google.appengine.runtime import apiproxy_errors
38 _DEFAULT_LOGIN_URL = 'https://www.google.com/accounts/Login?continue=%s'
39 _DEFAULT_LOGOUT_URL = 'https://www.google.com/accounts/Logout?continue=%s'
40 _DEFAULT_AUTH_DOMAIN = 'gmail.com'
45 _OAUTH_CONSUMER_KEY = 'example.com'
46 _OAUTH_EMAIL = 'example@example.com'
47 _OAUTH_USER_ID = '0'
48 _OAUTH_AUTH_DOMAIN = _DEFAULT_AUTH_DOMAIN
49 _OAUTH_CLIENT_ID = '123456789.apps.googleusercontent.com'
52 class UserServiceStub(apiproxy_stub.APIProxyStub):
53 """Trivial implementation of the UserService."""
55 _ACCEPTS_REQUEST_ID = True
57 THREADSAFE = True
59 def __init__(self,
60 login_url=_DEFAULT_LOGIN_URL,
61 logout_url=_DEFAULT_LOGOUT_URL,
62 service_name='user',
63 auth_domain=_DEFAULT_AUTH_DOMAIN,
64 request_data=None):
65 """Initializer.
67 Args:
68 login_url: String containing the URL to use for logging in.
69 logout_url: String containing the URL to use for logging out.
70 service_name: Service name expected for all calls.
71 auth_domain: The authentication domain for the service e.g. "gmail.com".
72 request_data: A apiproxy_stub.RequestData instance used to look up state
73 associated with the request that generated an API call.
75 Note: Both the login_url and logout_url arguments must contain one format
76 parameter, which will be replaced with the continuation URL where the user
77 should be redirected after log-in or log-out has been completed.
78 """
79 super(UserServiceStub, self).__init__(service_name,
80 request_data=request_data)
81 self._login_url = login_url
82 self._logout_url = logout_url
83 self.__scopes = None
85 self.SetOAuthUser(is_admin=(os.environ.get('OAUTH_IS_ADMIN', '0') == '1'))
90 os.environ['AUTH_DOMAIN'] = auth_domain
92 def SetOAuthUser(self,
93 email=_OAUTH_EMAIL,
94 domain=_OAUTH_AUTH_DOMAIN,
95 user_id=_OAUTH_USER_ID,
96 is_admin=False,
97 scopes=None,
98 client_id=_OAUTH_CLIENT_ID):
99 """Set test OAuth user.
101 Determines what user is returned by requests to GetOAuthUser.
103 Args:
104 email: Email address of oauth user. None indicates that no oauth user
105 is authenticated.
106 domain: Domain of oauth user.
107 user_id: User ID of oauth user.
108 is_admin: Whether the user is an admin.
109 scopes: List of scopes that user is authenticated against.
110 client_id: Client ID of the OAuth2 request
112 self.__email = email
113 self.__domain = domain
114 self.__user_id = user_id
115 self.__is_admin = is_admin
116 self.__scopes = scopes
117 self.__client_id = client_id
119 def _Dynamic_CreateLoginURL(self, request, response, request_id):
120 """Trivial implementation of UserService.CreateLoginURL().
122 Args:
123 request: a CreateLoginURLRequest
124 response: a CreateLoginURLResponse
125 request_id: A unique string identifying the request associated with the
126 API call.
128 response.set_login_url(
129 self._login_url %
130 urllib.quote(self._AddHostToContinueURL(request.destination_url(),
131 request_id)))
133 def _Dynamic_CreateLogoutURL(self, request, response, request_id):
134 """Trivial implementation of UserService.CreateLogoutURL().
136 Args:
137 request: a CreateLogoutURLRequest
138 response: a CreateLogoutURLResponse
139 request_id: A unique string identifying the request associated with the
140 API call.
142 response.set_logout_url(
143 self._logout_url %
144 urllib.quote(self._AddHostToContinueURL(request.destination_url(),
145 request_id)))
147 def _Dynamic_GetOAuthUser(self, request, response, request_id):
148 """Trivial implementation of UserService.GetOAuthUser().
150 Args:
151 request: a GetOAuthUserRequest
152 response: a GetOAuthUserResponse
153 request_id: A unique string identifying the request associated with the
154 API call.
156 if self.__email is None:
157 raise apiproxy_errors.ApplicationError(
158 user_service_pb.UserServiceError.OAUTH_INVALID_REQUEST)
159 else:
160 if self.__scopes is None:
161 authorized_scopes = set()
162 else:
164 authorized_scopes = set(request.scopes_list()).intersection(
165 self.__scopes)
166 if not authorized_scopes:
167 raise apiproxy_errors.ApplicationError(
168 user_service_pb.UserServiceError.OAUTH_INVALID_TOKEN)
169 response.set_email(self.__email)
170 response.set_user_id(self.__user_id)
171 response.set_auth_domain(self.__domain)
172 response.set_is_admin(self.__is_admin)
173 response.set_client_id(self.__client_id)
174 if request.request_writer_permission():
175 response.set_is_project_writer(self.__is_admin)
176 for scope in authorized_scopes:
177 response.add_scopes(scope)
179 def _Dynamic_CheckOAuthSignature(self, unused_request, response, request_id):
180 """Trivial implementation of UserService.CheckOAuthSignature().
182 Args:
183 unused_request: a CheckOAuthSignatureRequest
184 response: a CheckOAuthSignatureResponse
185 request_id: A unique string identifying the request associated with the
186 API call.
188 response.set_oauth_consumer_key(_OAUTH_CONSUMER_KEY)
190 def _AddHostToContinueURL(self, continue_url, request_id):
191 """Adds the request host to the continue url if no host is specified.
193 Args:
194 continue_url: the URL which may or may not have a host specified
195 request_id: A unique string identifying the request associated with the
196 API call.
198 Returns:
199 string
201 (protocol, host, path, parameters, query, fragment) = urlparse.urlparse(continue_url)
203 if host and protocol:
204 return continue_url
206 try:
207 protocol, host, _, _, _, _ = urlparse.urlparse(
208 self.request_data.get_request_url(request_id))
209 except KeyError:
213 pass
216 if path == '':
217 path = '/'
219 return urlparse.urlunparse(
220 (protocol, host, path, parameters, query, fragment))