mirror of
https://github.com/wahyd4/gitlabhq.git
synced 2026-08-09 20:56:08 +10:00
Allow creating Personal Access Tokens through the website Related to #2979 - Allow a user to create personal access tokens, and use them to authenticate - Refactor `API::Helpers` into `API::Helpers::Core` and `API::Helpers::Authentication` # Tasks - [ ] #2979 (!3749) - Personal Access Tokens - [x] Basic Implementation - [x] Add UI to add "Personal Access Tokens" - [x] Reload `lib/api` on every request - [x] Respect these tokens for API requests - [x] Just a param or a header too? - [x] Allow revoking tokens - [x] Expire tokens - [x] Left bar should have a "PAT" icon - [x] Scopes? - [x] Copy to Clipboard - [x] Show active/inactive tokens separately - [x] No need to check for expired/revoked in the appropriate places - [x] Why does regular ApplicationController check for private token? - [x] Support non-API requests - [x] Revert (or work on) `lib/api` eager loading - [x] Create MR - [x] Refactoring - [x] Fix tests - [x] Write more tests - [x] Add screenshots to MR - [x] Add description of query performance to MR - [x] Limit the number of queries in the `personal_access_tokens` page - [x] Wait for CI to pass - [x] Fix merge issues in schema.rb - [x] Assign MR to endboss - [x] Wait for feedback - [x] Fix feedback - [x] Wait for CI to pass - [x] Assign to @rspeicher - [x] Fix @rspeicher's comments - [x] Wait for CI to pass - [x] Assign back to @rspeicher - [x] Write documentation and ping @axil - [x] Wait for Axil to respond - [x] Assign to endboss - [x] Address Douwe's feedback - [x] Use the `private_token` or `authentication_token` param instead of `personal_access_token` - [x] Ditto for the header - [x] Assign to endboss - [x] Make sure CI is green - [x] Address Douwe's feedback - [x] Don't go through the `authenticate_user_from_private_token!` method, if a private token is supplied (or combine them) - [x] In `authenticate_user_from_personal_access_token!` don't hit DB if `token_string` is `nil` - [x] Use `current_user.personal_access_tokens.build` in the controller - [x] Remove the "We aren't using `personal_access_token` as the root param" comment - [x] `No need for = "...", we can just have the Inactive ... #{...} on the next line` in the view - [x] Render dates in a (more) human format - [x] CSS issue with table - [x] Don't show the tokens in the UI indefinitely - [x] How to implement scopes? Add-on to current impl? Doorkeeper? - [x] Wait for @DouweM's comments about scopes - [x] Address @DouweM's second review - [x] Try not using `native['innerHTML']` - [x] use contexts for all "when ..." - [x] Ensure consistency (styling) with other pages for "You don't have any tokens" message - [x] "Actions" table column doesn't need a label - [x] %td can be moved outside of the if/else statement - [x] The header title should be "Profile Settings" - [x] Can this be a `before_create`, so we don't need to use `generate`? - [x] If it couldn't be revoked, will we show an error? - [x] If it couldn't be saved, will we show an error? - [x] Merge master - [x] Update CHANGELOG entry - [x] Add tests for form errors? - [x] Post screenshots - [x] Tag @jschatz1 for review - [x] Wait for [build](https://gitlab.com/gitlab-org/gitlab-ce/commit/0dff6fd/builds) to pass - [x] Respond to @jschatz1's comments - [x] Hardcoded colors should be variables - [x] Should not be allowed to chose a date in the past - [x] Use the same table as in the Applications tab - [x] button should say "Create Personal Access Token" - [x] Float the revoke to the right on the `a` - [x] Change revocation message. "Are you sure you want to revoke this certificate? This action cannot be undone." - [x] Date stays selected and looks selected even though date is set as "never". - [x] ~~hover on the calendar button shifts~~ (not caused by this MR - happens on `milestones#new` as well) - [x] Don't use the panel for the created token - [x] Use a normal flash for "Your new personal access token has been created" - [x] Show the input (with the token) below it full width. - [x] Put the "Make sure you save it - you won't be able to access it again." message near the input - [x] Have the input highlight all on single click - [x] Update screenshots - [x] Merge master in + conflicts - [x] Assign to @jschatz1 again - [x] Respond to @jschatz1's comments - [x] No button for clipboard, only link - [x] text-danger - [x] highlight fade on that area where the token was created - [x] Make sure [build](https://gitlab.com/gitlab-org/gitlab-ce/commit/d754d99179f1ffe846fcc1d8e858163b39efc5dc/builds) is green - [x] Assign to @jschatz1 - [x] Wait for [build](https://gitlab.com/gitlab-org/gitlab-ce/commit/faa0e3f7580bc38d4d12916b4589c64d6c2678a7/builds) to pass - [x] Respond to @DouweM's feedback - [x] move the redirect_to out of the if/else - [x] certificate -> token - [x] datepicker back to text field - [x] combine the get_user_from_private_token and get_user_from_personal_access_token methods in ApplicationController - [x] combine the get_user_from_private_token and get_user_from_personal_access_token methods in `lib/api/helpers` - [x] don't need the new constants - [x] Wait for [build](https://gitlab.com/gitlab-org/gitlab-ce/commit/9d7cda3ddce52baad9618466a5d00319b333be57/builds) to pass - [ ] Wait for merge # Screenshots     See merge request !3749
105 lines
3.6 KiB
Ruby
105 lines
3.6 KiB
Ruby
require 'spec_helper'
|
|
|
|
describe ApplicationController do
|
|
describe '#check_password_expiration' do
|
|
let(:user) { create(:user) }
|
|
let(:controller) { ApplicationController.new }
|
|
|
|
it 'should redirect if the user is over their password expiry' do
|
|
user.password_expires_at = Time.new(2002)
|
|
expect(user.ldap_user?).to be_falsey
|
|
allow(controller).to receive(:current_user).and_return(user)
|
|
expect(controller).to receive(:redirect_to)
|
|
expect(controller).to receive(:new_profile_password_path)
|
|
controller.send(:check_password_expiration)
|
|
end
|
|
|
|
it 'should not redirect if the user is under their password expiry' do
|
|
user.password_expires_at = Time.now + 20010101
|
|
expect(user.ldap_user?).to be_falsey
|
|
allow(controller).to receive(:current_user).and_return(user)
|
|
expect(controller).not_to receive(:redirect_to)
|
|
controller.send(:check_password_expiration)
|
|
end
|
|
|
|
it 'should not redirect if the user is over their password expiry but they are an ldap user' do
|
|
user.password_expires_at = Time.new(2002)
|
|
allow(user).to receive(:ldap_user?).and_return(true)
|
|
allow(controller).to receive(:current_user).and_return(user)
|
|
expect(controller).not_to receive(:redirect_to)
|
|
controller.send(:check_password_expiration)
|
|
end
|
|
end
|
|
|
|
describe "#authenticate_user_from_token!" do
|
|
describe "authenticating a user from a private token" do
|
|
controller(ApplicationController) do
|
|
def index
|
|
render text: "authenticated"
|
|
end
|
|
end
|
|
|
|
let(:user) { create(:user) }
|
|
|
|
context "when the 'private_token' param is populated with the private token" do
|
|
it "logs the user in" do
|
|
get :index, private_token: user.private_token
|
|
expect(response.status).to eq(200)
|
|
expect(response.body).to eq("authenticated")
|
|
end
|
|
end
|
|
|
|
|
|
context "when the 'PRIVATE-TOKEN' header is populated with the private token" do
|
|
it "logs the user in" do
|
|
@request.headers['PRIVATE-TOKEN'] = user.private_token
|
|
get :index
|
|
expect(response.status).to eq(200)
|
|
expect(response.body).to eq("authenticated")
|
|
end
|
|
end
|
|
|
|
it "doesn't log the user in otherwise" do
|
|
@request.headers['PRIVATE-TOKEN'] = "token"
|
|
get :index, private_token: "token", authenticity_token: "token"
|
|
expect(response.status).not_to eq(200)
|
|
expect(response.body).not_to eq("authenticated")
|
|
end
|
|
end
|
|
|
|
describe "authenticating a user from a personal access token" do
|
|
controller(ApplicationController) do
|
|
def index
|
|
render text: 'authenticated'
|
|
end
|
|
end
|
|
|
|
let(:user) { create(:user) }
|
|
let(:personal_access_token) { create(:personal_access_token, user: user) }
|
|
|
|
context "when the 'personal_access_token' param is populated with the personal access token" do
|
|
it "logs the user in" do
|
|
get :index, private_token: personal_access_token.token
|
|
expect(response.status).to eq(200)
|
|
expect(response.body).to eq('authenticated')
|
|
end
|
|
end
|
|
|
|
context "when the 'PERSONAL_ACCESS_TOKEN' header is populated with the personal access token" do
|
|
it "logs the user in" do
|
|
@request.headers["PRIVATE-TOKEN"] = personal_access_token.token
|
|
get :index
|
|
expect(response.status).to eq(200)
|
|
expect(response.body).to eq('authenticated')
|
|
end
|
|
end
|
|
|
|
it "doesn't log the user in otherwise" do
|
|
get :index, private_token: "token"
|
|
expect(response.status).not_to eq(200)
|
|
expect(response.body).not_to eq('authenticated')
|
|
end
|
|
end
|
|
end
|
|
end
|