summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG5
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock4
-rw-r--r--app/helpers/tree_helper.rb2
-rw-r--r--app/models/project_services/slack_service.rb14
-rw-r--r--app/models/user.rb5
-rw-r--r--doc/api/projects.md3
-rw-r--r--doc/integration/slack.md28
-rw-r--r--doc/update/7.3-to-7.4.md1
-rw-r--r--features/steps/project/services.rb4
-rw-r--r--lib/api/entities.rb6
-rw-r--r--lib/gitlab/auth.rb2
-rw-r--r--lib/gitlab/git.rb5
-rw-r--r--lib/gitlab/git_access.rb4
-rw-r--r--spec/lib/gitlab/auth_spec.rb10
-rw-r--r--spec/lib/gitlab/git_access_spec.rb7
-rw-r--r--spec/models/slack_message_spec.rb2
-rw-r--r--spec/models/slack_service_spec.rb56
-rw-r--r--spec/models/user_spec.rb14
-rw-r--r--spec/requests/api/projects_spec.rb1
-rw-r--r--spec/requests/api/session_spec.rb26
21 files changed, 116 insertions, 85 deletions
diff --git a/CHANGELOG b/CHANGELOG
index cc287b67063..ff41575bcc6 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -5,7 +5,10 @@ v 7.5.0
- Fix LDAP config lookup for provider 'ldap'
- Add Atlassian Bamboo CI service (Drew Blessing)
- Mentioned @user will receive email even if he is not participating in issue or commit
+ - Session API: Use case-insensitive authentication like in UI (Andrey Krivko)
- Tie up loose ends with annotated tags: API & UI (Sean Edge)
+ - Return valid json for deleting branch via API (sponsored by O'Reilly Media)
+ - Expose username in project events API (sponsored by O'Reilly Media)
v 7.4.2
- Fix internal snippet exposing for unauthenticated users
@@ -50,7 +53,7 @@ v 7.4.0
- Fix ambiguous sha problem with mentioned commit
- Fixed bug with apostrophe when at mentioning users
- Add active directory ldap option
- - Developers can push to wiki repo. Protected branches does not affect wiki repo any more
+ - Developers can push to wiki repo. Protected branches does not affect wiki repo any more
- Faster rev list
- Fix branch removal
diff --git a/Gemfile b/Gemfile
index a2314236e29..dc84b26bc4c 100644
--- a/Gemfile
+++ b/Gemfile
@@ -143,7 +143,7 @@ gem "gitlab-flowdock-git-hook", "~> 0.4.2"
gem "gemnasium-gitlab-service", "~> 0.2"
# Slack integration
-gem "slack-notifier", "~> 0.3.2"
+gem "slack-notifier", "~> 1.0.0"
# d3
gem "d3_rails", "~> 3.1.4"
diff --git a/Gemfile.lock b/Gemfile.lock
index 800f33590cb..c283d4384fc 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -488,7 +488,7 @@ GEM
rack-protection (~> 1.4)
tilt (~> 1.3, >= 1.3.4)
six (0.2.0)
- slack-notifier (0.3.2)
+ slack-notifier (1.0.0)
slim (2.0.2)
temple (~> 0.6.6)
tilt (>= 1.3.3, < 2.1)
@@ -689,7 +689,7 @@ DEPENDENCIES
simplecov
sinatra
six
- slack-notifier (~> 0.3.2)
+ slack-notifier (~> 1.0.0)
slim
spinach-rails
spring (= 1.1.3)
diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb
index 9c611a1c147..8e209498323 100644
--- a/app/helpers/tree_helper.rb
+++ b/app/helpers/tree_helper.rb
@@ -66,7 +66,7 @@ module TreeHelper
def tree_breadcrumbs(tree, max_links = 2)
if @path.present?
part_path = ""
- parts = @path.split("\/")
+ parts = @path.split('/')
yield('..', nil) if parts.count > max_links
diff --git a/app/models/project_services/slack_service.rb b/app/models/project_services/slack_service.rb
index 837002ef3c8..963f5440b6f 100644
--- a/app/models/project_services/slack_service.rb
+++ b/app/models/project_services/slack_service.rb
@@ -30,24 +30,20 @@ class SlackService < Service
def fields
[
- { type: 'text', name: 'webhook', placeholder: '' }
+ { type: 'text', name: 'webhook', placeholder: 'https://hooks.slack.com/services/...' }
]
end
def execute(push_data)
+ return unless webhook.present?
+
message = SlackMessage.new(push_data.merge(
project_url: project_url,
project_name: project_name
))
- credentials = webhook.match(/([\w-]*).slack.com.*services\/(.*)/)
-
- if credentials.present?
- subdomain = credentials[1]
- token = credentials[2].split("token=").last
- notifier = Slack::Notifier.new(subdomain, token)
- notifier.ping(message.pretext, attachments: message.attachments)
- end
+ notifier = Slack::Notifier.new(webhook)
+ notifier.ping(message.pretext, attachments: message.attachments)
end
private
diff --git a/app/models/user.rb b/app/models/user.rb
index 154cc0f3e16..52e63cde6f9 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -226,6 +226,11 @@ class User < ActiveRecord::Base
where("lower(name) LIKE :query OR lower(email) LIKE :query OR lower(username) LIKE :query", query: "%#{query.downcase}%")
end
+ def by_login(login)
+ where('lower(username) = :value OR lower(email) = :value',
+ value: login.to_s.downcase).first
+ end
+
def by_username_or_id(name_or_id)
where('users.username = ? OR users.id = ?', name_or_id.to_s, name_or_id.to_i).first
end
diff --git a/doc/api/projects.md b/doc/api/projects.md
index dfe3502b6e4..0055e2e476f 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -186,6 +186,7 @@ Parameters:
"target_id": 830,
"target_type": "Issue",
"author_id": 1,
+ "author_username": "john",
"data": null,
"target_title": "Public project search field"
},
@@ -196,6 +197,7 @@ Parameters:
"target_id": null,
"target_type": null,
"author_id": 1,
+ "author_username": "john",
"data": {
"before": "50d4420237a9de7be1304607147aec22e4a14af7",
"after": "c5feabde2d8cd023215af4d2ceeb7a64839fc428",
@@ -231,6 +233,7 @@ Parameters:
"target_id": 840,
"target_type": "Issue",
"author_id": 1,
+ "author_username": "john",
"data": null,
"target_title": "Finish & merge Code search PR"
}
diff --git a/doc/integration/slack.md b/doc/integration/slack.md
index 95cb0c6fae2..f2e73f272ef 100644
--- a/doc/integration/slack.md
+++ b/doc/integration/slack.md
@@ -4,15 +4,23 @@
To enable Slack integration you must create an Incoming WebHooks integration on Slack;
-1. Sign in to [Slack](https://slack.com) (https://YOURSUBDOMAIN.slack.com/services)
-1. Click on the Integrations menu at the top of the page.
-1. Add a new Integration.
+1. [Sign in to Slack](https://slack.com/signin)
+
+1. Select **Configure Integrations** from the dropdown next to your team name.
+
+1. Select the **All Services** tab
+
+1. Click **Add** next to Incoming Webhooks
+
1. Pick Incoming WebHooks
-1. Choose the channel name you want to send notifications to, in the Settings section
-1. Add Integrations.
- - Optional step; You can change bot's name and avatar by clicking "change the name of your bot", and "change the icon" after that you have to click "Save settings".
-Now, Slack is ready to get external hooks. Before you leave this page don't forget to get the Token that you'll need on GitLab. You can find it by clicking Expand button, located in the "Instructions for creating Incoming WebHooks" section. It's a random alpha-numeric text 24 characters long.
+1. Choose the channel name you want to send notifications to
+
+1. Click **Add Incoming WebHooks Integration**Add Integrations.
+ - Optional step; You can change bot's name and avatar by clicking modifying the bot name or avatar under **Integration Settings**.
+
+1. Copy the **Webhook URL**, we'll need this later for GitLab.
+
## On GitLab
@@ -26,10 +34,8 @@ After Slack is ready we need to setup GitLab. Here are the steps to achieve this
1. Fill in your Slack details
- - Mark as active it
- - Type your subdomain's prefix (If your subdomain is https://somedomain.slack.com you only have to type the somedomain)
- - Type in the token you got from Slack
- - Type in the channel name you want to use (eg. #announcements)
+ - Mark it as active
+ - Paste in the webhook url you got from Slack
Have fun :)
diff --git a/doc/update/7.3-to-7.4.md b/doc/update/7.3-to-7.4.md
index 69d86fb06ed..3f471500c82 100644
--- a/doc/update/7.3-to-7.4.md
+++ b/doc/update/7.3-to-7.4.md
@@ -9,6 +9,7 @@
```bash
cd /home/git/gitlab
sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
+```
### 2. Get latest code
diff --git a/features/steps/project/services.rb b/features/steps/project/services.rb
index 17d62210d10..d5d58070d86 100644
--- a/features/steps/project/services.rb
+++ b/features/steps/project/services.rb
@@ -109,12 +109,12 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps
step 'I fill Slack settings' do
check 'Active'
- fill_in 'Webhook', with: 'https://gitlabhq.slack.com/services/hooks?token=cdIj4r4LfXUOySDUjp0tk3OI'
+ fill_in 'Webhook', with: 'https://hooks.slack.com/services/SVRWFV0VVAR97N/B02R25XN3/ZBqu7xMupaEEICInN685'
click_button 'Save'
end
step 'I should see Slack service settings saved' do
- find_field('Webhook').value.should == 'https://gitlabhq.slack.com/services/hooks?token=cdIj4r4LfXUOySDUjp0tk3OI'
+ find_field('Webhook').value.should == 'https://hooks.slack.com/services/SVRWFV0VVAR97N/B02R25XN3/ZBqu7xMupaEEICInN685'
end
step 'I click Pushover service link' do
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index db2dead487f..40696489ba2 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -184,6 +184,12 @@ module API
expose :target_id, :target_type, :author_id
expose :data, :target_title
expose :created_at
+
+ expose :author_username do |event, options|
+ if event.author
+ event.author.username
+ end
+ end
end
class Namespace < Grape::Entity
diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb
index ae33c529b93..30509528b8b 100644
--- a/lib/gitlab/auth.rb
+++ b/lib/gitlab/auth.rb
@@ -1,7 +1,7 @@
module Gitlab
class Auth
def find(login, password)
- user = User.find_by(email: login) || User.find_by(username: login)
+ user = User.by_login(login)
# If no user is found, or it's an LDAP server, try LDAP.
# LDAP users are only authenticated via LDAP
diff --git a/lib/gitlab/git.rb b/lib/gitlab/git.rb
new file mode 100644
index 00000000000..67aca5e36e9
--- /dev/null
+++ b/lib/gitlab/git.rb
@@ -0,0 +1,5 @@
+module Gitlab
+ module Git
+ BLANK_SHA = '0' * 40
+ end
+end
diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb
index b768a99a0e8..129881060d5 100644
--- a/lib/gitlab/git_access.rb
+++ b/lib/gitlab/git_access.rb
@@ -67,7 +67,7 @@ module Gitlab
if forced_push?(project, oldrev, newrev)
:force_push_code_to_protected_branches
# and we dont allow remove of protected branch
- elsif newrev =~ /0000000/
+ elsif newrev == Gitlab::Git::BLANK_SHA
:remove_protected_branches
else
:push_code_to_protected_branches
@@ -85,7 +85,7 @@ module Gitlab
def forced_push?(project, oldrev, newrev)
return false if project.empty_repo?
- if oldrev !~ /00000000/ && newrev !~ /00000000/
+ if oldrev != Gitlab::Git::BLANK_SHA && newrev != Gitlab::Git::BLANK_SHA
missed_refs = IO.popen(%W(git --git-dir=#{project.repository.path_to_repo} rev-list #{oldrev} ^#{newrev})).read
missed_refs.split("\n").size > 0
else
diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb
index 1f3e1a4a3c1..95fc7e16a11 100644
--- a/spec/lib/gitlab/auth_spec.rb
+++ b/spec/lib/gitlab/auth_spec.rb
@@ -10,13 +10,21 @@ describe Gitlab::Auth do
password: password,
password_confirmation: password)
end
- let(:username) { 'john' }
+ let(:username) { 'John' } # username isn't lowercase, test this
let(:password) { 'my-secret' }
it "should find user by valid login/password" do
expect( gl_auth.find(username, password) ).to eql user
end
+ it 'should find user by valid email/password with case-insensitive email' do
+ expect(gl_auth.find(user.email.upcase, password)).to eql user
+ end
+
+ it 'should find user by valid username/password with case-insensitive username' do
+ expect(gl_auth.find(username.upcase, password)).to eql user
+ end
+
it "should not find user with invalid password" do
password = 'wrong'
expect( gl_auth.find(username, password) ).to_not eql user
diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb
index 570b03827a8..fe0a6bbdabb 100644
--- a/spec/lib/gitlab/git_access_spec.rb
+++ b/spec/lib/gitlab/git_access_spec.rb
@@ -55,12 +55,13 @@ describe Gitlab::GitAccess do
def changes
{
- push_new_branch: '000000000 570e7b2ab refs/heads/wow',
+ push_new_branch: "#{Gitlab::Git::BLANK_SHA} 570e7b2ab refs/heads/wow",
push_master: '6f6d7e7ed 570e7b2ab refs/heads/master',
push_protected_branch: '6f6d7e7ed 570e7b2ab refs/heads/feature',
- push_remove_protected_branch: '570e7b2ab 000000000 refs/heads/feature',
+ push_remove_protected_branch: "570e7b2ab #{Gitlab::Git::BLANK_SHA} "\
+ 'refs/heads/feature',
push_tag: '6f6d7e7ed 570e7b2ab refs/tags/v1.0.0',
- push_new_tag: '000000000 570e7b2ab refs/tags/v7.8.9',
+ push_new_tag: "#{Gitlab::Git::BLANK_SHA} 570e7b2ab refs/tags/v7.8.9",
push_all: ['6f6d7e7ed 570e7b2ab refs/heads/master', '6f6d7e7ed 570e7b2ab refs/heads/feature']
}
end
diff --git a/spec/models/slack_message_spec.rb b/spec/models/slack_message_spec.rb
index 1cd58534702..78d743e01bf 100644
--- a/spec/models/slack_message_spec.rb
+++ b/spec/models/slack_message_spec.rb
@@ -1,4 +1,4 @@
-require_relative '../../app/models/project_services/slack_message'
+require 'spec_helper'
describe SlackMessage do
subject { SlackMessage.new(args) }
diff --git a/spec/models/slack_service_spec.rb b/spec/models/slack_service_spec.rb
index 526165e397c..d4840391967 100644
--- a/spec/models/slack_service_spec.rb
+++ b/spec/models/slack_service_spec.rb
@@ -31,71 +31,27 @@ describe SlackService do
end
describe "Execute" do
- let(:slack) { SlackService.new }
- let(:slack_service) { SlackService.new }
- let(:user) { create(:user) }
+ let(:slack) { SlackService.new }
+ let(:user) { create(:user) }
let(:project) { create(:project) }
let(:sample_data) { GitPushService.new.sample_data(project, user) }
- let(:webhook) { 'https://gitlabhq.slack.com/services/hooks?token=cdIj4r4LfXUOySDUjp0tk3OI' }
- let(:new_webhook) { 'https://hooks.gitlabhq.slack.com/services/cdIj4r4LfXUOySDUjp0tk3OI' }
- let(:api_url) {
- 'https://gitlabhq.slack.com/services/hooks/incoming-webhook?token=cdIj4r4LfXUOySDUjp0tk3OI'
- }
+ let(:webhook_url) { 'https://hooks.slack.com/services/SVRWFV0VVAR97N/B02R25XN3/ZBqu7xMupaEEICInN685' }
before do
slack.stub(
project: project,
project_id: project.id,
service_hook: true,
- webhook: webhook
+ webhook: webhook_url
)
- WebMock.stub_request(:post, api_url)
+ WebMock.stub_request(:post, webhook_url)
end
it "should call Slack API" do
slack.execute(sample_data)
- WebMock.should have_requested(:post, api_url).once
- end
-
- context 'with new webhook syntax' do
- before do
- slack_service.stub(
- project: project,
- project_id: project.id,
- service_hook: true,
- webhook: new_webhook
- )
-
- WebMock.stub_request(:post, api_url)
- end
-
- it "should call Slack API" do
- slack_service.execute(sample_data)
-
- WebMock.should have_requested(:post, api_url).once
- end
- end
-
- context 'with new webhook syntax with slack allowed team name' do
- before do
- @allowed_webhook = 'https://gitlab-hq-123.slack.com/services/hooks/incoming-webhook?token=cdIj4r4LfXUOySDUjp0tk3OI'
- slack_service.stub(
- project: project,
- project_id: project.id,
- service_hook: true,
- webhook: @allowed_webhook
- )
-
- WebMock.stub_request(:post, @allowed_webhook)
- end
-
- it "should call Slack API" do
- slack_service.execute(sample_data)
-
- WebMock.should have_requested(:post, @allowed_webhook).once
- end
+ WebMock.should have_requested(:post, webhook_url).once
end
end
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 6ad57b06e06..6d865cfc691 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -287,6 +287,20 @@ describe User do
end
end
+ describe '.by_login' do
+ let(:username) { 'John' }
+ let!(:user) { create(:user, username: username) }
+
+ it 'should get the correct user' do
+ expect(User.by_login(user.email.upcase)).to eq user
+ expect(User.by_login(user.email)).to eq user
+ expect(User.by_login(username.downcase)).to eq user
+ expect(User.by_login(username)).to eq user
+ expect(User.by_login(nil)).to be_nil
+ expect(User.by_login('')).to be_nil
+ end
+ end
+
describe 'all_ssh_keys' do
it { should have_many(:keys).dependent(:destroy) }
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index ba7ec7b2be9..cb7a2705573 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -339,6 +339,7 @@ describe API::API, api: true do
json_event['action_name'].should == 'joined'
json_event['project_id'].to_i.should == project.id
+ json_event['author_username'].should == user.username
end
it "should return a 404 error if not found" do
diff --git a/spec/requests/api/session_spec.rb b/spec/requests/api/session_spec.rb
index 013f425d6ce..57b2e6cbd6a 100644
--- a/spec/requests/api/session_spec.rb
+++ b/spec/requests/api/session_spec.rb
@@ -19,6 +19,32 @@ describe API::API, api: true do
end
end
+ context 'when email has case-typo and password is valid' do
+ it 'should return private token' do
+ post api('/session'), email: user.email.upcase, password: '12345678'
+ expect(response.status).to eq 201
+
+ expect(json_response['email']).to eq user.email
+ expect(json_response['private_token']).to eq user.private_token
+ expect(json_response['is_admin']).to eq user.is_admin?
+ expect(json_response['can_create_project']).to eq user.can_create_project?
+ expect(json_response['can_create_group']).to eq user.can_create_group?
+ end
+ end
+
+ context 'when login has case-typo and password is valid' do
+ it 'should return private token' do
+ post api('/session'), login: user.username.upcase, password: '12345678'
+ expect(response.status).to eq 201
+
+ expect(json_response['email']).to eq user.email
+ expect(json_response['private_token']).to eq user.private_token
+ expect(json_response['is_admin']).to eq user.is_admin?
+ expect(json_response['can_create_project']).to eq user.can_create_project?
+ expect(json_response['can_create_group']).to eq user.can_create_group?
+ end
+ end
+
context "when invalid password" do
it "should return authentication error" do
post api("/session"), email: user.email, password: '123'