如何通过Python使用gpg加密的oauth文件进行offlineimap

mat*_*ath 6 python gnupg oauth-2.0

我正在玩oauth2以更好地理解它.出于这个原因,我安装了offlineimap,它应该充当第三方应用程序.我发现一个很好的方式,对这里读取加密凭证stackexchange.

基于链接的帖子,我修改/复制了以下python脚本:

import subprocess
import os
import json

def passwd(file_name):
  acct = os.path.basename(file_name)
  path = "/PATHTOFILE/%s" % file_name
  args = ["gpg", "--use-agent", "--quiet", "--batch", "-d", path]
  try:
    return subprocess.check_output(args).strip()
  except subprocess.CalledProcessError:
    return ""

def oauthpasswd(acct, key):
  acct = os.path.basename(acct)
  path = "/PATHTOFILE/%s_oauth2.gpg" % acct
  args = ["gpg", "--use-agent", "--quiet", "--batch", "-d", path]
  try:
    return str(json.loads(subprocess.check_output(args).strip())['installed'][key])
  except subprocess.CalledProcessError:
    return ""

def prime_gpg_agent():
  ret = False
  i = 1
  while not ret:
    ret = (passwd("prime.gpg") == "prime")
    if i > 2:
      from offlineimap.ui import getglobalui
      sys.stderr.write("Error reading in passwords. Terminating.\n")
      getglobalui().terminate()
    i += 1
  return ret

prime_gpg_agent()
Run Code Online (Sandbox Code Playgroud)

在相应的offlineimaprc文件中,我使用正确的参数调用该函数:

oauth2_client_id = oauthpasswd('gmail', 'client_id')
oauth2_client_secret = oauthpasswd('gmail', 'client_secret')
oauth2_request_url = https://accounts.google.com/o/oauth2/token
oauth2_refresh_token = passwd('gmail_rf_token.gpg')
Run Code Online (Sandbox Code Playgroud)

请注意在本地文件PATHTOFILE中设置正确.我所做的是从Google下载了包含oauth2凭据的JSON文件并加密了它.我已将刷新令牌存储在单独的文件中.但是,如果我运行offlineimap,我收到一个身份验证错误:

 ERROR: While attempting to sync account 'gmail'
  ('http error', 401, 'Unauthorized', <httplib.HTTPMessage instance at 0x7f488c214320>) (configuration is: {'client_secret': "oauthpasswd('gmail', 'client_secret')", 'grant_type': 'refresh_token', 'refresh_token': "passwd('gmail_rf_token.gpg')", 'client_id': "oauthpasswd('gmail', 'client_id')"})
Run Code Online (Sandbox Code Playgroud)

我已经尝试检查两个python函数的输出passwdoauthpasswdpython解释器.我得到了所需的输出.更重要的是,我已经将python解释器中的函数输出复制到了offlineimaprc配置文件,并且我能够同步到Gmail.这意味着当offlineimap执行文件时必定会出错,但我看不出有什么问题.

如果我只加密我的Gmail密码,一切正常.这意味着从Google下载的详细信息(client_id,client_secret和刷新令牌)出现了问题.如上所述,值本身是正确的.我真的复制了输出

oauthpasswd('gmail', 'client_id')
oauthpasswd('gmail', 'client_secret')
passwd('gmail_rf_token.gpg')
Run Code Online (Sandbox Code Playgroud)

从python控制台到offlineimaprc文件,它工作.

mat*_*ath 1

发生的问题如下。根据这个答案, offlineimap 不允许对offlinemaprc 文件中的所有密钥进行加密。这就是为什么 python 函数永远不会被求值并且传递错误的字符串的原因。