summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorDouwe Maan <douwe@gitlab.com>2016-11-08 10:47:45 +0000
committerDouwe Maan <douwe@gitlab.com>2016-11-08 10:47:45 +0000
commit9c3f3e9e359740b10edafaa1b06b0ff3e2070820 (patch)
tree01846d1a63bd1177b68377822fcb23b86e176cf2 /app
parent8f85bd5789d50c080a7214981cc0a45fcb382bef (diff)
parent011e561bfa227f3ecbafe5b1ffd51700c680a15f (diff)
downloadgitlab-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.es622
-rw-r--r--app/assets/stylesheets/pages/profile.scss4
-rw-r--r--app/controllers/profiles_controller.rb10
-rw-r--r--app/controllers/projects_controller.rb7
-rw-r--r--app/helpers/accounts_helper.rb5
-rw-r--r--app/models/concerns/token_authenticatable.rb10
-rw-r--r--app/models/project.rb11
-rw-r--r--app/models/user.rb12
-rw-r--r--app/views/profiles/accounts/show.html.haml32
-rw-r--r--app/views/projects/issues/_issue_by_email.html.haml21
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.