| |   |
| 10 | 10 | validates_uniqueness_of :name, :scope => :project_id, :case_sensitive => false |
| 11 | 11 | |
| 12 | 12 | before_save :set_as_mainline_if_first |
| 13 | | after_create :add_user_as_committer, :create_git_repository |
| 13 | after_create :add_user_as_committer, :create_new_repos_task |
| 14 | after_destroy :create_delete_repos_task |
| 14 | 15 | |
| 15 | 16 | def self.new_by_cloning(other) |
| 16 | 17 | new(:parent => other, :project => other.project) |
| … | … | |
| 44 | 44 | git_backend.create(full_repository_path) |
| 45 | 45 | end |
| 46 | 46 | |
| 47 | def delete_git_repository |
| 48 | git_backend.delete!(full_repository_path) |
| 49 | end |
| 50 | |
| 47 | 51 | def has_commits? |
| 48 | 52 | git_backend.repository_has_commits?(full_repository_path) |
| 49 | 53 | end |
| … | … | |
| 69 | 69 | committers << user |
| 70 | 70 | end |
| 71 | 71 | end |
| 72 | |
| 73 | def create_new_repos_task |
| 74 | Task.create!(:target => self, :command => "create_git_repository") |
| 75 | end |
| 76 | |
| 77 | def create_delete_repos_task |
| 78 | Task.create!(:target => self, :command => "delete_git_repository") |
| 79 | end |
| 72 | 80 | |
| 73 | 81 | protected |
| 74 | 82 | def set_as_mainline_if_first |
| toggle raw diff |
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -10,7 +10,8 @@ class Repository < ActiveRecord::Base
validates_uniqueness_of :name, :scope => :project_id, :case_sensitive => false
before_save :set_as_mainline_if_first
- after_create :add_user_as_committer, :create_git_repository
+ after_create :add_user_as_committer, :create_new_repos_task
+ after_destroy :create_delete_repos_task
def self.new_by_cloning(other)
new(:parent => other, :project => other.project)
@@ -43,6 +44,10 @@ class Repository < ActiveRecord::Base
git_backend.create(full_repository_path)
end
+ def delete_git_repository
+ git_backend.delete!(full_repository_path)
+ end
+
def has_commits?
git_backend.repository_has_commits?(full_repository_path)
end
@@ -64,6 +69,14 @@ class Repository < ActiveRecord::Base
committers << user
end
end
+
+ def create_new_repos_task
+ Task.create!(:target => self, :command => "create_git_repository")
+ end
+
+ def create_delete_repos_task
+ Task.create!(:target => self, :command => "delete_git_repository")
+ end
protected
def set_as_mainline_if_first |
| |   |
| 6 | 6 | validates_presence_of :user_id, :key |
| 7 | 7 | validates_format_of :key, :with => SSH_KEY_FORMAT |
| 8 | 8 | |
| 9 | | before_save :lint_key! |
| 9 | before_save :lint_key! |
| 10 | after_create :create_new_task |
| 11 | # we only allow people to create/destroy keys after_update :create_update_task |
| 12 | after_destroy :create_delete_task |
| 10 | 13 | |
| 11 | 14 | def wrapped_key(cols=72) |
| 12 | 15 | key.gsub(/(.{1,#{cols}})/, "\\1\n").strip |
| … | … | |
| 20 | 20 | %Q{command="gitorious #{user.login}",no-port-forwarding,} + |
| 21 | 21 | %Q{no-X11-forwarding,no-agent-forwarding,no-pty #{key}} + |
| 22 | 22 | %Q{\n### END KEY #{self.id || "nil"} ###} |
| 23 | | end |
| 23 | end |
| 24 | |
| 25 | def add_to_authorized_keys(key_file_class=SshKeyFile) |
| 26 | key_file = key_file_class.new |
| 27 | key_file.add_key(self.to_key) |
| 28 | end |
| 29 | |
| 30 | def delete_from_authorized_keys(key_file_class=SshKeyFile) |
| 31 | key_file = key_file_class.new |
| 32 | key_file.delete_key(self.to_key) |
| 33 | end |
| 34 | |
| 35 | def create_new_task |
| 36 | Task.create!(:target => self, :command => "add_to_authorized_keys") |
| 37 | end |
| 38 | |
| 39 | def create_delete_task |
| 40 | Task.create!(:target => self, :command => "delete_from_authorized_keys") |
| 41 | end |
| 24 | 42 | |
| 25 | 43 | protected |
| 26 | 44 | def lint_key! |
| toggle raw diff |
--- a/app/models/ssh_key.rb
+++ b/app/models/ssh_key.rb
@@ -6,7 +6,10 @@ class SshKey < ActiveRecord::Base
validates_presence_of :user_id, :key
validates_format_of :key, :with => SSH_KEY_FORMAT
- before_save :lint_key!
+ before_save :lint_key!
+ after_create :create_new_task
+ # we only allow people to create/destroy keys after_update :create_update_task
+ after_destroy :create_delete_task
def wrapped_key(cols=72)
key.gsub(/(.{1,#{cols}})/, "\\1\n").strip
@@ -17,7 +20,25 @@ class SshKey < ActiveRecord::Base
%Q{command="gitorious #{user.login}",no-port-forwarding,} +
%Q{no-X11-forwarding,no-agent-forwarding,no-pty #{key}} +
%Q{\n### END KEY #{self.id || "nil"} ###}
- end
+ end
+
+ def add_to_authorized_keys(key_file_class=SshKeyFile)
+ key_file = key_file_class.new
+ key_file.add_key(self.to_key)
+ end
+
+ def delete_from_authorized_keys(key_file_class=SshKeyFile)
+ key_file = key_file_class.new
+ key_file.delete_key(self.to_key)
+ end
+
+ def create_new_task
+ Task.create!(:target => self, :command => "add_to_authorized_keys")
+ end
+
+ def create_delete_task
+ Task.create!(:target => self, :command => "delete_from_authorized_keys")
+ end
protected
def lint_key! |
| |   |
| 1 | class CreateTasks < ActiveRecord::Migration |
| 2 | def self.up |
| 3 | create_table :tasks do |t| |
| 4 | t.integer :target_id |
| 5 | t.string :target_type |
| 6 | t.string :command |
| 7 | t.boolean :performed, :default => false |
| 8 | t.datetime :performed_at |
| 9 | t.timestamps |
| 10 | end |
| 11 | add_index :tasks, :target_id |
| 12 | add_index :tasks, :target_type |
| 13 | add_index :tasks, :performed |
| 14 | end |
| 15 | |
| 16 | def self.down |
| 17 | drop_table :tasks |
| 18 | end |
| 19 | end |
| toggle raw diff |
--- /dev/null
+++ b/db/migrate/016_create_tasks.rb
@@ -0,0 +1,19 @@
+class CreateTasks < ActiveRecord::Migration
+ def self.up
+ create_table :tasks do |t|
+ t.integer :target_id
+ t.string :target_type
+ t.string :command
+ t.boolean :performed, :default => false
+ t.datetime :performed_at
+ t.timestamps
+ end
+ add_index :tasks, :target_id
+ add_index :tasks, :target_type
+ add_index :tasks, :performed
+ end
+
+ def self.down
+ drop_table :tasks
+ end
+end |
| |   |
| 9 | 9 | # |
| 10 | 10 | # It's strongly recommended to check this file into your version control system. |
| 11 | 11 | |
| 12 | | ActiveRecord::Schema.define(:version => 15) do |
| 12 | ActiveRecord::Schema.define(:version => 16) do |
| 13 | 13 | |
| 14 | 14 | create_table "committerships", :force => true do |t| |
| 15 | 15 | t.integer "user_id" |
| … | … | |
| 80 | 80 | t.string "name" |
| 81 | 81 | end |
| 82 | 82 | |
| 83 | create_table "tasks", :force => true do |t| |
| 84 | t.integer "target_id" |
| 85 | t.string "target_type" |
| 86 | t.string "command" |
| 87 | t.boolean "performed", :default => false |
| 88 | t.datetime "performed_at" |
| 89 | t.datetime "created_at" |
| 90 | t.datetime "updated_at" |
| 91 | end |
| 92 | |
| 93 | add_index "tasks", ["target_id"], :name => "index_tasks_on_target_id" |
| 94 | add_index "tasks", ["target_type"], :name => "index_tasks_on_target_type" |
| 95 | add_index "tasks", ["performed"], :name => "index_tasks_on_performed" |
| 96 | |
| 83 | 97 | create_table "users", :force => true do |t| |
| 84 | 98 | t.string "login" |
| 85 | 99 | t.string "email" |
| toggle raw diff |
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -9,7 +9,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 15) do
+ActiveRecord::Schema.define(:version => 16) do
create_table "committerships", :force => true do |t|
t.integer "user_id"
@@ -80,6 +80,20 @@ ActiveRecord::Schema.define(:version => 15) do
t.string "name"
end
+ create_table "tasks", :force => true do |t|
+ t.integer "target_id"
+ t.string "target_type"
+ t.string "command"
+ t.boolean "performed", :default => false
+ t.datetime "performed_at"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
+ add_index "tasks", ["target_id"], :name => "index_tasks_on_target_id"
+ add_index "tasks", ["target_type"], :name => "index_tasks_on_target_type"
+ add_index "tasks", ["performed"], :name => "index_tasks_on_performed"
+
create_table "users", :force => true do |t|
t.string "login"
t.string "email" |
| |   |
| 85 | 85 | @repository.create_git_repository |
| 86 | 86 | end |
| 87 | 87 | |
| 88 | | it "creates an repository after save" do |
| 89 | | @repository.should_receive(:create_git_repository).and_return(true) |
| 90 | | @repository.save |
| 88 | it "deletes a repository" do |
| 89 | @repository.git_backend.should_receive(:delete!).with(@repository.full_repository_path).and_return(true) |
| 90 | @repository.delete_git_repository |
| 91 | 91 | end |
| 92 | 92 | |
| 93 | 93 | it "knows if has commits" do |
| … | … | |
| 125 | 125 | @repository.add_committer(users(:moe)) |
| 126 | 126 | users(:moe).can_write_to?(@repository).should == true |
| 127 | 127 | end |
| 128 | |
| 129 | it "creates a Task on create and update" do |
| 130 | proc{ |
| 131 | @repository.save! |
| 132 | }.should change(Task, :count) |
| 133 | task = Task.find(:first, :conditions => ["target_id = ?", @repository.id], :order => "id desc") |
| 134 | task.command.should == "create_git_repository" |
| 135 | end |
| 136 | |
| 137 | it "creates a Task on destroy" do |
| 138 | @repository.save! |
| 139 | proc{ |
| 140 | @repository.destroy |
| 141 | }.should change(Task, :count) |
| 142 | task = Task.find(:first, :conditions => ["target_id = ?", @repository.id], :order => "id desc") |
| 143 | task.command.should == "delete_git_repository" |
| 144 | end |
| 128 | 145 | end |
| toggle raw diff |
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -85,9 +85,9 @@ describe Repository do
@repository.create_git_repository
end
- it "creates an repository after save" do
- @repository.should_receive(:create_git_repository).and_return(true)
- @repository.save
+ it "deletes a repository" do
+ @repository.git_backend.should_receive(:delete!).with(@repository.full_repository_path).and_return(true)
+ @repository.delete_git_repository
end
it "knows if has commits" do
@@ -125,4 +125,21 @@ describe Repository do
@repository.add_committer(users(:moe))
users(:moe).can_write_to?(@repository).should == true
end
+
+ it "creates a Task on create and update" do
+ proc{
+ @repository.save!
+ }.should change(Task, :count)
+ task = Task.find(:first, :conditions => ["target_id = ?", @repository.id], :order => "id desc")
+ task.command.should == "create_git_repository"
+ end
+
+ it "creates a Task on destroy" do
+ @repository.save!
+ proc{
+ @repository.destroy
+ }.should change(Task, :count)
+ task = Task.find(:first, :conditions => ["target_id = ?", @repository.id], :order => "id desc")
+ task.command.should == "delete_git_repository"
+ end
end |
| |   |
| 2 | 2 | |
| 3 | 3 | describe SshKey do |
| 4 | 4 | |
| 5 | | def create_key(opts={}) |
| 5 | def new_key(opts={}) |
| 6 | 6 | SshKey.new({ |
| 7 | 7 | :user_id => 1, |
| 8 | 8 | :key => "ssh-rsa bXljYWtkZHlpemltd21vY2NqdGJnaHN2bXFjdG9zbXplaGlpZnZ0a3VyZWFzc2dkanB4aXNxamxieGVib3l6Z3hmb2ZxZW15Y2FrZGR5aXppbXdtb2NjanRiZ2hzdm1xY3Rvc216ZWhpaWZ2dGt1cmVhc3NnZGpweGlzcWpsYnhlYm95emd4Zm9mcWU= foo@example.com", |
| … | … | |
| 10 | 10 | end |
| 11 | 11 | |
| 12 | 12 | it "should have a valid ssh key" do |
| 13 | | key = create_key |
| 13 | key = new_key |
| 14 | 14 | key.key = "" |
| 15 | 15 | key.should_not be_valid |
| 16 | 16 | key.key = "foo bar@baz" |
| … | … | |
| 28 | 28 | end |
| 29 | 29 | |
| 30 | 30 | it "should have a user to be valid" do |
| 31 | | key = create_key |
| 31 | key = new_key |
| 32 | 32 | key.user_id = nil |
| 33 | 33 | key.should_not be_valid |
| 34 | 34 | |
| … | … | |
| 38 | 38 | end |
| 39 | 39 | |
| 40 | 40 | it "strips newlines before save" do |
| 41 | | ssh = create_key(:key => "ssh-rsa bXljYWtkZHlpemltd21vY2NqdGJnaHN2bXFjdG\n9zbXplaGlpZnZ0a3VyZWFzc2dkanB4aXNxamxieGVib3l6Z3hmb2ZxZW15Y2FrZGR5aXppbXdtb2NjanRiZ2hzdm1xY3Rvc216ZWhpaWZ2dGt1cm\nVhc3NnZGpweGlzcWpsYnhlYm95emd4Zm9mcWU= foo@example.com") |
| 41 | ssh = new_key(:key => "ssh-rsa bXljYWtkZHlpemltd21vY2NqdGJnaHN2bXFjdG\n9zbXplaGlpZnZ0a3VyZWFzc2dkanB4aXNxamxieGVib3l6Z3hmb2ZxZW15Y2FrZGR5aXppbXdtb2NjanRiZ2hzdm1xY3Rvc216ZWhpaWZ2dGt1cm\nVhc3NnZGpweGlzcWpsYnhlYm95emd4Zm9mcWU= foo@example.com") |
| 42 | 42 | ssh.save |
| 43 | 43 | ssh.key.should_not include("\n") |
| 44 | 44 | end |
| 45 | 45 | |
| 46 | 46 | it "wraps the key at 72 for display" do |
| 47 | | ssh = create_key |
| 47 | ssh = new_key |
| 48 | 48 | ssh.wrapped_key.should include("\n") |
| 49 | 49 | end |
| 50 | 50 | |
| 51 | 51 | it "returns a proper ssh key with to_key" do |
| 52 | | ssh_key = create_key |
| 52 | ssh_key = new_key |
| 53 | 53 | ssh_key.save! |
| 54 | 54 | exp_key = %Q{### START KEY #{ssh_key.id} ###\n} + |
| 55 | 55 | %Q{command="gitorious #{users(:johan).login}",no-port-forwarding,} + |
| … | … | |
| 57 | 57 | %Q{\n### END KEY #{ssh_key.id} ###} |
| 58 | 58 | ssh_key.to_key.should == exp_key |
| 59 | 59 | end |
| 60 | |
| 61 | it "adds itself to the authorized keys file" do |
| 62 | ssh_key_file_mock = mock("SshKeyFile mock") |
| 63 | ssh_key = new_key |
| 64 | ssh_key_file_mock.should_receive(:new).and_return(ssh_key_file_mock) |
| 65 | ssh_key_file_mock.should_receive(:add_key).with(ssh_key.to_key).and_return(true) |
| 66 | ssh_key.add_to_authorized_keys(ssh_key_file_mock) |
| 67 | end |
| 68 | |
| 69 | it "removes itself to the authorized keys file" do |
| 70 | ssh_key_file_mock = mock("SshKeyFile mock") |
| 71 | ssh_key = new_key |
| 72 | ssh_key_file_mock.should_receive(:new).and_return(ssh_key_file_mock) |
| 73 | ssh_key_file_mock.should_receive(:delete_key).with(ssh_key.to_key).and_return(true) |
| 74 | ssh_key.delete_from_authorized_keys(ssh_key_file_mock) |
| 75 | end |
| 76 | |
| 77 | it "creates a Task on create and update" do |
| 78 | ssh_key = new_key |
| 79 | proc{ |
| 80 | ssh_key.save! |
| 81 | }.should change(Task, :count) |
| 82 | task = Task.find(:first, :conditions => ["target_id = ?", ssh_key.id], :order => "id desc") |
| 83 | task.command.should == "add_to_authorized_keys" |
| 84 | end |
| 85 | |
| 86 | it "creates a Task on destroy" do |
| 87 | ssh_key = new_key |
| 88 | ssh_key.save! |
| 89 | proc{ |
| 90 | ssh_key.destroy |
| 91 | }.should change(Task, :count) |
| 92 | task = Task.find(:first, :conditions => ["target_id = ?", ssh_key.id], :order => "id desc") |
| 93 | task.command.should == "delete_from_authorized_keys" |
| 94 | end |
| 60 | 95 | end |
| toggle raw diff |
--- a/spec/models/ssh_key_spec.rb
+++ b/spec/models/ssh_key_spec.rb
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../spec_helper'
describe SshKey do
- def create_key(opts={})
+ def new_key(opts={})
SshKey.new({
:user_id => 1,
:key => "ssh-rsa bXljYWtkZHlpemltd21vY2NqdGJnaHN2bXFjdG9zbXplaGlpZnZ0a3VyZWFzc2dkanB4aXNxamxieGVib3l6Z3hmb2ZxZW15Y2FrZGR5aXppbXdtb2NjanRiZ2hzdm1xY3Rvc216ZWhpaWZ2dGt1cmVhc3NnZGpweGlzcWpsYnhlYm95emd4Zm9mcWU= foo@example.com",
@@ -10,7 +10,7 @@ describe SshKey do
end
it "should have a valid ssh key" do
- key = create_key
+ key = new_key
key.key = ""
key.should_not be_valid
key.key = "foo bar@baz"
@@ -28,7 +28,7 @@ describe SshKey do
end
it "should have a user to be valid" do
- key = create_key
+ key = new_key
key.user_id = nil
key.should_not be_valid
@@ -38,18 +38,18 @@ describe SshKey do
end
it "strips newlines before save" do
- ssh = create_key(:key => "ssh-rsa bXljYWtkZHlpemltd21vY2NqdGJnaHN2bXFjdG\n9zbXplaGlpZnZ0a3VyZWFzc2dkanB4aXNxamxieGVib3l6Z3hmb2ZxZW15Y2FrZGR5aXppbXdtb2NjanRiZ2hzdm1xY3Rvc216ZWhpaWZ2dGt1cm\nVhc3NnZGpweGlzcWpsYnhlYm95emd4Zm9mcWU= foo@example.com")
+ ssh = new_key(:key => "ssh-rsa bXljYWtkZHlpemltd21vY2NqdGJnaHN2bXFjdG\n9zbXplaGlpZnZ0a3VyZWFzc2dkanB4aXNxamxieGVib3l6Z3hmb2ZxZW15Y2FrZGR5aXppbXdtb2NjanRiZ2hzdm1xY3Rvc216ZWhpaWZ2dGt1cm\nVhc3NnZGpweGlzcWpsYnhlYm95emd4Zm9mcWU= foo@example.com")
ssh.save
ssh.key.should_not include("\n")
end
it "wraps the key at 72 for display" do
- ssh = create_key
+ ssh = new_key
ssh.wrapped_key.should include("\n")
end
it "returns a proper ssh key with to_key" do
- ssh_key = create_key
+ ssh_key = new_key
ssh_key.save!
exp_key = %Q{### START KEY #{ssh_key.id} ###\n} +
%Q{command="gitorious #{users(:johan).login}",no-port-forwarding,} +
@@ -57,4 +57,39 @@ describe SshKey do
%Q{\n### END KEY #{ssh_key.id} ###}
ssh_key.to_key.should == exp_key
end
+
+ it "adds itself to the authorized keys file" do
+ ssh_key_file_mock = mock("SshKeyFile mock")
+ ssh_key = new_key
+ ssh_key_file_mock.should_receive(:new).and_return(ssh_key_file_mock)
+ ssh_key_file_mock.should_receive(:add_key).with(ssh_key.to_key).and_return(true)
+ ssh_key.add_to_authorized_keys(ssh_key_file_mock)
+ end
+
+ it "removes itself to the authorized keys file" do
+ ssh_key_file_mock = mock("SshKeyFile mock")
+ ssh_key = new_key
+ ssh_key_file_mock.should_receive(:new).and_return(ssh_key_file_mock)
+ ssh_key_file_mock.should_receive(:delete_key).with(ssh_key.to_key).and_return(true)
+ ssh_key.delete_from_authorized_keys(ssh_key_file_mock)
+ end
+
+ it "creates a Task on create and update" do
+ ssh_key = new_key
+ proc{
+ ssh_key.save!
+ }.should change(Task, :count)
+ task = Task.find(:first, :conditions => ["target_id = ?", ssh_key.id], :order => "id desc")
+ task.command.should == "add_to_authorized_keys"
+ end
+
+ it "creates a Task on destroy" do
+ ssh_key = new_key
+ ssh_key.save!
+ proc{
+ ssh_key.destroy
+ }.should change(Task, :count)
+ task = Task.find(:first, :conditions => ["target_id = ?", ssh_key.id], :order => "id desc")
+ task.command.should == "delete_from_authorized_keys"
+ end
end |
| |   |
| 1 | require File.dirname(__FILE__) + '/../spec_helper' |
| 2 | |
| 3 | describe Task do |
| 4 | before(:each) do |
| 5 | @task = tasks(:create_repo) |
| 6 | end |
| 7 | |
| 8 | it "has_valid_associations" do |
| 9 | @task.should have_valid_associations |
| 10 | end |
| 11 | |
| 12 | it "performs a task" do |
| 13 | @task.target.should_receive(@task.command).and_return(true) |
| 14 | @task.perform! |
| 15 | @task.reload |
| 16 | @task.performed?.should == true |
| 17 | @task.performed_at.should_not == nil |
| 18 | end |
| 19 | |
| 20 | it "finds tasks that needs performin'" do |
| 21 | @task.update_attributes(:performed => true) |
| 22 | Task.find_all_to_perform.should == [tasks(:add_key)] |
| 23 | end |
| 24 | end |
| toggle raw diff |
--- /dev/null
+++ b/spec/models/task_spec.rb
@@ -0,0 +1,24 @@
+require File.dirname(__FILE__) + '/../spec_helper'
+
+describe Task do
+ before(:each) do
+ @task = tasks(:create_repo)
+ end
+
+ it "has_valid_associations" do
+ @task.should have_valid_associations
+ end
+
+ it "performs a task" do
+ @task.target.should_receive(@task.command).and_return(true)
+ @task.perform!
+ @task.reload
+ @task.performed?.should == true
+ @task.performed_at.should_not == nil
+ end
+
+ it "finds tasks that needs performin'" do
+ @task.update_attributes(:performed => true)
+ Task.find_all_to_perform.should == [tasks(:add_key)]
+ end
+end |