pfaffman
(Jay Pfaffman)
2019 年11 月 8 日 17:37
1
嗯,安装失败了(我的安装脚本会获取一个 API 密钥,以便设置 mailgun_api_key)。我还在本地开发实例上检查了这个问题。
$ rake api_key:get
rake aborted!
NoMethodError: undefined method `create_master_key' for ApiKey (call 'ApiKey.connection' to establish a connection):Class
Did you mean? create_with
/home/pfaffman/src/discourse/lib/tasks/api.rake:5:in `block in <main>'
Tasks: TOP => api_key:get
(See full trace by running task with --trace)
是 这个提交 。@david
这里是 PR:FIX: create_master_key got renamed by pfaffman · Pull Request #8325 · discourse/discourse · GitHub
david
(David Taylor)
2019 年11 月 8 日 17:46
2
感谢 @pfaffman ,我已在 PR 上留言。
pfaffman:
我的安装脚本
确认一下:这是你个人的脚本,而不是标准的安装脚本,对吗?
pfaffman
(Jay Pfaffman)
2019 年11 月 8 日 17:49
3
是的!这并没有破坏正常的安装,只是破坏了我安装后需要 API 密钥来设置 mailgun_api_key 的那部分脚本。
我怀疑很少有人会使用这个 rake 任务。
david
(David Taylor)
2019 年11 月 8 日 17:51
4
出于好奇,你用完后会清除 API 密钥吗?你可能注意到我最近做了很多更改,以便更好地跟踪 API 密钥。我们正努力减少“未使用”的 API 密钥被留下成为潜在的安全漏洞。
如果这是在服务器上运行,或许你可以使用 Ruby 来设置站点配置,而不是生成和使用 API 密钥?
pfaffman
(Jay Pfaffman)
2019 年11 月 8 日 17:55
5
哦!我认为如果密钥已存在,最好不要修改它,或者添加一个 create_if_not_exists 任务。能够通过 Rake 任务获取现有密钥而不修改它、从而避免破坏任何使用该密钥的功能,这一点非常实用。
在我的 Ansible 工具链中有几个地方,如果我没有 API 密钥,就会调用该 Rake 任务来获取现有的密钥,例如:
- name: 获取 API 密钥
block:
- shell: docker exec -w /var/www/discourse -i {{ discourse_yml }} rake api_key:get
register: get_api_key
- set_fact:
discourse_api_key: "{{ get_api_key.stdout }}"
when: discourse_api_key is not defined
我想,只有在执行全新安装时,才真正需要以这种方式获取密钥。(对于现有站点,我会在该站点的变量中保存 API 密钥。)
我想,随着密钥处理方式的更新,我可以在完成后删除密钥,或者通过某种方式在容器内运行 Rails 脚本来修改站点设置?
david
(David Taylor)
2019 年11 月 8 日 18:17
6
我做出的一项更改是,现在每个用户可以拥有多个密钥(或多个“主密钥”)。这意味着每个集成都可以分配自己的密钥,并且可以单独审计、撤销或删除。因此,在您的情况下,您可以创建一个描述为“pfaffman 的设置工具”的密钥。这样,站点管理员就知道它的用途,并在不再需要时可以撤销或删除它。
至于这如何转化为 rake 任务……我还不确定。也许我们可以有一个名为 api:get_or_create "我的密钥描述" 的任务:thinking:
这对您的情况适用吗,@pfaffman ?
david
(David Taylor)
2019 年11 月 8 日 19:03
8
这个怎么样?this ?
rake api_key:get_or_create_master["Onboarding Key"]
如果没有异议,我将在几小时内合并它。
pfaffman
(Jay Pfaffman)
2019 年11 月 8 日 19:10
10
我觉得没问题!而且我的剧本还在编辑器里开着,所以我已经提交了。
david
(David Taylor)
2019 年11 月 29 日 15:56
16
抱歉 @pfaffman ,但恐怕我不得不在接下来的 PR 中移除这个新的 rake 任务。我们将对数据库中的 API 密钥进行哈希处理,因此从根本上讲,无法检索现有的密钥。
master ← davidtaylorhq:api-key-hash
merged 11:45AM - 12 Dec 19 UTC
> ⚠️This change is completely irreversible. Once the migrations are run, the pla… in text keys will be deleted from the database. Marking as a draft PR for now to avoid accidental merging, but this is ready for review.
API keys are now only visible when first created. After that, only the first four characters are stored in the database for identification, along with an sha256 hash of the full key. This makes key usage easier to audit, and ensures attackers would not have access to the live site in the event of a database leak.
Many of the changes in this diff are to implement the new post-create UI, which looks like:
<img width="1138" alt="Screenshot 2019-11-29 at 15 20 09" src="https://user-images.githubusercontent.com/6270921/69878077-c914f680-12bb-11ea-8645-435d7491f265.png">
From a security perspective, the key files to review are:
- `app/models/api_key.rb`
- `lib/auth/default_current_user_provider.rb`
- `db/migrate/20191128113434_add_hashed_api_key.rb`
- `db/post_migrate/20191128113435_remove_key_from_api_keys.rb`
@danielwaterworth I had some issues with `fab!` in the tests, because it 'refinds' the record from the database after the initial save. The keys are kept temporarily as instance variables, so this refind was causing the key to be lost. I set `refind:false` in these places, but would be interested if you know of a cleaner solution.
我已将 get_or_create_master 任务替换为一个更简单的 create_master 任务 ,该任务将无条件地创建新密钥。如果您希望只保留一个密钥,那么您需要在自己的系统中跟踪该密钥。
pfaffman
(Jay Pfaffman)
2019 年11 月 29 日 16:43
17
嗯,我大概猜到会有这种情况。其他系统都只显示一次 API 密钥,所以……
谢谢提醒!
pfaffman
(Jay Pfaffman)
2019 年11 月 29 日 18:01
18
我无法快速判断。(等等,db 目录中怎么没有 schema.rb 文件?)
如果我对同一个 some name 多次执行 rake api_key:create_master['some name'],会失败吗?也就是说,该名称是否需要唯一?
david
(David Taylor)
2019 年11 月 29 日 18:05
19
描述不需要唯一,没错。不过,如果你创建了大量看起来相似的键,可能会让人相当困惑。
pfaffman:
为什么没有 schema .rb 文件?
我们不会提交 schema.rb 文件。最好的查找位置是 /app/models 下每个文件底部的注释。
pfaffman
(Jay Pfaffman)
2019 年11 月 29 日 18:16
20
david:
我们不提交 schema.rb 文件。
等等,什么?从什么时候开始的?我本地当前 discourse 源码中的任何提交都仍然包含 schema.rb。能够轻松找到某个模型真的非常、非常有用。打开单个文件进行搜索(例如,确定你要找的模型)比在 app/models 下的 200 多个文件中逐个查找要容易得多。甚至没有一个好的方法可以只在模型末尾的 schema 部分进行 grep 搜索。
如果你不知道要找哪个模型,该怎么找到它呢?比如有一堆与“auth”相关的表,但并非所有表名都以 auth 开头,你该如何开始确定该去哪里查找?
david
(David Taylor)
2019 年11 月 29 日 19:22
21
pfaffman:
等等,什么?!从什么时候开始的?
一直以来都是这样,它就在 .gitignore 文件里。但当你运行 db:migrate 时它会生成,所以本地会有这个文件。
pfaffman:
如果你都不知道要找哪个模型,怎么找得到?
表名总是与模型名一致,所以我直接用文件名
pfaffman
(Jay Pfaffman)
2019 年11 月 29 日 19:37
22
原来如此。看来我懂的还不多。:wink 谢谢你的解释。
有时候我猜不出表名或模型名,所以把所有字段放在一处非常有帮助。