Commit 4e5597b852939d04535cc8453bb288da41654de7
Exists in
master
and in
4 other branches
Merge branch 'miks-deploy_keys_nonunique'
Showing
4 changed files
with
65 additions
and
8 deletions
Show diff stats
app/models/key.rb
1 | +require 'digest/md5' | ||
2 | + | ||
1 | class Key < ActiveRecord::Base | 3 | class Key < ActiveRecord::Base |
2 | belongs_to :user | 4 | belongs_to :user |
3 | belongs_to :project | 5 | belongs_to :project |
@@ -8,17 +10,30 @@ class Key < ActiveRecord::Base | @@ -8,17 +10,30 @@ class Key < ActiveRecord::Base | ||
8 | 10 | ||
9 | validates :key, | 11 | validates :key, |
10 | :presence => true, | 12 | :presence => true, |
11 | - :uniqueness => true, | ||
12 | :length => { :within => 0..5000 } | 13 | :length => { :within => 0..5000 } |
13 | 14 | ||
14 | before_save :set_identifier | 15 | before_save :set_identifier |
16 | + before_validation :strip_white_space | ||
15 | after_save :update_repository | 17 | after_save :update_repository |
16 | after_destroy :repository_delete_key | 18 | after_destroy :repository_delete_key |
17 | delegate :name, :email, :to => :user, :prefix => true | 19 | delegate :name, :email, :to => :user, :prefix => true |
20 | + validate :unique_key | ||
21 | + | ||
22 | + def strip_white_space | ||
23 | + self.key = self.key.strip unless self.key.blank? | ||
24 | + end | ||
25 | + | ||
26 | + def unique_key | ||
27 | + query = Key.where('key = ?', key) | ||
28 | + query = query.where('(project_id IS NULL OR project_id = ?)', project_id) if project_id | ||
29 | + if (query.count > 0) | ||
30 | + errors.add :key, 'already exist.' | ||
31 | + end | ||
32 | + end | ||
18 | 33 | ||
19 | def set_identifier | 34 | def set_identifier |
20 | if is_deploy_key | 35 | if is_deploy_key |
21 | - self.identifier = "deploy_#{project.code}_#{Time.now.to_i}" | 36 | + self.identifier = "deploy_" + Digest::MD5.hexdigest(key) |
22 | else | 37 | else |
23 | self.identifier = "#{user.identifier}_#{Time.now.to_i}" | 38 | self.identifier = "#{user.identifier}_#{Time.now.to_i}" |
24 | end | 39 | end |
@@ -33,11 +48,14 @@ class Key < ActiveRecord::Base | @@ -33,11 +48,14 @@ class Key < ActiveRecord::Base | ||
33 | 48 | ||
34 | def repository_delete_key | 49 | def repository_delete_key |
35 | Gitlabhq::GitHost.system.new.configure do |c| | 50 | Gitlabhq::GitHost.system.new.configure do |c| |
36 | - c.delete_key(identifier) | 51 | + #delete key file is there is no identically deploy keys |
52 | + if !is_deploy_key || Key.where(:identifier => identifier).count() == 0 | ||
53 | + c.delete_key(identifier) | ||
54 | + end | ||
37 | c.update_projects(projects) | 55 | c.update_projects(projects) |
38 | end | 56 | end |
39 | end | 57 | end |
40 | - | 58 | + |
41 | def is_deploy_key | 59 | def is_deploy_key |
42 | true if project_id | 60 | true if project_id |
43 | end | 61 | end |
db/schema.rb
@@ -163,6 +163,13 @@ ActiveRecord::Schema.define(:version => 20120228134252) do | @@ -163,6 +163,13 @@ ActiveRecord::Schema.define(:version => 20120228134252) do | ||
163 | t.integer "project_access", :default => 0, :null => false | 163 | t.integer "project_access", :default => 0, :null => false |
164 | end | 164 | end |
165 | 165 | ||
166 | + create_table "web_hook_urls", :force => true do |t| | ||
167 | + t.string "url" | ||
168 | + t.integer "project_id" | ||
169 | + t.datetime "created_at" | ||
170 | + t.datetime "updated_at" | ||
171 | + end | ||
172 | + | ||
166 | create_table "web_hooks", :force => true do |t| | 173 | create_table "web_hooks", :force => true do |t| |
167 | t.string "url" | 174 | t.string "url" |
168 | t.integer "project_id" | 175 | t.integer "project_id" |
spec/factory.rb
@@ -10,8 +10,8 @@ class Factory | @@ -10,8 +10,8 @@ class Factory | ||
10 | new(name, opts).tap(&:save!) | 10 | new(name, opts).tap(&:save!) |
11 | end | 11 | end |
12 | 12 | ||
13 | - def new(name, opts) | ||
14 | - factory = @factories[name] | 13 | + def new(name, opts = {}) |
14 | + factory= @factories[name] | ||
15 | factory[0].new.tap do |obj| | 15 | factory[0].new.tap do |obj| |
16 | factory[1].call(obj) | 16 | factory[1].call(obj) |
17 | end.tap do |obj| | 17 | end.tap do |obj| |
spec/models/key_spec.rb
@@ -14,8 +14,40 @@ describe Key do | @@ -14,8 +14,40 @@ describe Key do | ||
14 | it { should respond_to :projects } | 14 | it { should respond_to :projects } |
15 | end | 15 | end |
16 | 16 | ||
17 | - it { Factory.create(:key, | ||
18 | - :user => Factory(:user)).should be_valid } | 17 | + context "validation of uniqueness" do |
18 | + | ||
19 | + context "as a deploy key" do | ||
20 | + let(:project) { Factory.create(:project, path: 'alpha', code: 'alpha') } | ||
21 | + let(:another_project) { Factory.create(:project, path: 'beta', code: 'beta') } | ||
22 | + | ||
23 | + before do | ||
24 | + deploy_key = Factory.create(:key, project: project) | ||
25 | + end | ||
26 | + | ||
27 | + it "does not accept the same key twice for a project" do | ||
28 | + key = Factory.new(:key, project: project) | ||
29 | + key.should_not be_valid | ||
30 | + end | ||
31 | + | ||
32 | + it "does accept the same key for another project" do | ||
33 | + key = Factory.new(:key, project: another_project) | ||
34 | + key.should be_valid | ||
35 | + end | ||
36 | + end | ||
37 | + | ||
38 | + context "as a personal key" do | ||
39 | + let(:user) { Factory.create(:user) } | ||
40 | + | ||
41 | + it "accepts the key once" do | ||
42 | + Factory.new(:key, user: user).should be_valid | ||
43 | + end | ||
44 | + | ||
45 | + it "does not accepts the key twice" do | ||
46 | + Factory.create(:key, user: user) | ||
47 | + Factory.new(:key, user: user).should_not be_valid | ||
48 | + end | ||
49 | + end | ||
50 | + end | ||
19 | end | 51 | end |
20 | # == Schema Information | 52 | # == Schema Information |
21 | # | 53 | # |