Merge branch 'use-separate-token-for-incoming-email' into 'master'
Use separate email-friendly token for incoming email See merge request !5914
This commit is contained in:
commit
9c3f3e9e35
|
@ -10,6 +10,7 @@
|
||||||
Issuable.initSearch();
|
Issuable.initSearch();
|
||||||
Issuable.initChecks();
|
Issuable.initChecks();
|
||||||
Issuable.initResetFilters();
|
Issuable.initResetFilters();
|
||||||
|
Issuable.resetIncomingEmailToken();
|
||||||
return Issuable.initLabelFilterRemove();
|
return Issuable.initLabelFilterRemove();
|
||||||
},
|
},
|
||||||
initTemplates: function() {
|
initTemplates: function() {
|
||||||
|
@ -154,6 +155,27 @@
|
||||||
this.issuableBulkActions.willUpdateLabels = false;
|
this.issuableBulkActions.willUpdateLabels = false;
|
||||||
}
|
}
|
||||||
return true;
|
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');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,10 @@
|
||||||
color: $md-link-color;
|
color: $md-link-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.private-tokens-reset div.reset-action:not(:first-child) {
|
||||||
|
padding-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
.oauth-buttons {
|
.oauth-buttons {
|
||||||
.btn-group {
|
.btn-group {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
|
|
|
@ -26,7 +26,15 @@ class ProfilesController < Profiles::ApplicationController
|
||||||
|
|
||||||
def reset_private_token
|
def reset_private_token
|
||||||
if current_user.reset_authentication_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
|
end
|
||||||
|
|
||||||
redirect_to profile_account_path
|
redirect_to profile_account_path
|
||||||
|
|
|
@ -160,6 +160,13 @@ class ProjectsController < Projects::ApplicationController
|
||||||
end
|
end
|
||||||
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
|
def archive
|
||||||
return access_denied! unless can?(current_user, :archive_project, @project)
|
return access_denied! unless can?(current_user, :archive_project, @project)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
module AccountsHelper
|
||||||
|
def incoming_email_token_enabled?
|
||||||
|
current_user.incoming_email_token && Gitlab::IncomingEmail.supports_issue_creation?
|
||||||
|
end
|
||||||
|
end
|
|
@ -4,17 +4,21 @@ module TokenAuthenticatable
|
||||||
private
|
private
|
||||||
|
|
||||||
def write_new_token(token_field)
|
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)
|
write_attribute(token_field, new_token)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_token(token_field)
|
def generate_available_token(token_field)
|
||||||
loop do
|
loop do
|
||||||
token = Devise.friendly_token
|
token = generate_token(token_field)
|
||||||
break token unless self.class.unscoped.find_by(token_field => token)
|
break token unless self.class.unscoped.find_by(token_field => token)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def generate_token(token_field)
|
||||||
|
Devise.friendly_token
|
||||||
|
end
|
||||||
|
|
||||||
class_methods do
|
class_methods do
|
||||||
def authentication_token_fields
|
def authentication_token_fields
|
||||||
@token_fields || []
|
@token_fields || []
|
||||||
|
|
|
@ -624,13 +624,12 @@ class Project < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def new_issue_address(author)
|
def new_issue_address(author)
|
||||||
# This feature is disabled for the time being.
|
return unless Gitlab::IncomingEmail.supports_issue_creation? && author
|
||||||
return nil
|
|
||||||
|
|
||||||
if Gitlab::IncomingEmail.enabled? && author # rubocop:disable Lint/UnreachableCode
|
author.ensure_incoming_email_token!
|
||||||
Gitlab::IncomingEmail.reply_address(
|
|
||||||
"#{path_with_namespace}+#{author.authentication_token}")
|
Gitlab::IncomingEmail.reply_address(
|
||||||
end
|
"#{path_with_namespace}+#{author.incoming_email_token}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_commit_note(commit)
|
def build_commit_note(commit)
|
||||||
|
|
|
@ -13,6 +13,7 @@ class User < ActiveRecord::Base
|
||||||
DEFAULT_NOTIFICATION_LEVEL = :participating
|
DEFAULT_NOTIFICATION_LEVEL = :participating
|
||||||
|
|
||||||
add_authentication_token_field :authentication_token
|
add_authentication_token_field :authentication_token
|
||||||
|
add_authentication_token_field :incoming_email_token
|
||||||
|
|
||||||
default_value_for :admin, false
|
default_value_for :admin, false
|
||||||
default_value_for(:external) { current_application_settings.user_default_external }
|
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? }
|
before_validation :set_public_email, if: ->(user) { user.public_email_changed? }
|
||||||
|
|
||||||
after_update :update_emails_with_primary_email, if: ->(user) { user.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
|
before_save :ensure_external_user_rights
|
||||||
after_save :ensure_namespace_correct
|
after_save :ensure_namespace_correct
|
||||||
after_initialize :set_projects_limit
|
after_initialize :set_projects_limit
|
||||||
|
@ -956,4 +957,13 @@ class User < ActiveRecord::Base
|
||||||
signup_domain =~ regexp
|
signup_domain =~ regexp
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
|
@ -8,24 +8,36 @@
|
||||||
.row.prepend-top-default
|
.row.prepend-top-default
|
||||||
.col-lg-3.profile-settings-sidebar
|
.col-lg-3.profile-settings-sidebar
|
||||||
%h4.prepend-top-0
|
%h4.prepend-top-0
|
||||||
Private Token
|
= incoming_email_token_enabled? ? "Private Tokens" : "Private Token"
|
||||||
%p
|
%p
|
||||||
Your private token is used to access application resources without authentication.
|
Keep
|
||||||
.col-lg-9
|
= incoming_email_token_enabled? ? "these tokens" : "this token"
|
||||||
= form_for @user, url: reset_private_token_profile_path, method: :put, html: { class: "private-token" } do |f|
|
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
|
%p.cgray
|
||||||
- if current_user.private_token
|
- if current_user.private_token
|
||||||
= label_tag "token", "Private token", class: "label-light"
|
= label_tag "private-token", "Private token", class: "label-light"
|
||||||
= text_field_tag "token", current_user.private_token, class: "form-control"
|
= text_field_tag "private-token", current_user.private_token, class: "form-control", readonly: true, onclick: "this.select()"
|
||||||
- else
|
- else
|
||||||
%span You don`t have one yet. Click generate to fix it.
|
%span You don't have one yet. Click generate to fix it.
|
||||||
%p.help-block
|
%p.help-block
|
||||||
It can be used for atom feeds or the API. Keep it secret!
|
Your private token is used to access the API and Atom feeds without username/password authentication.
|
||||||
.prepend-top-default
|
.prepend-top-default
|
||||||
- if current_user.private_token
|
- 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
|
- else
|
||||||
= f.submit 'Generate', class: "btn btn-default"
|
= 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
|
%hr
|
||||||
.row.prepend-top-default
|
.row.prepend-top-default
|
||||||
.col-lg-3.profile-settings-sidebar
|
.col-lg-3.profile-settings-sidebar
|
||||||
|
|
|
@ -12,16 +12,23 @@
|
||||||
Create new issue by email
|
Create new issue by email
|
||||||
.modal-body
|
.modal-body
|
||||||
%p
|
%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
|
.email-modal-input-group.input-group
|
||||||
= text_field_tag :issue_email, email, class: "monospace js-select-on-focus form-control", readonly: true
|
= text_field_tag :issue_email, email, class: "monospace js-select-on-focus form-control", readonly: true
|
||||||
.input-group-btn
|
.input-group-btn
|
||||||
= clipboard_button(clipboard_target: '#issue_email')
|
= clipboard_button(clipboard_target: '#issue_email')
|
||||||
%p
|
%p
|
||||||
Send an email to this address to create an 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
|
%p
|
||||||
Use the subject line as the title of your issue.
|
This is a private email address, generated just for you.
|
||||||
%p
|
|
||||||
Use the message as the body of your issue (feel free to include some nice
|
Anyone who gets ahold of it can create issues as if they were you.
|
||||||
= succeed ")." do
|
You should
|
||||||
= link_to "Markdown", help_page_path('markdown', 'markdown')
|
= link_to 'reset it', new_issue_address_namespace_project_path(@project.namespace, @project), class: 'incoming-email-token-reset'
|
||||||
|
if that ever happens.
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
title: Use separate email-token for incoming email and revert back the inactive feature
|
||||||
|
merge_request: 5914
|
||||||
|
author:
|
|
@ -4,6 +4,7 @@ resource :profile, only: [:show, :update] do
|
||||||
get :applications, to: 'oauth/applications#index'
|
get :applications, to: 'oauth/applications#index'
|
||||||
|
|
||||||
put :reset_private_token
|
put :reset_private_token
|
||||||
|
put :reset_incoming_email_token
|
||||||
put :update_username
|
put :update_username
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ resources :namespaces, path: '/', constraints: { id: /[a-zA-Z.0-9_\-]+/ }, only:
|
||||||
get :autocomplete_sources
|
get :autocomplete_sources
|
||||||
get :activity
|
get :activity
|
||||||
get :refs
|
get :refs
|
||||||
|
put :new_issue_address
|
||||||
end
|
end
|
||||||
|
|
||||||
scope module: :projects do
|
scope module: :projects do
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
|
||||||
|
# for more information on how to write migrations for GitLab.
|
||||||
|
|
||||||
|
class AddIncomingEmailTokenToUsers < ActiveRecord::Migration
|
||||||
|
include Gitlab::Database::MigrationHelpers
|
||||||
|
|
||||||
|
# Set this constant to true if this migration requires downtime.
|
||||||
|
DOWNTIME = false
|
||||||
|
|
||||||
|
disable_ddl_transaction!
|
||||||
|
|
||||||
|
def change
|
||||||
|
add_column :users, :incoming_email_token, :string
|
||||||
|
add_concurrent_index :users, :incoming_email_token
|
||||||
|
end
|
||||||
|
end
|
|
@ -1183,6 +1183,7 @@ ActiveRecord::Schema.define(version: 20161106185620) do
|
||||||
t.boolean "ldap_email", default: false, null: false
|
t.boolean "ldap_email", default: false, null: false
|
||||||
t.boolean "external", default: false
|
t.boolean "external", default: false
|
||||||
t.string "organization"
|
t.string "organization"
|
||||||
|
t.string "incoming_email_token"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "users", ["admin"], name: "index_users_on_admin", using: :btree
|
add_index "users", ["admin"], name: "index_users_on_admin", using: :btree
|
||||||
|
@ -1192,6 +1193,7 @@ ActiveRecord::Schema.define(version: 20161106185620) do
|
||||||
add_index "users", ["current_sign_in_at"], name: "index_users_on_current_sign_in_at", using: :btree
|
add_index "users", ["current_sign_in_at"], name: "index_users_on_current_sign_in_at", using: :btree
|
||||||
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
|
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
|
||||||
add_index "users", ["email"], name: "index_users_on_email_trigram", using: :gin, opclasses: {"email"=>"gin_trgm_ops"}
|
add_index "users", ["email"], name: "index_users_on_email_trigram", using: :gin, opclasses: {"email"=>"gin_trgm_ops"}
|
||||||
|
add_index "users", ["incoming_email_token"], name: "index_users_on_incoming_email_token", using: :btree
|
||||||
add_index "users", ["name"], name: "index_users_on_name", using: :btree
|
add_index "users", ["name"], name: "index_users_on_name", using: :btree
|
||||||
add_index "users", ["name"], name: "index_users_on_name_trigram", using: :gin, opclasses: {"name"=>"gin_trgm_ops"}
|
add_index "users", ["name"], name: "index_users_on_name_trigram", using: :gin, opclasses: {"name"=>"gin_trgm_ops"}
|
||||||
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
|
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
|
||||||
|
|
|
@ -59,11 +59,6 @@ Feature: Profile
|
||||||
When I unsuccessfully change my password
|
When I unsuccessfully change my password
|
||||||
Then I should see a password error message
|
Then I should see a password error message
|
||||||
|
|
||||||
Scenario: I reset my token
|
|
||||||
Given I visit profile account page
|
|
||||||
Then I reset my token
|
|
||||||
And I should see new token
|
|
||||||
|
|
||||||
Scenario: I visit history tab
|
Scenario: I visit history tab
|
||||||
Given I have activity
|
Given I have activity
|
||||||
When I visit Audit Log page
|
When I visit Audit Log page
|
||||||
|
|
|
@ -104,18 +104,6 @@ class Spinach::Features::Profile < Spinach::FeatureSteps
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
step 'I reset my token' do
|
|
||||||
page.within '.private-token' do
|
|
||||||
@old_token = @user.private_token
|
|
||||||
click_button "Reset private token"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
step 'I should see new token' do
|
|
||||||
expect(find("#token").value).not_to eq @old_token
|
|
||||||
expect(find("#token").value).to eq @user.reload.private_token
|
|
||||||
end
|
|
||||||
|
|
||||||
step 'I have activity' do
|
step 'I have activity' do
|
||||||
create(:closed_issue_event, author: current_user)
|
create(:closed_issue_event, author: current_user)
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,8 +4,7 @@ require 'gitlab/email/handler/create_issue_handler'
|
||||||
module Gitlab
|
module Gitlab
|
||||||
module Email
|
module Email
|
||||||
module Handler
|
module Handler
|
||||||
# The `CreateIssueHandler` feature is disabled for the time being.
|
HANDLERS = [CreateNoteHandler, CreateIssueHandler]
|
||||||
HANDLERS = [CreateNoteHandler]
|
|
||||||
|
|
||||||
def self.for(mail, mail_key)
|
def self.for(mail, mail_key)
|
||||||
HANDLERS.find do |klass|
|
HANDLERS.find do |klass|
|
||||||
|
|
|
@ -5,16 +5,16 @@ module Gitlab
|
||||||
module Email
|
module Email
|
||||||
module Handler
|
module Handler
|
||||||
class CreateIssueHandler < BaseHandler
|
class CreateIssueHandler < BaseHandler
|
||||||
attr_reader :project_path, :authentication_token
|
attr_reader :project_path, :incoming_email_token
|
||||||
|
|
||||||
def initialize(mail, mail_key)
|
def initialize(mail, mail_key)
|
||||||
super(mail, mail_key)
|
super(mail, mail_key)
|
||||||
@project_path, @authentication_token =
|
@project_path, @incoming_email_token =
|
||||||
mail_key && mail_key.split('+', 2)
|
mail_key && mail_key.split('+', 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
def can_handle?
|
def can_handle?
|
||||||
!authentication_token.nil?
|
!incoming_email_token.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute
|
def execute
|
||||||
|
@ -29,7 +29,7 @@ module Gitlab
|
||||||
end
|
end
|
||||||
|
|
||||||
def author
|
def author
|
||||||
@author ||= User.find_by(authentication_token: authentication_token)
|
@author ||= User.find_by(incoming_email_token: incoming_email_token)
|
||||||
end
|
end
|
||||||
|
|
||||||
def project
|
def project
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
module Gitlab
|
module Gitlab
|
||||||
module IncomingEmail
|
module IncomingEmail
|
||||||
|
WILDCARD_PLACEHOLDER = '%{key}'.freeze
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
FALLBACK_MESSAGE_ID_REGEX = /\Areply\-(.+)@#{Gitlab.config.gitlab.host}\Z/.freeze
|
FALLBACK_MESSAGE_ID_REGEX = /\Areply\-(.+)@#{Gitlab.config.gitlab.host}\Z/.freeze
|
||||||
|
|
||||||
|
@ -7,8 +9,16 @@ module Gitlab
|
||||||
config.enabled && config.address
|
config.enabled && config.address
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def supports_wildcard?
|
||||||
|
config.address && config.address.include?(WILDCARD_PLACEHOLDER)
|
||||||
|
end
|
||||||
|
|
||||||
|
def supports_issue_creation?
|
||||||
|
enabled? && supports_wildcard?
|
||||||
|
end
|
||||||
|
|
||||||
def reply_address(key)
|
def reply_address(key)
|
||||||
config.address.gsub('%{key}', key)
|
config.address.gsub(WILDCARD_PLACEHOLDER, key)
|
||||||
end
|
end
|
||||||
|
|
||||||
def key_from_address(address)
|
def key_from_address(address)
|
||||||
|
|
|
@ -284,6 +284,33 @@ describe ProjectsController do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'PUT #new_issue_address' do
|
||||||
|
subject do
|
||||||
|
put :new_issue_address,
|
||||||
|
namespace_id: project.namespace.to_param,
|
||||||
|
id: project.to_param
|
||||||
|
user.reload
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in(user)
|
||||||
|
project.team << [user, :developer]
|
||||||
|
allow(Gitlab.config.incoming_email).to receive(:enabled).and_return(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'has http status 200' do
|
||||||
|
expect(response).to have_http_status(200)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'changes the user incoming email token' do
|
||||||
|
expect { subject }.to change { user.incoming_email_token }
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'changes projects new issue address' do
|
||||||
|
expect { subject }.to change { project.new_issue_address(user) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "POST #toggle_star" do
|
describe "POST #toggle_star" do
|
||||||
it "toggles star if user is signed in" do
|
it "toggles star if user is signed in" do
|
||||||
sign_in(user)
|
sign_in(user)
|
||||||
|
|
|
@ -3,6 +3,7 @@ require 'spec_helper'
|
||||||
describe 'Issues', feature: true do
|
describe 'Issues', feature: true do
|
||||||
include IssueHelpers
|
include IssueHelpers
|
||||||
include SortingHelper
|
include SortingHelper
|
||||||
|
include WaitForAjax
|
||||||
|
|
||||||
let(:project) { create(:project) }
|
let(:project) { create(:project) }
|
||||||
|
|
||||||
|
@ -368,6 +369,26 @@ describe 'Issues', feature: true do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'when I want to reset my incoming email token' do
|
||||||
|
let(:project1) { create(:project, namespace: @user.namespace) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(Gitlab.config.incoming_email).to receive(:enabled).and_return(true)
|
||||||
|
project1.team << [@user, :master]
|
||||||
|
visit namespace_project_issues_path(@user.namespace, project1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'changes incoming email address token', js: true do
|
||||||
|
find('.issue-email-modal-btn').click
|
||||||
|
previous_token = find('input#issue_email').value
|
||||||
|
|
||||||
|
find('.incoming-email-token-reset').click
|
||||||
|
wait_for_ajax
|
||||||
|
|
||||||
|
expect(find('input#issue_email').value).not_to eq(previous_token)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe 'update labels from issue#show', js: true do
|
describe 'update labels from issue#show', js: true do
|
||||||
let(:issue) { create(:issue, project: project, author: @user, assignee: @user) }
|
let(:issue) { create(:issue, project: project, author: @user, assignee: @user) }
|
||||||
let!(:label) { create(:label, project: project) }
|
let!(:label) { create(:label, project: project) }
|
||||||
|
@ -553,7 +574,7 @@ describe 'Issues', feature: true do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
xdescribe 'new issue by email' do
|
describe 'new issue by email' do
|
||||||
shared_examples 'show the email in the modal' do
|
shared_examples 'show the email in the modal' do
|
||||||
before do
|
before do
|
||||||
stub_incoming_email_setting(enabled: true, address: "p+%{key}@gl.ab")
|
stub_incoming_email_setting(enabled: true, address: "p+%{key}@gl.ab")
|
||||||
|
|
|
@ -32,4 +32,33 @@ describe 'Profile account page', feature: true do
|
||||||
expect(current_path).to eq(profile_account_path)
|
expect(current_path).to eq(profile_account_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'when I reset private token' do
|
||||||
|
before do
|
||||||
|
visit profile_account_path
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'resets private token' do
|
||||||
|
previous_token = find("#private-token").value
|
||||||
|
|
||||||
|
click_link('Reset private token')
|
||||||
|
|
||||||
|
expect(find('#private-token').value).not_to eq(previous_token)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'when I reset incoming email token' do
|
||||||
|
before do
|
||||||
|
allow(Gitlab.config.incoming_email).to receive(:enabled).and_return(true)
|
||||||
|
visit profile_account_path
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'resets incoming email token' do
|
||||||
|
previous_token = find('#incoming-email-token').value
|
||||||
|
|
||||||
|
click_link('Reset incoming email token')
|
||||||
|
|
||||||
|
expect(find('#incoming-email-token').value).not_to eq(previous_token)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
require_relative '../email_shared_blocks'
|
require_relative '../email_shared_blocks'
|
||||||
|
|
||||||
xdescribe Gitlab::Email::Handler::CreateIssueHandler, lib: true do
|
describe Gitlab::Email::Handler::CreateIssueHandler, lib: true do
|
||||||
include_context :email_shared_context
|
include_context :email_shared_context
|
||||||
it_behaves_like :email_shared_examples
|
it_behaves_like :email_shared_examples
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ xdescribe Gitlab::Email::Handler::CreateIssueHandler, lib: true do
|
||||||
create(
|
create(
|
||||||
:user,
|
:user,
|
||||||
email: 'jake@adventuretime.ooo',
|
email: 'jake@adventuretime.ooo',
|
||||||
authentication_token: 'auth_token'
|
incoming_email_token: 'auth_token'
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -60,8 +60,8 @@ xdescribe Gitlab::Email::Handler::CreateIssueHandler, lib: true do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when we can't find the authentication_token" do
|
context "when we can't find the incoming_email_token" do
|
||||||
let(:email_raw) { fixture_file("emails/wrong_authentication_token.eml") }
|
let(:email_raw) { fixture_file("emails/wrong_incoming_email_token.eml") }
|
||||||
|
|
||||||
it "raises an UserNotFoundError" do
|
it "raises an UserNotFoundError" do
|
||||||
expect { receiver.execute }.to raise_error(Gitlab::Email::UserNotFoundError)
|
expect { receiver.execute }.to raise_error(Gitlab::Email::UserNotFoundError)
|
||||||
|
|
|
@ -295,7 +295,7 @@ describe Project, models: true do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
xdescribe "#new_issue_address" do
|
describe "#new_issue_address" do
|
||||||
let(:project) { create(:empty_project, path: "somewhere") }
|
let(:project) { create(:empty_project, path: "somewhere") }
|
||||||
let(:user) { create(:user) }
|
let(:user) { create(:user) }
|
||||||
|
|
||||||
|
@ -305,8 +305,7 @@ describe Project, models: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns the address to create a new issue' do
|
it 'returns the address to create a new issue' do
|
||||||
token = user.authentication_token
|
address = "p+#{project.path_with_namespace}+#{user.incoming_email_token}@gl.ab"
|
||||||
address = "p+#{project.namespace.path}/#{project.path}+#{token}@gl.ab"
|
|
||||||
|
|
||||||
expect(project.new_issue_address(user)).to eq(address)
|
expect(project.new_issue_address(user)).to eq(address)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue