Gitlab: 使用API方式修改邮箱不成功的对应方法
这篇文章介绍一下在Gitlab中通过API修改邮箱不成功的对应方法。
现象说明
使用API修改邮箱(字段为email),返回信息正常,但是结果中仍为之前邮箱信息。
原因与对应方法
版本说明
本文memo的内容为Gitlab的Api为v4版本的情况
环境准备
环境的准备以及token等信息的设定可参看下文:
- https://liumiaocn.blog.csdn.net/article/details/107443400
问题再现
测试用户准备
准备如下用户信息(liumiao/12341234), 执行日志如下所示:
liumiaocn:api liumiao$ curl -X POST -H "PRIVATE-TOKEN: ${access_token}" http://${gitlab_url}/api/v4/users \
> -H 'cache-control: no-cache' \
> -H 'content-type: application/json' \
> -d '{ "email": "liumiaocn@outlook.com",
> "username": "liumiaocn",
> "password": "12341234",
> "name": "liumiaocn",
> "skip_confirmation": "true"
> }' |jq .
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 833 100 690 100 143 1751 362 --:--:-- --:--:-- --:--:-- 2114
{
"id": 2,
"name": "liumiaocn",
"username": "liumiaocn",
"state": "active",
"avatar_url": "https://www.gravatar.com/avatar/95c1f7ff72d71b448592a335ba80fb64?s=80&d=identicon",
"web_url": "http://fb1429a3b28c/liumiaocn",
"created_at": "2020-07-30T23:20:49.710Z",
"bio": null,
"location": null,
"skype": "",
"linkedin": "",
"twitter": "",
"website_url": "",
"organization": null,
"last_sign_in_at": null,
"confirmed_at": "2020-07-30T23:20:49.650Z",
"last_activity_on": null,
"email": "liumiaocn@outlook.com",
"theme_id": 1,
"color_scheme_id": 1,
"projects_limit": 100000,
"current_sign_in_at": null,
"identities": [],
"can_create_group": true,
"can_create_project": true,
"two_factor_enabled": false,
"external": false,
"private_profile": null
}
liumiaocn:api liumiao$
登录确认此用户的邮箱地址
修改用户邮箱
将用户邮箱从liumiaocn@outlook.com修改为liumiao123@outlook.com
liumiaocn:api liumiao$ userid=2
liumiaocn:api liumiao$ curl -X PUT -H "PRIVATE-TOKEN: ${access_token}" http://${gitlab_url}/api/v4/users/${userid} \
> -H 'cache-control: no-cache' \
> -H 'content-type: application/json' \
> -d '{ "email": "liumiaocn123@outlook.com"}'
{"id":2,"name":"liumiaocn","username":"liumiaocn","state":"active","avatar_url":"https://www.gravatar.com/avatar/95c1f7ff72d71b448592a335ba80fb64?s=80\u0026d=identicon","web_url":"http://fb1429a3b28c/liumiaocn","created_at":"2020-07-30T23:20:49.710Z","bio":null,"location":null,"skype":"","linkedin":"","twitter":"","website_url":"","organization":null,"last_sign_in_at":"2020-07-30T23:22:06.395Z","confirmed_at":"2020-07-30T23:20:49.650Z","last_activity_on":"2020-07-30","email":"liumiaocn@outlook.com","theme_id":1,"color_scheme_id":1,"projects_limit":100000,"current_sign_in_at":"2020-07-30T23:22:06.395Z","identities":[],"can_create_group":true,"can_create_project":true,"two_factor_enabled":false,"external":false,"private_profile":null}liumiaocn:api liumiao$
liumiaocn:api liumiao$
结果发现返回的信息中email字段并没有发生变化。
验证方法1: 结合用户操作完成
登录之后发现如下信息,实际还是邮箱验证的机制起了作用,如果gitlab的smtp设定之后,此时修改后的邮箱应该已经收到邮件,用户自行点击里面的链接方可完成邮箱的修改。
此种方式也是较为安全的方式,前提是SMTP的设定和用户的操作以及使用上都是可以接受的。
验证方法2: 使用页面添加
方式1实际上还是需要用户点击发出来的URL链接,考虑使用从页面添加email并修改,确认是否能够保存成功。首先添加如下email地址
然后再修改email,虽然显示生效,但是实际上并未生效,刷新之后就会发现实际并没有保存成功,这种方式尚未验证成功。
验证方式3:修改gitlab设定并重启服务
思路:将用户相关的gitlab的ruby代码删去验证部分,重启gitlab服务。简单来说,删除用户模块相关文件中的验证部分,然后重启即可。
- 引入部分:/opt/gitlab/embedded/service/gitlab-rails/app/models/user.rb
- 使用部分:/opt/gitlab/embedded/service/gitlab-rails/app/views/profiles/show.html.haml
步骤1: 进入到gitlab容器中
liumiaocn:api liumiao$ docker exec -it gitlab_gitlab_1 sh
#
步骤2: 删除user.rb中的关联代码
# cp -p /opt/gitlab/embedded/service/gitlab-rails/app/models/user.rb /opt/gitlab/embedded/service/gitlab-rails/app/models/user.rb.org
# vi /opt/gitlab/embedded/service/gitlab-rails/app/models/user.rb
# diff /opt/gitlab/embedded/service/gitlab-rails/app/models/user.rb /opt/gitlab/embedded/service/gitlab-rails/app/models/user.rb.org
56c56
< :validatable, :omniauthable, :registerable
---
> :validatable, :omniauthable, :confirmable, :registerable
#
步骤3: 重启gitlab服务
# gitlab-ctl restart
ok: run: alertmanager: (pid 30175) 1s
ok: run: gitaly: (pid 30206) 0s
ok: run: gitlab-monitor: (pid 30219) 0s
ok: run: gitlab-workhorse: (pid 30238) 1s
ok: run: logrotate: (pid 30251) 0s
ok: run: nginx: (pid 30258) 1s
ok: run: node-exporter: (pid 30266) 0s
ok: run: postgres-exporter: (pid 30275) 1s
ok: run: postgresql: (pid 30360) 0s
ok: run: prometheus: (pid 30369) 1s
ok: run: redis: (pid 30385) 0s
ok: run: redis-exporter: (pid 30390) 1s
ok: run: sidekiq: (pid 30399) 1s
ok: run: sshd: (pid 30406) 0s
ok: run: unicorn: (pid 30413) 0s
#
结果验证:此时确认即可发现,已经可以设定
liumiaocn:gitlab liumiao$ curl -X PUT -H "PRIVATE-TOKEN: ${access_token}" http://${gitlab_url}/api/v4/users/${userid} \
> -H 'cache-control: no-cache' \
> -H 'content-type: application/json' \
> -d '{ "email": "liumiao@outlook.com"}'
{"id":2,"name":"liumiaocn","username":"liumiaocn","state":"active","avatar_url":"https://www.gravatar.com/avatar/cf0d8c6aee3403a64e55ce27898eb710?s=80\u0026d=identicon","web_url":"http://a47b8f2ccff7/liumiaocn","created_at":"2020-07-31T03:58:34.373Z","bio":"","location":"","skype":"","linkedin":"","twitter":"","website_url":"","organization":"","last_sign_in_at":"2020-07-31T04:02:25.818Z","confirmed_at":"2020-07-31T03:58:34.178Z","last_activity_on":"2020-07-31","email":"liumiao@outlook.com","theme_id":1,"color_scheme_id":1,"projects_limit":100000,"current_sign_in_at":"2020-07-31T04:02:25.818Z","identities":[],"can_create_group":true,"can_create_project":true,"two_factor_enabled":false,"external":false,"private_profile":false}liumiaocn:gitlab liumiao$
步骤4: 确认错误日志并修改
上述粗暴地删除之后,并没有定位其他的影响,可根据日志信息结合确认,日志路径如下所示:/var/log/gitlab/gitlab-rails/production.log
在GitLab页面登录之后,点击右上角的settings菜单项,页面不能正常显示,出现500错误,上述日志中出现如下错误信息:
Completed 500 Internal Server Error in 1245ms (ActiveRecord: 23.9ms)
ActionView::Template::Error (undefined method `user_confirmation_path' for #<#<Class:0x00007f5462351c50>:0x00007f546233b108>
Did you mean? new_confirmation_path):
83: - if @user.read_only_attribute?(:email)
84: = f.text_field :email, required: true, readonly: true, help: "Your email address was automatically set based on your #{ attribute_provider_label(:email) } account."
85: - else
86: = f.text_field :email, required: true, value: (@user.email unless @user.temp_oauth_email?),
87: help: user_email_help_text(@user)
88: = f.select :public_email, options_for_select(@user.all_emails, selected: @user.public_email),
89: { help: 'This email will be displayed on your public profile.', include_blank: 'Do not show on profile' },
app/helpers/users_helper.rb:11:in `user_email_help_text'
app/views/profiles/show.html.haml:86:in `block in _app_views_profiles_show_html_haml__1825549301882057885_70000200764700'
app/views/profiles/show.html.haml:4:in `_app_views_profiles_show_html_haml__1825549301882057885_70000200764700'
lib/gitlab/i18n.rb:51:in `with_locale'
lib/gitlab/i18n.rb:57:in `with_user_locale'
app/controllers/application_controller.rb:401:in `set_locale'
lib/gitlab/middleware/multipart.rb:97:in `call'
lib/gitlab/request_profiler/middleware.rb:14:in `call'
lib/gitlab/middleware/go.rb:17:in `call'
lib/gitlab/etag_caching/middleware.rb:11:in `call'
lib/gitlab/middleware/rails_queue_duration.rb:22:in `call'
lib/gitlab/metrics/rack_middleware.rb:15:in `block in call'
lib/gitlab/metrics/transaction.rb:53:in `run'
lib/gitlab/metrics/rack_middleware.rb:15:in `call'
lib/gitlab/middleware/read_only/controller.rb:38:in `call'
lib/gitlab/middleware/read_only.rb:16:in `call'
lib/gitlab/middleware/basic_health_check.rb:25:in `call'
lib/gitlab/request_context.rb:18:in `call'
lib/gitlab/metrics/requests_rack_middleware.rb:27:in `call'
lib/gitlab/middleware/release_env.rb:10:in `call'
根据上述信息,做如下修改
# pwd
/opt/gitlab/embedded/service/gitlab-rails/app/views/profiles
# cp -p show.html.haml show.html.haml.org
# vi show.html.haml
# diff show.html.haml show.html.haml.org
84a85,87
> - else
> = f.text_field :email, required: true, value: (@user.email unless @user.temp_oauth_email?),
> help: user_email_help_text(@user)
# gitlab-ctl restart
ok: run: alertmanager: (pid 39114) 0s
ok: run: gitaly: (pid 39127) 0s
ok: run: gitlab-monitor: (pid 39142) 1s
ok: run: gitlab-workhorse: (pid 39159) 0s
ok: run: logrotate: (pid 39175) 1s
ok: run: nginx: (pid 39181) 0s
ok: run: node-exporter: (pid 39190) 1s
ok: run: postgres-exporter: (pid 39196) 0s
ok: run: postgresql: (pid 39282) 0s
ok: run: prometheus: (pid 39290) 0s
ok: run: redis: (pid 39299) 0s
ok: run: redis-exporter: (pid 39311) 1s
ok: run: sidekiq: (pid 39320) 1s
ok: run: sshd: (pid 39327) 0s
ok: run: unicorn: (pid 39334) 0s
#
步骤5: 重启并确认
重启gitlab服务
# gitlab-ctl restart
ok: run: alertmanager: (pid 39114) 0s
ok: run: gitaly: (pid 39127) 0s
ok: run: gitlab-monitor: (pid 39142) 1s
ok: run: gitlab-workhorse: (pid 39159) 0s
ok: run: logrotate: (pid 39175) 1s
ok: run: nginx: (pid 39181) 0s
ok: run: node-exporter: (pid 39190) 1s
ok: run: postgres-exporter: (pid 39196) 0s
ok: run: postgresql: (pid 39282) 0s
ok: run: prometheus: (pid 39290) 0s
ok: run: redis: (pid 39299) 0s
ok: run: redis-exporter: (pid 39311) 1s
ok: run: sidekiq: (pid 39320) 1s
ok: run: sshd: (pid 39327) 0s
ok: run: unicorn: (pid 39334) 0s
#
再次登录确认,发现删除两行之后页面已经能够正常打开了,凑合用吧。
步骤6: 再次确认
重新确认API方式是否可以修改和设定,此处将邮件设定为liumiaocn456@outlook.com, 可以看到执行之后立即进行了修改,无需进行进一步邮箱的确认了
liumiaocn:gitlab liumiao$ userid=2
liumiaocn:gitlab liumiao$ curl -X PUT -H "PRIVATE-TOKEN: ${access_token}" http://${gitlab_url}/api/v4/users/${userid} \
> -H 'cache-control: no-cache' \
> -H 'content-type: application/json' \
> -d '{ "email": "liumiao456@outlook.com"}'
{"id":2,"name":"liumiaocn","username":"liumiaocn","state":"active","avatar_url":"https://www.gravatar.com/avatar/f8d4a298670af74bf1e24eb284dc38ee?s=80\u0026d=identicon","web_url":"http://a47b8f2ccff7/liumiaocn","created_at":"2020-07-31T03:58:34.373Z","bio":"","location":"","skype":"","linkedin":"","twitter":"","website_url":"","organization":"","last_sign_in_at":"2020-07-31T04:02:25.818Z","confirmed_at":"2020-07-31T03:58:34.178Z","last_activity_on":"2020-07-31","email":"liumiao456@outlook.com","theme_id":1,"color_scheme_id":1,"projects_limit":100000,"current_sign_in_at":"2020-07-31T04:02:25.818Z","identities":[],"can_create_group":true,"can_create_project":true,"two_factor_enabled":false,"external":false,"private_profile":false}liumiaocn:gitlab liumiao$
liumiaocn:gitlab liumiao$
注意事项
此种做法严重不推荐,因为这种方式之下后续的升级和其他做法都会存在后续问题,而且此处只修改了一个页面,比如可以预见的就是/profile/emails之类的页面也会Whoops,当在企业内网之中不得已而为之,或者在流程上无法接受中断之后用户登录点击链接的返回方式等情况下,可使用本文整理的方式进行暂定对应,坑先埋下,后续再填。
还没有评论,来说两句吧...