diff options
author | Douwe Maan <douwe@gitlab.com> | 2016-11-08 10:47:45 +0000 |
---|---|---|
committer | Douwe Maan <douwe@gitlab.com> | 2016-11-08 10:47:45 +0000 |
commit | 9c3f3e9e359740b10edafaa1b06b0ff3e2070820 (patch) | |
tree | 01846d1a63bd1177b68377822fcb23b86e176cf2 /app | |
parent | 8f85bd5789d50c080a7214981cc0a45fcb382bef (diff) | |
parent | 011e561bfa227f3ecbafe5b1ffd51700c680a15f (diff) | |
download | gitlab-ce-9c3f3e9e359740b10edafaa1b06b0ff3e2070820.tar.gz |
Merge branch 'use-separate-token-for-incoming-email' into 'master'
Use separate email-friendly token for incoming email
See merge request !5914
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/javascripts/issuable.js.es6 | 22 | ||||
-rw-r--r-- | app/assets/stylesheets/pages/profile.scss | 4 | ||||
-rw-r--r-- | app/controllers/profiles_controller.rb | 10 | ||||
-rw-r--r-- | app/controllers/projects_controller.rb | 7 | ||||
-rw-r--r-- | app/helpers/accounts_helper.rb | 5 | ||||
-rw-r--r-- | app/models/concerns/token_authenticatable.rb | 10 | ||||
-rw-r--r-- | app/models/project.rb | 11 | ||||
-rw-r--r-- | app/models/user.rb | 12 | ||||
-rw-r--r-- | app/views/profiles/accounts/show.html.haml | 32 | ||||
-rw-r--r-- | app/views/projects/issues/_issue_by_email.html.haml | 21 |
10 files changed, 106 insertions, 28 deletions
diff --git a/app/assets/javascripts/issuable.js.es6 b/app/assets/javascripts/issuable.js.es6 index 8fc498be27d..46503c290ae 100644 --- a/app/assets/javascripts/issuable.js.es6 +++ b/app/assets/javascripts/issuable.js.es6 @@ -10,6 +10,7 @@ Issuable.initSearch(); Issuable.initChecks(); Issuable.initResetFilters(); + Issuable.resetIncomingEmailToken(); return Issuable.initLabelFilterRemove(); }, initTemplates: function() { @@ -154,6 +155,27 @@ this.issuableBulkActions.willUpdateLabels = false; } return true; + }, + + resetIncomingEmailToken: function() { + $('.incoming-email-token-reset').on('click', function(e) { + e.preventDefault(); + + $.ajax({ + type: 'PUT', + url: $('.incoming-email-token-reset').attr('href'), + dataType: 'json', + success: function(response) { + $('#issue_email').val(response.new_issue_address).focus(); + }, + beforeSend: function() { + $('.incoming-email-token-reset').text('resetting...'); + }, + complete: function() { + $('.incoming-email-token-reset').text('reset it'); + } + }); + }); } }; diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss index ede29db1979..6fab97a71aa 100644 --- a/app/assets/stylesheets/pages/profile.scss +++ b/app/assets/stylesheets/pages/profile.scss @@ -23,6 +23,10 @@ color: $md-link-color; } +.private-tokens-reset div.reset-action:not(:first-child) { + padding-top: 15px; +} + .oauth-buttons { .btn-group { margin-right: 10px; diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb index f71e0a1302b..f0c71725ea8 100644 --- a/app/controllers/profiles_controller.rb +++ b/app/controllers/profiles_controller.rb @@ -26,7 +26,15 @@ class ProfilesController < Profiles::ApplicationController def reset_private_token if current_user.reset_authentication_token! - flash[:notice] = "Token was successfully updated" + flash[:notice] = "Private token was successfully reset" + end + + redirect_to profile_account_path + end + + def reset_incoming_email_token + if current_user.reset_incoming_email_token! + flash[:notice] = "Incoming email token was successfully reset" end redirect_to profile_account_path diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 8cd50480ec1..28820adcc46 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -160,6 +160,13 @@ class ProjectsController < Projects::ApplicationController end end + def new_issue_address + return render_404 unless Gitlab::IncomingEmail.supports_issue_creation? + + current_user.reset_incoming_email_token! + render json: { new_issue_address: @project.new_issue_address(current_user) } + end + def archive return access_denied! unless can?(current_user, :archive_project, @project) diff --git a/app/helpers/accounts_helper.rb b/app/helpers/accounts_helper.rb new file mode 100644 index 00000000000..5d27d30eaa3 --- /dev/null +++ b/app/helpers/accounts_helper.rb @@ -0,0 +1,5 @@ +module AccountsHelper + def incoming_email_token_enabled? + current_user.incoming_email_token && Gitlab::IncomingEmail.supports_issue_creation? + end +end diff --git a/app/models/concerns/token_authenticatable.rb b/app/models/concerns/token_authenticatable.rb index 24c7b26d223..04d30f46210 100644 --- a/app/models/concerns/token_authenticatable.rb +++ b/app/models/concerns/token_authenticatable.rb @@ -4,17 +4,21 @@ module TokenAuthenticatable private def write_new_token(token_field) - new_token = generate_token(token_field) + new_token = generate_available_token(token_field) write_attribute(token_field, new_token) end - def generate_token(token_field) + def generate_available_token(token_field) loop do - token = Devise.friendly_token + token = generate_token(token_field) break token unless self.class.unscoped.find_by(token_field => token) end end + def generate_token(token_field) + Devise.friendly_token + end + class_methods do def authentication_token_fields @token_fields || [] diff --git a/app/models/project.rb b/app/models/project.rb index 686d285410b..4c9c7c001dd 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -624,13 +624,12 @@ class Project < ActiveRecord::Base end def new_issue_address(author) - # This feature is disabled for the time being. - return nil + return unless Gitlab::IncomingEmail.supports_issue_creation? && author - if Gitlab::IncomingEmail.enabled? && author # rubocop:disable Lint/UnreachableCode - Gitlab::IncomingEmail.reply_address( - "#{path_with_namespace}+#{author.authentication_token}") - end + author.ensure_incoming_email_token! + + Gitlab::IncomingEmail.reply_address( + "#{path_with_namespace}+#{author.incoming_email_token}") end def build_commit_note(commit) diff --git a/app/models/user.rb b/app/models/user.rb index c0dffa7b6ea..3813df6684e 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -13,6 +13,7 @@ class User < ActiveRecord::Base DEFAULT_NOTIFICATION_LEVEL = :participating add_authentication_token_field :authentication_token + add_authentication_token_field :incoming_email_token default_value_for :admin, false default_value_for(:external) { current_application_settings.user_default_external } @@ -119,7 +120,7 @@ class User < ActiveRecord::Base before_validation :set_public_email, if: ->(user) { user.public_email_changed? } after_update :update_emails_with_primary_email, if: ->(user) { user.email_changed? } - before_save :ensure_authentication_token + before_save :ensure_authentication_token, :ensure_incoming_email_token before_save :ensure_external_user_rights after_save :ensure_namespace_correct after_initialize :set_projects_limit @@ -956,4 +957,13 @@ class User < ActiveRecord::Base signup_domain =~ regexp end end + + def generate_token(token_field) + if token_field == :incoming_email_token + # Needs to be all lowercase and alphanumeric because it's gonna be used in an email address. + SecureRandom.hex.to_i(16).to_s(36) + else + super + end + end end diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml index e2e974ba072..72f658d1b68 100644 --- a/app/views/profiles/accounts/show.html.haml +++ b/app/views/profiles/accounts/show.html.haml @@ -8,24 +8,36 @@ .row.prepend-top-default .col-lg-3.profile-settings-sidebar %h4.prepend-top-0 - Private Token + = incoming_email_token_enabled? ? "Private Tokens" : "Private Token" %p - Your private token is used to access application resources without authentication. - .col-lg-9 - = form_for @user, url: reset_private_token_profile_path, method: :put, html: { class: "private-token" } do |f| + Keep + = incoming_email_token_enabled? ? "these tokens" : "this token" + secret, anyone with access to them can interact with GitLab as if they were you. + .col-lg-9.private-tokens-reset + .reset-action %p.cgray - if current_user.private_token - = label_tag "token", "Private token", class: "label-light" - = text_field_tag "token", current_user.private_token, class: "form-control" + = label_tag "private-token", "Private token", class: "label-light" + = text_field_tag "private-token", current_user.private_token, class: "form-control", readonly: true, onclick: "this.select()" - else - %span You don`t have one yet. Click generate to fix it. - %p.help-block - It can be used for atom feeds or the API. Keep it secret! + %span You don't have one yet. Click generate to fix it. + %p.help-block + Your private token is used to access the API and Atom feeds without username/password authentication. .prepend-top-default - if current_user.private_token - = f.submit 'Reset private token', data: { confirm: "Are you sure?" }, class: "btn btn-default" + = link_to 'Reset private token', reset_private_token_profile_path, method: :put, data: { confirm: "Are you sure?" }, class: "btn btn-default private-token" - else = f.submit 'Generate', class: "btn btn-default" + - if incoming_email_token_enabled? + .reset-action + %p.cgray + = label_tag "incoming-email-token", "Incoming Email Token", class: 'label-light' + = text_field_tag "incoming-email-token", current_user.incoming_email_token, class: "form-control", readonly: true, onclick: "this.select()" + %p.help-block + Your incoming email token is used to create new issues by email, and is included in your project-specific email addresses. + .prepend-top-default + = link_to 'Reset incoming email token', reset_incoming_email_token_profile_path, method: :put, data: { confirm: "Are you sure?" }, class: "btn btn-default incoming-email-token" + %hr .row.prepend-top-default .col-lg-3.profile-settings-sidebar diff --git a/app/views/projects/issues/_issue_by_email.html.haml b/app/views/projects/issues/_issue_by_email.html.haml index 72669372497..d2038a2be68 100644 --- a/app/views/projects/issues/_issue_by_email.html.haml +++ b/app/views/projects/issues/_issue_by_email.html.haml @@ -12,16 +12,23 @@ Create new issue by email .modal-body %p - Write an email to the below email address. (This is a private email address, so keep it secret.) + You can create a new issue inside this project by sending an email to the following email address: .email-modal-input-group.input-group = text_field_tag :issue_email, email, class: "monospace js-select-on-focus form-control", readonly: true .input-group-btn = clipboard_button(clipboard_target: '#issue_email') %p - Send an email to this address to create an issue. - %p - Use the subject line as the title of your issue. + The subject will be used as the title of the new issue, and the message will be the description. + + = link_to 'Slash commands', help_page_path('user/project/slash_commands'), target: '_blank', tabindex: -1 + and styling with + = link_to 'Markdown', help_page_path('user/markdown'), target: '_blank', tabindex: -1 + are supported. + %p - Use the message as the body of your issue (feel free to include some nice - = succeed ")." do - = link_to "Markdown", help_page_path('markdown', 'markdown') + This is a private email address, generated just for you. + + Anyone who gets ahold of it can create issues as if they were you. + You should + = link_to 'reset it', new_issue_address_namespace_project_path(@project.namespace, @project), class: 'incoming-email-token-reset' + if that ever happens. |