提问人:Uri 提问时间:10/4/2015 最后编辑:Uri 更新时间:11/10/2015 访问量:873
我们如何检查是否为某些组织安装了我们的应用程序,但不是所有组织?
How can we check if our app is installed for some organizations but not all of them?
问:
我们为 Google Apps Marketplace 创建了一个应用程序。我们的应用程序只有在为所有人安装时才有效。但问题是,一些客户为某些组织安装我们的应用程序,而不是每个人。我们希望向这些客户显示特定消息,但问题是我们不知道我们的应用程序是为某些组织安装的,还是根本没有安装。因此,为某些组织安装我们的应用程序的客户会收到一条消息,该消息适用于根本没有安装我们应用程序的客户。我们向他们展示了安装按钮,但当他们再次安装我们的应用程序时没有任何反应,因为它已经安装。我们想向他们说明如何将我们的应用程序状态更改为“面向所有人”。
我们如何检查某些组织是否安装了我们的应用程序?我们从 Google 收到以下错误消息:
Failed to retrieve access token: {
"error" : "unauthorized_client",
"error_description" : "Unauthorized client or scope in request."
}
这与我们收到的根本没有安装我们的应用程序的客户相同的错误消息相同。
这是抛出异常的 Python 函数:
def _do_refresh_request(self, http_request):
"""Refresh the access_token using the refresh_token.
Args:
http_request: callable, a callable that matches the method signature of
httplib2.Http.request, used to make the refresh request.
Raises:
AccessTokenRefreshError: When the refresh fails.
"""
body = self._generate_refresh_request_body()
headers = self._generate_refresh_request_headers()
logger.info('Refreshing access_token')
resp, content = http_request(
self.token_uri, method='POST', body=body, headers=headers)
if resp.status == 200:
# TODO(jcgregorio) Raise an error if loads fails?
d = simplejson.loads(content)
self.token_response = d
self.access_token = d['access_token']
self.refresh_token = d.get('refresh_token', self.refresh_token)
if 'expires_in' in d:
self.token_expiry = datetime.timedelta(
seconds=int(d['expires_in'])) + datetime.datetime.utcnow()
else:
self.token_expiry = None
if self.store:
self.store.locked_put(self)
else:
# An {'error':...} response body means the token is expired or revoked,
# so we flag the credentials as such.
logger.info('Failed to retrieve access token: %s' % content)
error_msg = 'Invalid response %s.' % resp['status']
try:
d = simplejson.loads(content)
if 'error' in d:
error_msg = d['error']
self.invalid = True
if self.store:
self.store.locked_put(self)
except StandardError:
pass
raise AccessTokenRefreshError(error_msg)
更新 1:在应用>市场应用中,应用可以为所有人启用、为选定组织启用或关闭。我们需要知道应用程序的状态。
更新2:我尝试调用,但是当我们的应用程序被卸载时,我们收到True(应用程序具有常规访问权限)。这是在我们确认返回 False 之后。check_general_access
check_access
@staticmethod
def check_access(admin_email):
http = httplib2.Http()
credentials = SignedJwtAssertionCredentials(
SERVICE_EMAIL,
PRIVATE_KEY,
scope='https://apps-apis.google.com/a/feeds/emailsettings/2.0/ https://www.googleapis.com/auth/admin.directory.user.readonly',
sub=str(admin_email),
)
http = credentials.authorize(http)
try:
service = build(serviceName='admin', version='directory_v1', http=http)
logging.info("Application has access to admin's %s domain" % (admin_email))
return True
except Exception as e:
logging.info("Application does not have access to admin's %s domain (exception: %s)" % (admin_email, e.message))
return False
@staticmethod
def check_general_access():
http = httplib2.Http()
credentials = SignedJwtAssertionCredentials(
SERVICE_EMAIL,
PRIVATE_KEY,
scope='https://apps-apis.google.com/a/feeds/emailsettings/2.0/ https://www.googleapis.com/auth/admin.directory.user.readonly',
)
http = credentials.authorize(http)
try:
service = build(serviceName='admin', version='directory_v1', http=http)
logging.info("Application has general access")
return True
except Exception as e:
logging.info("Application does not have general access (exception: %s)" % e.message)
return False
答:
您可以每隔一小时左右调用某个端点即可添加 ping 回。如果 ping 太久了,他们可能会删除该应用程序
评论
不确定,但可能已经找到了方法。在文档中,我断言需要域范围的访问权限来模拟目标域中的用户。服务应用不需要它来执行其他任务。虽然很复杂,但您可以测试是否获取了没有 SignedJwtAssertionCredentials 的 sub 参数的凭据。如果此操作成功,但添加 sub 参数失败,则表示已安装,但不在域范围内安装。
让我们知道这是否可行,显然谷歌还有一些工作要做。
评论