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 | # |