[GSoC] Multi-factor feature for RubyGems.#2369
Conversation
| request.add_field 'Authorization', api_key | ||
| end | ||
|
|
||
| # For compatibility to Gemcutters without mfa support |
There was a problem hiding this comment.
Gemcutters is obsoleted name. Please use rubygems.org
There was a problem hiding this comment.
Thanks. Here I originally wanted to include some private servers. So I'll change it to servers.
|
Using both |
| ## | ||
| # Require user for extra OTP code if multifactor authentication is enabled. | ||
|
|
||
| def run_mfa_check |
There was a problem hiding this comment.
run doesn't really mean anything. Maybe just mfa_check?
|
Can you please explain how the user flows works with 2FA. Looking at the code, does the user need to sign in with 2FA first or an error will be given? Can we just ask the user to give their MFA token whenever they sign in to an account which has 2FA? |
|
@colby-swandale Here we have a concept about level of mfa, inspired by npm. A user can set his level to |
|
A lot of |
| end | ||
| end | ||
|
|
||
| @mfa_level == 'mfa_login_and_write' |
There was a problem hiding this comment.
If there isn't a many different values for @mfa_level, shouldn't symbols be
favored over strings here?
There was a problem hiding this comment.
Since text received is string and we turned # frozen_string_literal: true on, will that help (in performance) ?
There was a problem hiding this comment.
No idea, I didn't even thought about performance when I commented to be honest.
It was more about "semantics", that it seemed used as an "identifier" more than
a string.
But on the other hand, as you said this data is received as string already, if
the spec pass in theory we shouldn't need more code :-)
Anyway it was a small detail I just asked about in case it would help, feel
free to ignore.
| end | ||
|
|
||
| # For compatibility to Gemcutters without mfa support | ||
| # For compatibility to servers without mfa support |
There was a problem hiding this comment.
I think this change belongs to another commit (the one adding this comment).
71e4429 to
6c1996b
Compare
| options[:host] = value | ||
| end | ||
|
|
||
| add_option('--mfa CODE', 'Digit code for multifactor authentication') do |value, options| |
There was a problem hiding this comment.
can this repeated code be factored into a module?
| def need_mfa? | ||
| return false if options[:suppress_mfa] | ||
| unless instance_variable_defined? :@mfa_level | ||
| response = rubygems_api_request(:get, 'api/v1/multifactor_auth') do |request| |
There was a problem hiding this comment.
Won't this be adding additional api call to all requests? For default case, we should assume that mfa on api is disabled. mfa is an opt-in feature.
From server, we can return 403 or something more appropriate for cases where otp was required but not provided. Only then, client will prompt for otp and repeat the request.
There was a problem hiding this comment.
Here options[:supress_mfa] is just an internal option for keep compatibility with older test cases, since many of them relies on last_request. And fail message the client received is plain/text, should I just match it literally?
There was a problem hiding this comment.
for keep compatibility with older test cases, since many of them relies on last_request
Can you please explain more about this limitation? Are you sure we can't do away with options[:suppress_mfa]?
should I just match it literally?
Yeah, checking for response text would be good enough unless we come up with something more elegant.
There was a problem hiding this comment.
If we want to remove options[:suppress_mfa], just @cmd.instance_variable_set :@mfa_level, 'no_mfa' works. This method should be not so intrusive. Just now I posted a much more complicated method, like here. Sorry for my carelessness.
The reason why we need to suppress mfa in original tests is they require last_request in Gem::FakeFetcher to determine method, content, headers of last request. One more fake request for mfa status will replace it.
d92565d to
b02ae88
Compare
| request.set_form_data 'email' => owner | ||
| request.add_field "Authorization", api_key | ||
| request.add_field "OTP", options[:mfa] | ||
| end |
There was a problem hiding this comment.
Please don't duplicate code. Make a method out of common code where otp is optional argument.
Also, I agree with @colby-swandale
the code would be clearer if you stick with just the one name.
"OTP", options[:mfa] 🚫
Please use otp for everything.
| end | ||
|
|
||
| if need_mfa? response | ||
| check_mfa |
There was a problem hiding this comment.
check_mfa and need_mfa? always seem to go together. Can we please call check_mfa from need_mfa? instead?
There was a problem hiding this comment.
Yes. Thanks, I changed it.
| def need_otp? response | ||
| return unless response.kind_of?(Net::HTTPUnauthorized) && | ||
| response.body.start_with?('You have enabled multifactor authentication') | ||
| unless options[:otp] |
There was a problem hiding this comment.
return true if options[:otp]
e8445e7 to
2295519
Compare
b70e0cf to
c8f5fef
Compare
|
To push progress of this feature, I listed some implementation problems about current workflow. Can you please take a look and leave comments? Thanks! |
c8f5fef to
67ffcf6
Compare
|
😄 Is there any problem for current implementation status? I wrote in detail about what it will look like and how it's implemented in GSoC final report. Sorry for out of work these days, maybe I should add 2FA to |
|
@indirect @sonalkr132 Can you handle this issue with rubygems.org side. I'm okay to merge this pull-request targeted RubyGems 3.0. |
|
@ecnelises Do you still waiting to review this? |
ba17286 to
f24d666
Compare
|
@bundlerbot r+ |
2369: [GSoC] Multi-factor feature for RubyGems. r=hsbt a=ecnelises # Description: Hello. This is my GSoC project, dedicated to add multifactor authentication to both RubyGems command program and Gemcutter ([RubyGems.org](https://rubygems.org)). Work for the Gemcutter part has almost been finished (see [PR #1753](rubygems/rubygems.org#1753), [PR #1729](rubygems/rubygems.org#1729) and a series of [my progress reports](https://ecnelises.github.io/)). ## Content: This PR will contain my changes to RubyGems client, adding multifactor auth for `gem push`, `gem signin` and `gem owner` commands. Since no command for editing profile, adding command for changing multifactor auth settings seems unnecessary. ## Workflow: - User set up multifactor auth well in the site. (into `mfa_login_and_write` level) - When user does the actions requiring MFA, an OTP prompt is shown. Or user can add `--otp` option into command, like `gem push mygem-0.0.0.gem --otp 123456`. - If the OTP is incorrect, operation fails with failure text. ______________ # Tasks: - [x] Add OTP requirement to `push_command`. - [x] Add OTP requirement to `owner_command`. - [x] Add OTP prompt to `sign_in`. - [ ] Support for `yank_command`. - [x] Write related tests. I will abide by the [code of conduct](https://github.com/rubygems/rubygems/blob/master/CODE_OF_CONDUCT.md). Co-authored-by: Qiu Chaofan <fwage73@gmail.com> Co-authored-by: SHIBATA Hiroshi <hsbt@ruby-lang.org>
Build succeeded |
* [GSoC] Multi-factor feature for RubyGems ruby/rubygems#2369 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66118 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
@ecnelises @sonalkr132 Thanks for your work. I'm going to release this feature with RG 3.0 at 25, Dec 2018. |
Not really sure why @ecnelises decided to keep it separate but PR for it is now merged on rubygems.org, I guess now he can add it here. |
|
@sonalkr132 I thought that may delay the review process and I’ve waited for `yank` related API on rubygems.org for a while. I can add it in future PRs. :-) Thanks.
…________________________________
寄件者: Aditya Prakash <notifications@github.com>
寄件日期: 星期六, 12月 1, 2018 11:08 下午
收件者: rubygems/rubygems
副本: Qiu Chaofan; Mention
主旨: Re: [rubygems/rubygems] [GSoC] Multi-factor feature for RubyGems. (#2369)
* Support for yank_command.
Not really sure why @ecnelises<https://github.com/ecnelises> decided to keep it separate but PR for it is now merged on rubygems.org, I guess now he can add it here.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub<#2369 (comment)>, or mute the thread<https://github.com/notifications/unsubscribe-auth/AJ2ePzy7oXpghjbwp3C2-inZytYKai3aks5u0pt2gaJpZM4VjU1G>.
|
|
yeah, its cool. yank is not as often used (although very important for mfa) command. |
* [GSoC] Multi-factor feature for RubyGems ruby/rubygems#2369 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66118 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Description:
Hello. This is my GSoC project, dedicated to add multifactor authentication to both RubyGems command program and Gemcutter (RubyGems.org).
Work for the Gemcutter part has almost been finished (see PR #1753, PR #1729 and a series of my progress reports).
Content:
This PR will contain my changes to RubyGems client, adding multifactor auth for
gem push,gem signinandgem ownercommands. Since no command for editing profile, adding command for changing multifactor auth settings seems unnecessary.Workflow:
mfa_login_and_writelevel)--otpoption into command, likegem push mygem-0.0.0.gem --otp 123456.Tasks:
push_command.owner_command.sign_in.yank_command.I will abide by the code of conduct.