summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/controllers/admin/deploy_keys_controller.rb2
-rw-r--r--app/controllers/projects/deploy_keys_controller.rb4
-rw-r--r--app/helpers/projects_helper.rb6
-rw-r--r--app/models/deploy_key.rb14
-rw-r--r--app/models/key.rb8
-rw-r--r--app/views/projects/deploy_keys/_form.html.haml9
-rw-r--r--changelogs/unreleased/feature-1376-allow-write-access-deploy-keys.yml4
-rw-r--r--db/migrate/20160811172945_add_can_push_to_keys.rb14
-rw-r--r--db/schema.rb1
-rw-r--r--doc/api/deploy_keys.md19
-rw-r--r--lib/api/entities.rb2
-rw-r--r--lib/gitlab/auth/result.rb3
-rw-r--r--lib/gitlab/checks/change_access.rb11
-rw-r--r--lib/gitlab/git_access.rb121
-rw-r--r--lib/gitlab/git_access_wiki.rb2
-rw-r--r--lib/gitlab/user_access.rb16
-rw-r--r--spec/lib/gitlab/git_access_spec.rb34
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml1
-rw-r--r--spec/models/deploy_key_spec.rb12
-rw-r--r--spec/models/key_spec.rb12
20 files changed, 207 insertions, 88 deletions
diff --git a/app/controllers/admin/deploy_keys_controller.rb b/app/controllers/admin/deploy_keys_controller.rb
index 285e8495342..6b146712940 100644
--- a/app/controllers/admin/deploy_keys_controller.rb
+++ b/app/controllers/admin/deploy_keys_controller.rb
@@ -10,7 +10,7 @@ class Admin::DeployKeysController < Admin::ApplicationController
end
def create
- @deploy_key = deploy_keys.new(deploy_key_params)
+ @deploy_key = deploy_keys.new(deploy_key_params.merge(user: current_user))
if @deploy_key.save
redirect_to admin_deploy_keys_path
diff --git a/app/controllers/projects/deploy_keys_controller.rb b/app/controllers/projects/deploy_keys_controller.rb
index 529e0aa2d33..b094491e006 100644
--- a/app/controllers/projects/deploy_keys_controller.rb
+++ b/app/controllers/projects/deploy_keys_controller.rb
@@ -16,7 +16,7 @@ class Projects::DeployKeysController < Projects::ApplicationController
end
def create
- @key = DeployKey.new(deploy_key_params)
+ @key = DeployKey.new(deploy_key_params.merge(user: current_user))
set_index_vars
if @key.valid? && @project.deploy_keys << @key
@@ -53,6 +53,6 @@ class Projects::DeployKeysController < Projects::ApplicationController
end
def deploy_key_params
- params.require(:deploy_key).permit(:key, :title)
+ params.require(:deploy_key).permit(:key, :title, :can_push)
end
end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 898ce6a3af7..704a80dd958 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -90,10 +90,12 @@ module ProjectsHelper
end
def project_for_deploy_key(deploy_key)
- if deploy_key.projects.include?(@project)
+ if deploy_key.has_access_to?(@project)
@project
else
- deploy_key.projects.find { |project| can?(current_user, :read_project, project) }
+ deploy_key.projects.find do |project|
+ can?(current_user, :read_project, project)
+ end
end
end
diff --git a/app/models/deploy_key.rb b/app/models/deploy_key.rb
index 2c525d4cd7a..053f2a11aa0 100644
--- a/app/models/deploy_key.rb
+++ b/app/models/deploy_key.rb
@@ -20,4 +20,18 @@ class DeployKey < Key
def destroyed_when_orphaned?
self.private?
end
+
+ def has_access_to?(project)
+ projects.include?(project)
+ end
+
+ def can_push_to?(project)
+ can_push? && has_access_to?(project)
+ end
+
+ private
+
+ # we don't want to notify the user for deploy keys
+ def notify_user
+ end
end
diff --git a/app/models/key.rb b/app/models/key.rb
index ff8dda2dc89..c0a64cfb5fc 100644
--- a/app/models/key.rb
+++ b/app/models/key.rb
@@ -49,10 +49,6 @@ class Key < ActiveRecord::Base
)
end
- def notify_user
- run_after_commit { NotificationService.new.new_key(self) }
- end
-
def post_create_hook
SystemHooksService.new.execute_hooks_for(self, :create)
end
@@ -78,4 +74,8 @@ class Key < ActiveRecord::Base
self.fingerprint = Gitlab::KeyFingerprint.new(self.key).fingerprint
end
+
+ def notify_user
+ run_after_commit { NotificationService.new.new_key(self) }
+ end
end
diff --git a/app/views/projects/deploy_keys/_form.html.haml b/app/views/projects/deploy_keys/_form.html.haml
index 901605f7ca3..757260aa5b5 100644
--- a/app/views/projects/deploy_keys/_form.html.haml
+++ b/app/views/projects/deploy_keys/_form.html.haml
@@ -10,4 +10,13 @@
%p.light.append-bottom-0
Paste a machine public key here. Read more about how to generate it
= link_to "here", help_page_path("ssh/README")
+ .form-group
+ .checkbox
+ = f.label :can_push do
+ = f.check_box :can_push
+ %strong Write access allowed?
+ .form-group
+ %p.light.append-bottom-0
+ Allow this key to push to repository as well? (Default only allows pull access.)
+
= f.submit "Add key", class: "btn-create btn"
diff --git a/changelogs/unreleased/feature-1376-allow-write-access-deploy-keys.yml b/changelogs/unreleased/feature-1376-allow-write-access-deploy-keys.yml
new file mode 100644
index 00000000000..0fd590a877b
--- /dev/null
+++ b/changelogs/unreleased/feature-1376-allow-write-access-deploy-keys.yml
@@ -0,0 +1,4 @@
+---
+title: Allow to add deploy keys with write-access
+merge_request: 5807
+author: Ali Ibrahim
diff --git a/db/migrate/20160811172945_add_can_push_to_keys.rb b/db/migrate/20160811172945_add_can_push_to_keys.rb
new file mode 100644
index 00000000000..5fd303fe8fb
--- /dev/null
+++ b/db/migrate/20160811172945_add_can_push_to_keys.rb
@@ -0,0 +1,14 @@
+class AddCanPushToKeys < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+ disable_ddl_transaction!
+
+ DOWNTIME = false
+
+ def up
+ add_column_with_default(:keys, :can_push, :boolean, default: false, allow_null: false)
+ end
+
+ def down
+ remove_column(:keys, :can_push)
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 6b28e80f01d..31bf0d1281a 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -528,6 +528,7 @@ ActiveRecord::Schema.define(version: 20161118183841) do
t.string "type"
t.string "fingerprint"
t.boolean "public", default: false, null: false
+ t.boolean "can_push", default: false, null: false
end
add_index "keys", ["fingerprint"], name: "index_keys_on_fingerprint", unique: true, using: :btree
diff --git a/doc/api/deploy_keys.md b/doc/api/deploy_keys.md
index 5f248ab6f91..284d5f88c55 100644
--- a/doc/api/deploy_keys.md
+++ b/doc/api/deploy_keys.md
@@ -20,12 +20,14 @@ Example response:
"id": 1,
"title": "Public key",
"key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=",
+ "can_push": false,
"created_at": "2013-10-02T10:12:29Z"
},
{
"id": 3,
"title": "Another Public key",
"key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=",
+ "can_push": true,
"created_at": "2013-10-02T11:12:29Z"
}
]
@@ -55,12 +57,14 @@ Example response:
"id": 1,
"title": "Public key",
"key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=",
+ "can_push": false,
"created_at": "2013-10-02T10:12:29Z"
},
{
"id": 3,
"title": "Another Public key",
"key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=",
+ "can_push": false,
"created_at": "2013-10-02T11:12:29Z"
}
]
@@ -92,6 +96,7 @@ Example response:
"id": 1,
"title": "Public key",
"key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=",
+ "can_push": false,
"created_at": "2013-10-02T10:12:29Z"
}
```
@@ -107,14 +112,15 @@ project only if original one was is accessible by the same user.
POST /projects/:id/deploy_keys
```
-| Attribute | Type | Required | Description |
-| --------- | ---- | -------- | ----------- |
-| `id` | integer | yes | The ID of the project |
-| `title` | string | yes | New deploy key's title |
-| `key` | string | yes | New deploy key |
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `id` | integer | yes | The ID of the project |
+| `title` | string | yes | New deploy key's title |
+| `key` | string | yes | New deploy key |
+| `can_push` | boolean | no | Can deploy key push to the project's repository |
```bash
-curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --header "Content-Type: application/json" --data '{"title": "My deploy key", "key": "ssh-rsa AAAA..."}' "https://gitlab.example.com/api/v3/projects/5/deploy_keys/"
+curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --header "Content-Type: application/json" --data '{"title": "My deploy key", "key": "ssh-rsa AAAA...", "can_push": "true"}' "https://gitlab.example.com/api/v3/projects/5/deploy_keys/"
```
Example response:
@@ -124,6 +130,7 @@ Example response:
"key" : "ssh-rsa AAAA...",
"id" : 12,
"title" : "My deploy key",
+ "can_push": true,
"created_at" : "2015-08-29T12:44:31.550Z"
}
```
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 33cb6fd3704..4cf8a478f1d 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -279,7 +279,7 @@ module API
end
class SSHKey < Grape::Entity
- expose :id, :title, :key, :created_at
+ expose :id, :title, :key, :created_at, :can_push
end
class SSHKeyWithUser < SSHKey
diff --git a/lib/gitlab/auth/result.rb b/lib/gitlab/auth/result.rb
index 6be7f690676..39b86c61a18 100644
--- a/lib/gitlab/auth/result.rb
+++ b/lib/gitlab/auth/result.rb
@@ -9,8 +9,7 @@ module Gitlab
def lfs_deploy_token?(for_project)
type == :lfs_deploy_token &&
- actor &&
- actor.projects.include?(for_project)
+ actor.try(:has_access_to?, for_project)
end
def success?
diff --git a/lib/gitlab/checks/change_access.rb b/lib/gitlab/checks/change_access.rb
index cb1065223d4..6b6a86ffde9 100644
--- a/lib/gitlab/checks/change_access.rb
+++ b/lib/gitlab/checks/change_access.rb
@@ -1,13 +1,15 @@
module Gitlab
module Checks
class ChangeAccess
- attr_reader :user_access, :project
+ attr_reader :user_access, :project, :skip_authorization
- def initialize(change, user_access:, project:)
+ def initialize(
+ change, user_access:, project:, skip_authorization: false)
@oldrev, @newrev, @ref = change.values_at(:oldrev, :newrev, :ref)
@branch_name = Gitlab::Git.branch_name(@ref)
@user_access = user_access
@project = project
+ @skip_authorization = skip_authorization
end
def exec
@@ -23,6 +25,7 @@ module Gitlab
protected
def protected_branch_checks
+ return if skip_authorization
return unless @branch_name
return unless project.protected_branch?(@branch_name)
@@ -48,6 +51,8 @@ module Gitlab
end
def tag_checks
+ return if skip_authorization
+
tag_ref = Gitlab::Git.tag_name(@ref)
if tag_ref && protected_tag?(tag_ref) && user_access.cannot_do_action?(:admin_project)
@@ -56,6 +61,8 @@ module Gitlab
end
def push_checks
+ return if skip_authorization
+
if user_access.cannot_do_action?(:push_code)
"You are not allowed to push code to this project."
end
diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb
index bcbf6455998..b87ca316240 100644
--- a/lib/gitlab/git_access.rb
+++ b/lib/gitlab/git_access.rb
@@ -7,7 +7,10 @@ module Gitlab
ERROR_MESSAGES = {
upload: 'You are not allowed to upload code for this project.',
download: 'You are not allowed to download code from this project.',
- deploy_key: 'Deploy keys are not allowed to push code.',
+ deploy_key_upload:
+ 'This deploy key does not have write access to this project.',
+ deploy_key:
+ 'This deploy key does not have access to this project.',
no_repo: 'A repository for this project does not exist yet.'
}
@@ -27,7 +30,7 @@ module Gitlab
def check(cmd, changes)
check_protocol!
- check_active_user!
+ check_active_user! unless deploy_key?
check_project_accessibility!
check_command_existence!(cmd)
@@ -44,25 +47,36 @@ module Gitlab
end
def download_access_check
- if user
- user_download_access_check
- elsif deploy_key.nil? && !Guest.can?(:download_code, project)
- raise UnauthorizedError, ERROR_MESSAGES[:download]
+ passed = if deploy_key
+ deploy_key.has_access_to?(project)
+ elsif user
+ user_can_download_code? || build_can_download_code?
+ end || Guest.can?(:download_code, project)
+
+ unless passed
+ message = if deploy_key
+ ERROR_MESSAGES[:deploy_key]
+ else
+ ERROR_MESSAGES[:download]
+ end
+
+ raise UnauthorizedError, message
end
end
def push_access_check(changes)
- if user
- user_push_access_check(changes)
+ if deploy_key
+ deploy_key_push_access_check
+ elsif user
+ user_push_access_check
else
- raise UnauthorizedError, ERROR_MESSAGES[deploy_key ? :deploy_key : :upload]
+ raise UnauthorizedError, ERROR_MESSAGES[:upload]
end
- end
- def user_download_access_check
- unless user_can_download_code? || build_can_download_code?
- raise UnauthorizedError, ERROR_MESSAGES[:download]
- end
+ return if changes.blank? # Allow access.
+
+ check_repository_existence!
+ check_change_access!(changes)
end
def user_can_download_code?
@@ -73,33 +87,16 @@ module Gitlab
authentication_abilities.include?(:build_download_code) && user_access.can_do_action?(:build_download_code)
end
- def user_push_access_check(changes)
+ def user_push_access_check
unless authentication_abilities.include?(:push_code)
raise UnauthorizedError, ERROR_MESSAGES[:upload]
end
-
- if changes.blank?
- return # Allow access.
- end
-
- unless project.repository.exists?
- raise UnauthorizedError, ERROR_MESSAGES[:no_repo]
- end
-
- changes_list = Gitlab::ChangesList.new(changes)
-
- # Iterate over all changes to find if user allowed all of them to be applied
- changes_list.each do |change|
- status = change_access_check(change)
- unless status.allowed?
- # If user does not have access to make at least one change - cancel all push
- raise UnauthorizedError, status.message
- end
- end
end
- def change_access_check(change)
- Checks::ChangeAccess.new(change, user_access: user_access, project: project).exec
+ def deploy_key_push_access_check
+ unless deploy_key.can_push_to?(project)
+ raise UnauthorizedError, ERROR_MESSAGES[:deploy_key_upload]
+ end
end
def protocol_allowed?
@@ -132,31 +129,51 @@ module Gitlab
end
end
+ def check_repository_existence!
+ unless project.repository.exists?
+ raise UnauthorizedError, ERROR_MESSAGES[:no_repo]
+ end
+ end
+
+ def check_change_access!(changes)
+ changes_list = Gitlab::ChangesList.new(changes)
+
+ # Iterate over all changes to find if user allowed all of them to be applied
+ changes_list.each do |change|
+ status = check_single_change_access(change)
+ unless status.allowed?
+ # If user does not have access to make at least one change - cancel all push
+ raise UnauthorizedError, status.message
+ end
+ end
+ end
+
+ def check_single_change_access(change)
+ Checks::ChangeAccess.new(
+ change,
+ user_access: user_access,
+ project: project,
+ skip_authorization: deploy_key?).exec
+ end
+
def matching_merge_request?(newrev, branch_name)
Checks::MatchingMergeRequest.new(newrev, branch_name, project).match?
end
def deploy_key
- actor if actor.is_a?(DeployKey)
+ actor if deploy_key?
end
- def deploy_key_can_read_project?
- if deploy_key
- return true if project.public?
- deploy_key.projects.include?(project)
- else
- false
- end
+ def deploy_key?
+ actor.is_a?(DeployKey)
end
def can_read_project?
- if user
- user_access.can_read_project?
- elsif deploy_key
- deploy_key_can_read_project?
- else
- Guest.can?(:read_project, project)
- end
+ if deploy_key
+ deploy_key.has_access_to?(project)
+ elsif user
+ user.can?(:read_project, project)
+ end || Guest.can?(:read_project, project)
end
protected
@@ -168,8 +185,6 @@ module Gitlab
case actor
when User
actor
- when DeployKey
- nil
when Key
actor.user
end
diff --git a/lib/gitlab/git_access_wiki.rb b/lib/gitlab/git_access_wiki.rb
index f71d3575909..f7976a64ef5 100644
--- a/lib/gitlab/git_access_wiki.rb
+++ b/lib/gitlab/git_access_wiki.rb
@@ -1,6 +1,6 @@
module Gitlab
class GitAccessWiki < GitAccess
- def change_access_check(change)
+ def check_single_change_access(change)
if user_access.can_do_action?(:create_wiki)
build_status_object(true)
else
diff --git a/lib/gitlab/user_access.rb b/lib/gitlab/user_access.rb
index 9858d2e7d83..6c7e673fb9f 100644
--- a/lib/gitlab/user_access.rb
+++ b/lib/gitlab/user_access.rb
@@ -8,6 +8,8 @@ module Gitlab
end
def can_do_action?(action)
+ return false if no_user_or_blocked?
+
@permission_cache ||= {}
@permission_cache[action] ||= user.can?(action, project)
end
@@ -17,7 +19,7 @@ module Gitlab
end
def allowed?
- return false if user.blank? || user.blocked?
+ return false if no_user_or_blocked?
if user.requires_ldap_check? && user.try_obtain_ldap_lease
return false unless Gitlab::LDAP::Access.allowed?(user)
@@ -27,7 +29,7 @@ module Gitlab
end
def can_push_to_branch?(ref)
- return false unless user
+ return false if no_user_or_blocked?
if project.protected_branch?(ref)
return true if project.empty_repo? && project.user_can_push_to_empty_repo?(user)
@@ -40,7 +42,7 @@ module Gitlab
end
def can_merge_to_branch?(ref)
- return false unless user
+ return false if no_user_or_blocked?
if project.protected_branch?(ref)
access_levels = project.protected_branches.matching(ref).map(&:merge_access_levels).flatten
@@ -51,9 +53,15 @@ module Gitlab
end
def can_read_project?
- return false unless user
+ return false if no_user_or_blocked?
user.can?(:read_project, project)
end
+
+ private
+
+ def no_user_or_blocked?
+ user.nil? || user.blocked?
+ end
end
end
diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb
index f1d0a190002..2c90397cc78 100644
--- a/spec/lib/gitlab/git_access_spec.rb
+++ b/spec/lib/gitlab/git_access_spec.rb
@@ -82,7 +82,7 @@ describe Gitlab::GitAccess, lib: true do
end
end
- describe 'without acccess to project' do
+ describe 'without access to project' do
context 'pull code' do
it { expect(subject.allowed?).to be_falsey }
end
@@ -112,7 +112,7 @@ describe Gitlab::GitAccess, lib: true do
end
describe 'deploy key permissions' do
- let(:key) { create(:deploy_key) }
+ let(:key) { create(:deploy_key, user: user) }
let(:actor) { key }
context 'pull code' do
@@ -136,7 +136,7 @@ describe Gitlab::GitAccess, lib: true do
end
context 'from private project' do
- let(:project) { create(:project, :internal) }
+ let(:project) { create(:project, :private) }
it { expect(subject).not_to be_allowed }
end
@@ -353,13 +353,13 @@ describe Gitlab::GitAccess, lib: true do
end
end
- shared_examples 'can not push code' do
+ shared_examples 'pushing code' do |can|
subject { access.check('git-receive-pack', '_any') }
context 'when project is authorized' do
before { authorize }
- it { expect(subject).not_to be_allowed }
+ it { expect(subject).public_send(can, be_allowed) }
end
context 'when unauthorized' do
@@ -386,7 +386,7 @@ describe Gitlab::GitAccess, lib: true do
describe 'build authentication abilities' do
let(:authentication_abilities) { build_authentication_abilities }
- it_behaves_like 'can not push code' do
+ it_behaves_like 'pushing code', :not_to do
def authorize
project.team << [user, :reporter]
end
@@ -394,12 +394,26 @@ describe Gitlab::GitAccess, lib: true do
end
describe 'deploy key permissions' do
- let(:key) { create(:deploy_key) }
+ let(:key) { create(:deploy_key, user: user, can_push: can_push) }
let(:actor) { key }
- it_behaves_like 'can not push code' do
- def authorize
- key.projects << project
+ context 'when deploy_key can push' do
+ let(:can_push) { true }
+
+ it_behaves_like 'pushing code', :to do
+ def authorize
+ key.projects << project
+ end
+ end
+ end
+
+ context 'when deploy_key cannot push' do
+ let(:can_push) { false }
+
+ it_behaves_like 'pushing code', :not_to do
+ def authorize
+ key.projects << project
+ end
end
end
end
diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml
index d6807941b31..f8531bf715b 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -246,6 +246,7 @@ DeployKey:
- type
- fingerprint
- public
+- can_push
Service:
- id
- type
diff --git a/spec/models/deploy_key_spec.rb b/spec/models/deploy_key_spec.rb
index 93623e8e99b..3a2252ea40c 100644
--- a/spec/models/deploy_key_spec.rb
+++ b/spec/models/deploy_key_spec.rb
@@ -5,4 +5,16 @@ describe DeployKey, models: true do
it { is_expected.to have_many(:deploy_keys_projects) }
it { is_expected.to have_many(:projects) }
end
+
+ describe 'notification' do
+ let(:user) { create(:user) }
+
+ it 'does not send a notification' do
+ perform_enqueued_jobs do
+ create(:deploy_key, user: user)
+ end
+
+ should_not_email(user)
+ end
+ end
end
diff --git a/spec/models/key_spec.rb b/spec/models/key_spec.rb
index 90731f55470..0c0444e1f2a 100644
--- a/spec/models/key_spec.rb
+++ b/spec/models/key_spec.rb
@@ -92,4 +92,16 @@ describe Key, models: true do
expect(described_class.new(key: " #{valid_key} ").key).to eq(valid_key)
end
end
+
+ describe 'notification' do
+ let(:user) { create(:user) }
+
+ it 'sends a notification' do
+ perform_enqueued_jobs do
+ create(:key, user: user)
+ end
+
+ should_email(user)
+ end
+ end
end