【问题标题】:How can we check if our app is installed for some organizations but not all of them?我们如何检查我们的应用程序是否已为某些组织而不是所有组织安装?
【发布时间】:2015-10-04 09:15:47
【问题描述】:

我们为 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: 我尝试调用 check_general_access,但当我们的应用程序被卸载时,我们收到 True(应用程序具有一般访问权限)。这是在我们确认 check_access 返回 False 之后。

@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

【问题讨论】:

  • 请详细解释“为组织安装”是什么意思!
  • @KlausD。请查看我更新的问题。
  • 更新没有说清楚。
  • @Alex.S Google Apps 域的管理员,当他安装我们的应用程序时,他可以选择“为所有人开启”、“为选定的组织开启”或“关闭”。但是我们的应用只有在“所有人都可以使用”的情况下才有效
  • 我也不明白这个问题。除了代码的sn-p之外,我还想看一个问题。我很惊讶它没有被标记。

标签: python google-apps google-apps-marketplace


【解决方案1】:

不确定,但可能已经找到了方法。从文档中,我断言需要域范围的访问来模拟目标域中的用户。服务应用程序不需要它来执行其他任务。虽然令人费解,但您可以测试是否获得了不带 SignedJwtAssertionCredentials 的 sub 参数的凭据。如果此操作成功,但添加 sub 参数失败,则说明您已安装但不是域范围的。

让我们知道这是否可行,显然谷歌还有一些工作要做。

【讨论】:

  • 感谢您的回答,但它不起作用。请看我的第二次更新。
【解决方案2】:

您可以每隔一小时左右添加 ping 返回某个端点。如果 ping 太早,他们可能会删除该应用

【讨论】:

  • 我们想在特定时间检查我们的应用程序的状态是什么——“为所有人开启”、“为选定的组织开启”或“关闭”。我不明白您所说的“ping back”和“call some end point”是什么意思,请更具体一点。
  • 你可以使用developers.google.com/cloud-messaging 有两种方法可以用 GCM 实现你想要的。如果您使用更简单的 HTTP 连接到 GCM 服务器,您的服务器会向 GCM 服务器发送一个 HTTP 请求,后者将消息传递到您的设备。您的设备必须创建自己的与服务器的连接才能将数据发送回服务器(ping 回服务器)。
  • 我想知道我可以向 Google 发送哪条消息以确定我们的应用程序是如何安装(或未安装)的。我正在寻找一个具体的答案。我看到了你提到的链接,但我没有在那里找到答案。请注意,我们的应用并非适用于 android 或 ios,而是适用于 Google 应用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-20
  • 2014-12-13
  • 1970-01-01
  • 1970-01-01
  • 2022-11-04
相关资源
最近更新 更多