diff --git a/app/models/key.rb b/app/models/key.rb index 4114e5261dc5285b05753df6156b9ffda043a90f..779d985d98b2e3555e5b8b0e7f7babc17d89ccd4 100644 --- a/app/models/key.rb +++ b/app/models/key.rb @@ -1,3 +1,5 @@ +require 'digest/md5' + class Key < ActiveRecord::Base belongs_to :user belongs_to :project @@ -8,17 +10,30 @@ class Key < ActiveRecord::Base validates :key, :presence => true, - :uniqueness => true, :length => { :within => 0..5000 } before_save :set_identifier + before_validation :strip_white_space after_save :update_repository after_destroy :repository_delete_key delegate :name, :email, :to => :user, :prefix => true + validate :unique_key + + def strip_white_space + self.key = self.key.strip unless self.key.blank? + end + + def unique_key + query = Key.where('key = ?', key) + query = query.where('(project_id IS NULL OR project_id = ?)', project_id) if project_id + if (query.count > 0) + errors.add :key, 'already exist.' + end + end def set_identifier if is_deploy_key - self.identifier = "deploy_#{project.code}_#{Time.now.to_i}" + self.identifier = "deploy_" + Digest::MD5.hexdigest(key) else self.identifier = "#{user.identifier}_#{Time.now.to_i}" end @@ -33,11 +48,14 @@ class Key < ActiveRecord::Base def repository_delete_key Gitlabhq::GitHost.system.new.configure do |c| - c.delete_key(identifier) + #delete key file is there is no identically deploy keys + if !is_deploy_key || Key.where(:identifier => identifier).count() == 0 + c.delete_key(identifier) + end c.update_projects(projects) end end - + def is_deploy_key true if project_id end diff --git a/db/schema.rb b/db/schema.rb index a0baf8e2d6745b643e93e54402cdbb48bba0af3c..c5e14a69542253de70f9dffe9b5448d96f693ebc 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -163,6 +163,13 @@ ActiveRecord::Schema.define(:version => 20120228134252) do t.integer "project_access", :default => 0, :null => false end + create_table "web_hook_urls", :force => true do |t| + t.string "url" + t.integer "project_id" + t.datetime "created_at" + t.datetime "updated_at" + end + create_table "web_hooks", :force => true do |t| t.string "url" t.integer "project_id" diff --git a/spec/factory.rb b/spec/factory.rb index 5edef358abcce60d178fa240dd48a270a093e08a..1758b4d69d702adbb48dc177da680890629ccd72 100644 --- a/spec/factory.rb +++ b/spec/factory.rb @@ -10,8 +10,8 @@ class Factory new(name, opts).tap(&:save!) end - def new(name, opts) - factory = @factories[name] + def new(name, opts = {}) + factory= @factories[name] factory[0].new.tap do |obj| factory[1].call(obj) end.tap do |obj| diff --git a/spec/models/key_spec.rb b/spec/models/key_spec.rb index 44963e3cea77b078e37567891ceeae31da736755..b24f22cad963d43da32071200f5e8b24ed26d312 100644 --- a/spec/models/key_spec.rb +++ b/spec/models/key_spec.rb @@ -14,8 +14,40 @@ describe Key do it { should respond_to :projects } end - it { Factory.create(:key, - :user => Factory(:user)).should be_valid } + context "validation of uniqueness" do + + context "as a deploy key" do + let(:project) { Factory.create(:project, path: 'alpha', code: 'alpha') } + let(:another_project) { Factory.create(:project, path: 'beta', code: 'beta') } + + before do + deploy_key = Factory.create(:key, project: project) + end + + it "does not accept the same key twice for a project" do + key = Factory.new(:key, project: project) + key.should_not be_valid + end + + it "does accept the same key for another project" do + key = Factory.new(:key, project: another_project) + key.should be_valid + end + end + + context "as a personal key" do + let(:user) { Factory.create(:user) } + + it "accepts the key once" do + Factory.new(:key, user: user).should be_valid + end + + it "does not accepts the key twice" do + Factory.create(:key, user: user) + Factory.new(:key, user: user).should_not be_valid + end + end + end end # == Schema Information #