summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimothy Andrew <mail@timothyandrew.net>2016-11-22 14:27:31 +0530
committerTimothy Andrew <mail@timothyandrew.net>2016-12-16 15:08:10 +0530
commit6c809dfae84e702f7a49d3fac5725745264e0ff9 (patch)
tree185c6d1444abd3f884515b92f077e747cac96e1d
parent1d0ccec6dd8375b751846f69bb170ebd11e9a391 (diff)
downloadgitlab-ce-6c809dfae84e702f7a49d3fac5725745264e0ff9.tar.gz
Allow creating personal access tokens / OAuth applications with scopes.
-rw-r--r--app/assets/stylesheets/pages/profile.scss10
-rw-r--r--app/controllers/admin/applications_controller.rb6
-rw-r--r--app/controllers/concerns/oauth_applications.rb14
-rw-r--r--app/controllers/oauth/applications_controller.rb6
-rw-r--r--app/controllers/profiles/personal_access_tokens_controller.rb12
-rw-r--r--app/views/admin/applications/_form.html.haml10
-rw-r--r--app/views/admin/applications/show.html.haml15
-rw-r--r--app/views/doorkeeper/applications/_form.html.haml9
-rw-r--r--app/views/doorkeeper/applications/show.html.haml15
-rw-r--r--app/views/profiles/personal_access_tokens/_form.html.haml22
-rw-r--r--app/views/profiles/personal_access_tokens/index.html.haml17
-rw-r--r--spec/features/profiles/personal_access_tokens_spec.rb26
12 files changed, 138 insertions, 24 deletions
diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss
index 8a5b0e20a86..8b1976bd925 100644
--- a/app/assets/stylesheets/pages/profile.scss
+++ b/app/assets/stylesheets/pages/profile.scss
@@ -262,3 +262,13 @@ table.u2f-registrations {
border-right: solid 1px transparent;
}
}
+
+.oauth-application-show {
+ .scope-name {
+ font-weight: 600;
+ }
+
+ .scopes-list {
+ padding-left: 18px;
+ }
+} \ No newline at end of file
diff --git a/app/controllers/admin/applications_controller.rb b/app/controllers/admin/applications_controller.rb
index 471d24934a0..759044910bb 100644
--- a/app/controllers/admin/applications_controller.rb
+++ b/app/controllers/admin/applications_controller.rb
@@ -1,4 +1,6 @@
class Admin::ApplicationsController < Admin::ApplicationController
+ include OauthApplications
+
before_action :set_application, only: [:show, :edit, :update, :destroy]
def index
@@ -10,9 +12,11 @@ class Admin::ApplicationsController < Admin::ApplicationController
def new
@application = Doorkeeper::Application.new
+ @scopes = Doorkeeper.configuration.scopes
end
def edit
+ @scopes = Doorkeeper.configuration.scopes
end
def create
@@ -47,6 +51,6 @@ class Admin::ApplicationsController < Admin::ApplicationController
# Only allow a trusted parameter "white list" through.
def application_params
- params[:doorkeeper_application].permit(:name, :redirect_uri)
+ params[:doorkeeper_application].permit(:name, :redirect_uri, :scopes)
end
end
diff --git a/app/controllers/concerns/oauth_applications.rb b/app/controllers/concerns/oauth_applications.rb
new file mode 100644
index 00000000000..34ad43ededd
--- /dev/null
+++ b/app/controllers/concerns/oauth_applications.rb
@@ -0,0 +1,14 @@
+module OauthApplications
+ extend ActiveSupport::Concern
+
+ included do
+ before_action :prepare_scopes, only: [:create, :update]
+ end
+
+ def prepare_scopes
+ scopes = params.dig(:doorkeeper_application, :scopes)
+ if scopes
+ params[:doorkeeper_application][:scopes] = scopes.join(' ')
+ end
+ end
+end
diff --git a/app/controllers/oauth/applications_controller.rb b/app/controllers/oauth/applications_controller.rb
index 0f54dfa4efc..b5449a6c30e 100644
--- a/app/controllers/oauth/applications_controller.rb
+++ b/app/controllers/oauth/applications_controller.rb
@@ -2,6 +2,7 @@ class Oauth::ApplicationsController < Doorkeeper::ApplicationsController
include Gitlab::CurrentSettings
include Gitlab::GonHelper
include PageLayoutHelper
+ include OauthApplications
before_action :verify_user_oauth_applications_enabled
before_action :authenticate_user!
@@ -13,6 +14,10 @@ class Oauth::ApplicationsController < Doorkeeper::ApplicationsController
set_index_vars
end
+ def edit
+ @scopes = Doorkeeper.configuration.scopes
+ end
+
def create
@application = Doorkeeper::Application.new(application_params)
@@ -40,6 +45,7 @@ class Oauth::ApplicationsController < Doorkeeper::ApplicationsController
@authorized_tokens = current_user.oauth_authorized_tokens
@authorized_anonymous_tokens = @authorized_tokens.reject(&:application)
@authorized_apps = @authorized_tokens.map(&:application).uniq.reject(&:nil?)
+ @scopes = Doorkeeper.configuration.scopes
# Don't overwrite a value possibly set by `create`
@application ||= Doorkeeper::Application.new
diff --git a/app/controllers/profiles/personal_access_tokens_controller.rb b/app/controllers/profiles/personal_access_tokens_controller.rb
index 508b82a9a6c..6e007f17913 100644
--- a/app/controllers/profiles/personal_access_tokens_controller.rb
+++ b/app/controllers/profiles/personal_access_tokens_controller.rb
@@ -1,8 +1,6 @@
class Profiles::PersonalAccessTokensController < Profiles::ApplicationController
- before_action :load_personal_access_tokens, only: :index
-
def index
- @personal_access_token = current_user.personal_access_tokens.build
+ set_index_vars
end
def create
@@ -12,7 +10,7 @@ class Profiles::PersonalAccessTokensController < Profiles::ApplicationController
flash[:personal_access_token] = @personal_access_token.token
redirect_to profile_personal_access_tokens_path, notice: "Your new personal access token has been created."
else
- load_personal_access_tokens
+ set_index_vars
render :index
end
end
@@ -32,10 +30,12 @@ class Profiles::PersonalAccessTokensController < Profiles::ApplicationController
private
def personal_access_token_params
- params.require(:personal_access_token).permit(:name, :expires_at)
+ params.require(:personal_access_token).permit(:name, :expires_at, scopes: [])
end
- def load_personal_access_tokens
+ def set_index_vars
+ @personal_access_token ||= current_user.personal_access_tokens.build
+ @scopes = Gitlab::Auth::SCOPES
@active_personal_access_tokens = current_user.personal_access_tokens.active.order(:expires_at)
@inactive_personal_access_tokens = current_user.personal_access_tokens.inactive
end
diff --git a/app/views/admin/applications/_form.html.haml b/app/views/admin/applications/_form.html.haml
index 4aacbb8cd77..36d2f415a05 100644
--- a/app/views/admin/applications/_form.html.haml
+++ b/app/views/admin/applications/_form.html.haml
@@ -18,6 +18,16 @@
Use
%code= Doorkeeper.configuration.native_redirect_uri
for local tests
+
+ .form-group
+ = f.label :scopes, class: 'col-sm-2 control-label'
+ .col-sm-10
+ - @scopes.each do |scope|
+ %fieldset
+ = check_box_tag 'doorkeeper_application[scopes][]', scope, application.scopes.include?(scope), id: "doorkeeper_application_scopes_#{scope}"
+ = label_tag "doorkeeper_application_scopes_#{scope}", scope
+ %span= "(#{t(scope, scope: [:doorkeeper, :scopes])})"
+
.form-actions
= f.submit 'Submit', class: "btn btn-save wide"
= link_to "Cancel", admin_applications_path, class: "btn btn-default"
diff --git a/app/views/admin/applications/show.html.haml b/app/views/admin/applications/show.html.haml
index 3eb9d61972b..3418dc96496 100644
--- a/app/views/admin/applications/show.html.haml
+++ b/app/views/admin/applications/show.html.haml
@@ -2,8 +2,7 @@
%h3.page-title
Application: #{@application.name}
-
-.table-holder
+.table-holder.oauth-application-show
%table.table
%tr
%td
@@ -23,6 +22,18 @@
- @application.redirect_uri.split.each do |uri|
%div
%span.monospace= uri
+
+ - if @application.scopes.present?
+ %tr
+ %td
+ Scopes
+ %td
+ %ul.scopes-list.append-bottom-0
+ - @application.scopes.each do |scope|
+ %li
+ %span.scope-name= scope
+ = "(#{t(scope, scope: [:doorkeeper, :scopes])})"
+
.form-actions
= link_to 'Edit', edit_admin_application_path(@application), class: 'btn btn-primary wide pull-left'
= render 'delete_form', application: @application, submit_btn_css: 'btn btn-danger prepend-left-10'
diff --git a/app/views/doorkeeper/applications/_form.html.haml b/app/views/doorkeeper/applications/_form.html.haml
index 5c98265727a..6fdb04077b6 100644
--- a/app/views/doorkeeper/applications/_form.html.haml
+++ b/app/views/doorkeeper/applications/_form.html.haml
@@ -17,5 +17,14 @@
%code= Doorkeeper.configuration.native_redirect_uri
for local tests
+ .form-group
+ = f.label :scopes, class: 'label-light'
+ - @scopes.each do |scope|
+ %fieldset
+ = check_box_tag 'doorkeeper_application[scopes][]', scope, application.scopes.include?(scope), id: "doorkeeper_application_scopes_#{scope}"
+ = label_tag "doorkeeper_application_scopes_#{scope}", scope
+ %span= "(#{t(scope, scope: [:doorkeeper, :scopes])})"
+
+
.prepend-top-default
= f.submit 'Save application', class: "btn btn-create"
diff --git a/app/views/doorkeeper/applications/show.html.haml b/app/views/doorkeeper/applications/show.html.haml
index 47442b78d48..a18e133c8de 100644
--- a/app/views/doorkeeper/applications/show.html.haml
+++ b/app/views/doorkeeper/applications/show.html.haml
@@ -2,7 +2,7 @@
%h3.page-title
Application: #{@application.name}
-.table-holder
+.table-holder.oauth-application-show
%table.table
%tr
%td
@@ -22,6 +22,19 @@
- @application.redirect_uri.split.each do |uri|
%div
%span.monospace= uri
+
+ - if @application.scopes.present?
+ %tr
+ %td
+ Scopes
+ %td
+ %ul.scopes-list.append-bottom-0
+ - @application.scopes.each do |scope|
+ %li
+ %span.scope-name= scope
+ = "(#{t(scope, scope: [:doorkeeper, :scopes])})"
+
+
.form-actions
= link_to 'Edit', edit_oauth_application_path(@application), class: 'btn btn-primary wide pull-left'
= render 'delete_form', application: @application, submit_btn_css: 'btn btn-danger prepend-left-10'
diff --git a/app/views/profiles/personal_access_tokens/_form.html.haml b/app/views/profiles/personal_access_tokens/_form.html.haml
new file mode 100644
index 00000000000..6083fdaa31d
--- /dev/null
+++ b/app/views/profiles/personal_access_tokens/_form.html.haml
@@ -0,0 +1,22 @@
+= form_for [:profile, @personal_access_token], method: :post, html: { class: 'js-requires-input' } do |f|
+
+ = form_errors(@personal_access_token)
+
+ .form-group
+ = f.label :name, class: 'label-light'
+ = f.text_field :name, class: "form-control", required: true
+
+ .form-group
+ = f.label :expires_at, class: 'label-light'
+ = f.text_field :expires_at, class: "datepicker form-control", required: false
+
+ .form-group
+ = f.label :scopes, class: 'label-light'
+ - @scopes.each do |scope|
+ %fieldset
+ = check_box_tag 'personal_access_token[scopes][]', scope, @personal_access_token.scopes.include?(scope), id: "personal_access_token_scopes_#{scope}"
+ = label_tag "personal_access_token_scopes_#{scope}", scope
+ %span= "(#{t(scope, scope: [:doorkeeper, :scopes])})"
+
+ .prepend-top-default
+ = f.submit 'Create Personal Access Token', class: "btn btn-create"
diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml
index 05a2ea67aa2..39eef0f6baf 100644
--- a/app/views/profiles/personal_access_tokens/index.html.haml
+++ b/app/views/profiles/personal_access_tokens/index.html.haml
@@ -28,21 +28,8 @@
Add a Personal Access Token
%p.profile-settings-content
Pick a name for the application, and we'll give you a unique token.
- = form_for [:profile, @personal_access_token],
- method: :post, html: { class: 'js-requires-input' } do |f|
- = form_errors(@personal_access_token)
-
- .form-group
- = f.label :name, class: 'label-light'
- = f.text_field :name, class: "form-control", required: true
-
- .form-group
- = f.label :expires_at, class: 'label-light'
- = f.text_field :expires_at, class: "datepicker form-control", required: false
-
- .prepend-top-default
- = f.submit 'Create Personal Access Token', class: "btn btn-create"
+ = render "form"
%hr
@@ -56,6 +43,7 @@
%th Name
%th Created
%th Expires
+ %th Scopes
%th
%tbody
- @active_personal_access_tokens.each do |token|
@@ -67,6 +55,7 @@
= token.expires_at.to_date.to_s(:medium)
- else
%span.personal-access-tokens-never-expires-label Never
+ %td= token.scopes.present? ? token.scopes.join(", ") : "<no scopes selected>"
%td= link_to "Revoke", revoke_profile_personal_access_token_path(token), method: :put, class: "btn btn-danger pull-right", data: { confirm: "Are you sure you want to revoke this token? This action cannot be undone." }
- else
diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb
index a85930c7543..0ffeeff0921 100644
--- a/spec/features/profiles/personal_access_tokens_spec.rb
+++ b/spec/features/profiles/personal_access_tokens_spec.rb
@@ -51,6 +51,32 @@ describe 'Profile > Personal Access Tokens', feature: true, js: true do
expect(active_personal_access_tokens).to have_text(Date.today.next_month.at_beginning_of_month.to_s(:medium))
end
+ context "scopes" do
+ it "allows creation of a token with scopes" do
+ visit profile_personal_access_tokens_path
+ fill_in "Name", with: FFaker::Product.brand
+
+ check "api"
+ check "read_user"
+
+ expect {click_on "Create Personal Access Token"}.to change { PersonalAccessToken.count }.by(1)
+ expect(created_personal_access_token).to eq(PersonalAccessToken.last.token)
+ expect(PersonalAccessToken.last.scopes).to match_array(['api', 'read_user'])
+ expect(active_personal_access_tokens).to have_text('api')
+ expect(active_personal_access_tokens).to have_text('read_user')
+ end
+
+ it "allows creation of a token with no scopes" do
+ visit profile_personal_access_tokens_path
+ fill_in "Name", with: FFaker::Product.brand
+
+ expect {click_on "Create Personal Access Token"}.to change { PersonalAccessToken.count }.by(1)
+ expect(created_personal_access_token).to eq(PersonalAccessToken.last.token)
+ expect(PersonalAccessToken.last.scopes).to eq([])
+ expect(active_personal_access_tokens).to have_text('no scopes')
+ end
+ end
+
context "when creation fails" do
it "displays an error message" do
disallow_personal_access_token_saves!