gritano 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +20 -0
- data/Gemfile.lock +72 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +51 -0
- data/Rakefile +62 -0
- data/TODO +0 -0
- data/VERSION +1 -0
- data/bin/gritano +74 -0
- data/bin/gritano-check +17 -0
- data/db/database.yml +2 -0
- data/db/migrate/001_create_users.rb +8 -0
- data/db/migrate/002_create_repositories.rb +9 -0
- data/db/migrate/003_create_permissions.rb +10 -0
- data/db/migrate/004_create_keys.rb +11 -0
- data/features/command.feature +12 -0
- data/features/console.feature +59 -0
- data/features/data/keys/full_authorized_keys +2 -0
- data/features/data/keys/igorbonadio.pub +1 -0
- data/features/data/keys/igorbonadio_authorized_keys +1 -0
- data/features/data/keys/jessicaeto.pub +1 -0
- data/features/data/keys/jessicaeto_authorized_keys +1 -0
- data/features/keys.feature +31 -0
- data/features/polices.feature +55 -0
- data/features/step_definitions/command_step.rb +8 -0
- data/features/step_definitions/console_step.rb +14 -0
- data/features/step_definitions/keys_steps.rb +23 -0
- data/features/step_definitions/polices_steps.rb +54 -0
- data/features/support/database_cleaner.rb +15 -0
- data/features/support/env.rb +25 -0
- data/lib/gritano.rb +5 -0
- data/lib/gritano/command.rb +16 -0
- data/lib/gritano/console.rb +119 -0
- data/lib/gritano/models.rb +7 -0
- data/lib/gritano/models/key.rb +21 -0
- data/lib/gritano/models/permission.rb +39 -0
- data/lib/gritano/models/repository.rb +24 -0
- data/lib/gritano/models/user.rb +41 -0
- data/spec/command_spec.rb +17 -0
- data/spec/console_spec.rb +51 -0
- data/spec/model_key_spec.rb +18 -0
- data/spec/model_repository_spec.rb +23 -0
- data/spec/model_user_spec.rb +84 -0
- data/spec/spec_helper.rb +32 -0
- data/tmp/.gitignore +4 -0
- metadata +260 -0
| @@ -0,0 +1,2 @@ | |
| 1 | 
            +
            command="gritano-check igorbonadio" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDFW6Du1iXTyo44g+7R4DNgm4P1fQIiW/iGRFwHJTV1jaPX74VwNq7tC1kBSdPS4+Q9f24wJC1MhWzLxB40BFdqn519JhhV+/1IWZdY/UJ0D5KiUw38U7QPzMM2uA0l0JeB+FwZAl/Oiu/ty3Fq0JsuqsolehIbRRLeiJiwrn1XC5LdhA81b2WBzM8SSFgAaXPimuLBXYJyYrcTR5SXczZvgkWojQEvk7wCavvDzFpy/DtXUFv0ZwUJILhN23cW3mg1IsGMXg7hOQfp67J6cX212YYXhDe+5sI3UpFWKCHcyxv3EdL8rQ/3DLSELkTwWHPRqDhn1wnPmfJlj8ZfbpyX git2@debian-ror
         | 
| 2 | 
            +
            command="gritano-check jessicaeto" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDZ4WqIu8XwnHwBz220/1Kbgi1IR7aanq8hW1dB0LD2dmCSyojBvduoht4p7+3k2R6A5y2DZvTetzEios9OFUnCC+4U8g2GTc+zGM0W+msCb6yWnpfYaIwHVuFtsid7lyWOCEYLi2WbNZxfAx0PbwIcHMoYWc9sil3R/YwLGorvQDGH0rFcf6BOMzVMDRD0yPvuN3xgAtBOxrSRl0U4dH+3fAQ9oKLePmouzLrrKvRmyVwl/rHNod8ae5VmmAalC+wXIsiQAI92Hwew757HzhY45wWtjOsdBBf45Psv7BkB1OqGxMfwysO5iwhY3HPTJs70K22K2DARpejFq8Bd8PyV git2@debian-ror
         | 
| @@ -0,0 +1 @@ | |
| 1 | 
            +
            ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDFW6Du1iXTyo44g+7R4DNgm4P1fQIiW/iGRFwHJTV1jaPX74VwNq7tC1kBSdPS4+Q9f24wJC1MhWzLxB40BFdqn519JhhV+/1IWZdY/UJ0D5KiUw38U7QPzMM2uA0l0JeB+FwZAl/Oiu/ty3Fq0JsuqsolehIbRRLeiJiwrn1XC5LdhA81b2WBzM8SSFgAaXPimuLBXYJyYrcTR5SXczZvgkWojQEvk7wCavvDzFpy/DtXUFv0ZwUJILhN23cW3mg1IsGMXg7hOQfp67J6cX212YYXhDe+5sI3UpFWKCHcyxv3EdL8rQ/3DLSELkTwWHPRqDhn1wnPmfJlj8ZfbpyX git2@debian-ror
         | 
| @@ -0,0 +1 @@ | |
| 1 | 
            +
            command="gritano-check igorbonadio" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDFW6Du1iXTyo44g+7R4DNgm4P1fQIiW/iGRFwHJTV1jaPX74VwNq7tC1kBSdPS4+Q9f24wJC1MhWzLxB40BFdqn519JhhV+/1IWZdY/UJ0D5KiUw38U7QPzMM2uA0l0JeB+FwZAl/Oiu/ty3Fq0JsuqsolehIbRRLeiJiwrn1XC5LdhA81b2WBzM8SSFgAaXPimuLBXYJyYrcTR5SXczZvgkWojQEvk7wCavvDzFpy/DtXUFv0ZwUJILhN23cW3mg1IsGMXg7hOQfp67J6cX212YYXhDe+5sI3UpFWKCHcyxv3EdL8rQ/3DLSELkTwWHPRqDhn1wnPmfJlj8ZfbpyX git2@debian-ror
         | 
| @@ -0,0 +1 @@ | |
| 1 | 
            +
            ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDZ4WqIu8XwnHwBz220/1Kbgi1IR7aanq8hW1dB0LD2dmCSyojBvduoht4p7+3k2R6A5y2DZvTetzEios9OFUnCC+4U8g2GTc+zGM0W+msCb6yWnpfYaIwHVuFtsid7lyWOCEYLi2WbNZxfAx0PbwIcHMoYWc9sil3R/YwLGorvQDGH0rFcf6BOMzVMDRD0yPvuN3xgAtBOxrSRl0U4dH+3fAQ9oKLePmouzLrrKvRmyVwl/rHNod8ae5VmmAalC+wXIsiQAI92Hwew757HzhY45wWtjOsdBBf45Psv7BkB1OqGxMfwysO5iwhY3HPTJs70K22K2DARpejFq8Bd8PyV git2@debian-ror
         | 
| @@ -0,0 +1 @@ | |
| 1 | 
            +
            command="gritano-check jessicaeto" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDZ4WqIu8XwnHwBz220/1Kbgi1IR7aanq8hW1dB0LD2dmCSyojBvduoht4p7+3k2R6A5y2DZvTetzEios9OFUnCC+4U8g2GTc+zGM0W+msCb6yWnpfYaIwHVuFtsid7lyWOCEYLi2WbNZxfAx0PbwIcHMoYWc9sil3R/YwLGorvQDGH0rFcf6BOMzVMDRD0yPvuN3xgAtBOxrSRl0U4dH+3fAQ9oKLePmouzLrrKvRmyVwl/rHNod8ae5VmmAalC+wXIsiQAI92Hwew757HzhY45wWtjOsdBBf45Psv7BkB1OqGxMfwysO5iwhY3HPTJs70K22K2DARpejFq8Bd8PyV git2@debian-ror
         | 
| @@ -0,0 +1,31 @@ | |
| 1 | 
            +
            Feature: Keys
         | 
| 2 | 
            +
              In Order to restrict access to repositories
         | 
| 3 | 
            +
              As Gritano
         | 
| 4 | 
            +
              I want to manage user's keys
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              Background:
         | 
| 7 | 
            +
                Given the following users exist:
         | 
| 8 | 
            +
                  | login       |
         | 
| 9 | 
            +
                  | igorbonadio |
         | 
| 10 | 
            +
                  | jessicaeto  |
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              Scenario Outline: Add user key
         | 
| 13 | 
            +
                Given I add "<key>" key to "<user>"
         | 
| 14 | 
            +
                When I generate the authorized_keys
         | 
| 15 | 
            +
                Then I should see "<authorized_keys>" authorized_keys
         | 
| 16 | 
            +
                Examples:
         | 
| 17 | 
            +
                  | user | key | authorized_keys |
         | 
| 18 | 
            +
                  | igorbonadio | igorbonadio.pub | igorbonadio_authorized_keys |
         | 
| 19 | 
            +
                  | jessicaeto  | jessicaeto.pub  | jessicaeto_authorized_keys  |
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              Scenario: Generate autorized_keys
         | 
| 22 | 
            +
                Given I add "igorbonadio.pub" key to "igorbonadio"
         | 
| 23 | 
            +
                And I add "jessicaeto.pub" key to "jessicaeto"
         | 
| 24 | 
            +
                When I generate the authorized_keys
         | 
| 25 | 
            +
                Then I should see "full_authorized_keys" authorized_keys
         | 
| 26 | 
            +
                
         | 
| 27 | 
            +
              Scenario: Duplicated keys
         | 
| 28 | 
            +
                Given I add "igorbonadio.pub" key to "igorbonadio"
         | 
| 29 | 
            +
                When I add "igorbonadio.pub" key to "igorbonadio"
         | 
| 30 | 
            +
                Then I should see that "igorbonadio" has only one key
         | 
| 31 | 
            +
             | 
| @@ -0,0 +1,55 @@ | |
| 1 | 
            +
            Feature: Policies
         | 
| 2 | 
            +
            	In order to restrict access to repositories
         | 
| 3 | 
            +
            	As Gritano
         | 
| 4 | 
            +
            	I want to create policies
         | 
| 5 | 
            +
            	
         | 
| 6 | 
            +
            	Background:
         | 
| 7 | 
            +
            		Given the following users exist:
         | 
| 8 | 
            +
            		  | login       |
         | 
| 9 | 
            +
            		  | igorbonadio |
         | 
| 10 | 
            +
            		  | jessicaeto  |
         | 
| 11 | 
            +
            		  
         | 
| 12 | 
            +
            	  And the following repositories exist:
         | 
| 13 | 
            +
            	    | name            |
         | 
| 14 | 
            +
            	    | tmp/gritano.git |
         | 
| 15 | 
            +
            	    | tmp/jeka.git    |
         | 
| 16 | 
            +
            	    
         | 
| 17 | 
            +
            	  And the following permissions exist:
         | 
| 18 | 
            +
            	     | user        | repo            | access |
         | 
| 19 | 
            +
            	     | igorbonadio | tmp/gritano.git | read   |
         | 
| 20 | 
            +
            	     | igorbonadio | tmp/gritano.git | write  |
         | 
| 21 | 
            +
            	     | igorbonadio | tmp/jeka.git    | read   |
         | 
| 22 | 
            +
            	     | jessicaeto  | tmp/jeka.git    | read   |
         | 
| 23 | 
            +
            	     | jessicaeto  | tmp/jeka.git    | write  |
         | 
| 24 | 
            +
            	     
         | 
| 25 | 
            +
            	Scenario Outline: Create a new user
         | 
| 26 | 
            +
            		Given I create a new user called "<user>"
         | 
| 27 | 
            +
            		When I check if "<user>" has <access> access to "<repo>"
         | 
| 28 | 
            +
            		Then I should see that the access is <result>
         | 
| 29 | 
            +
            		Examples:
         | 
| 30 | 
            +
            		  | user       | access | repo            | result |
         | 
| 31 | 
            +
            		  | arybonadio | read   | tmp/gritano.git | denied |
         | 
| 32 | 
            +
            		  | arybonadio | write  | tmp/gritano.git | denied |
         | 
| 33 | 
            +
            		
         | 
| 34 | 
            +
            	Scenario Outline: Create a new repository
         | 
| 35 | 
            +
            		Given I create a new repository called "<repo>" to "<user>"
         | 
| 36 | 
            +
            		Then I should see that only "<user>" has access to "<repo>"
         | 
| 37 | 
            +
            		Examples:
         | 
| 38 | 
            +
            		  | user        | repo           |
         | 
| 39 | 
            +
            		  | igorbonadio | tmp/p-lang.git |
         | 
| 40 | 
            +
            		  | jessicaeto  | tmp/pabel.git  |
         | 
| 41 | 
            +
            		
         | 
| 42 | 
            +
            	Scenario Outline: Edit access permission
         | 
| 43 | 
            +
            		Given I <op> "<user>" <permission> access to "<repo>"
         | 
| 44 | 
            +
            		When I check if "<user>" has <access> access to "<repo>"
         | 
| 45 | 
            +
            		Then I should see that the access is <result>
         | 
| 46 | 
            +
            		Examples:
         | 
| 47 | 
            +
            		  | op     | user        | permission | repo         | access | result  |
         | 
| 48 | 
            +
            		  | add    | igorbonadio | read       | tmp/jeka.git | read   | allowed |
         | 
| 49 | 
            +
            		  | add    | igorbonadio | read       | tmp/jeka.git | write  | denied  |
         | 
| 50 | 
            +
            		  | add    | igorbonadio | write      | tmp/jeka.git | read   | allowed |
         | 
| 51 | 
            +
            		  | add    | igorbonadio | write      | tmp/jeka.git | write  | allowed |
         | 
| 52 | 
            +
            		  | remove | jessicaeto  | read       | tmp/jeka.git | read   | denied  |
         | 
| 53 | 
            +
            		  | remove | jessicaeto  | read       | tmp/jeka.git | write  | allowed |
         | 
| 54 | 
            +
            		  | remove | jessicaeto  | write      | tmp/jeka.git | read   | allowed |
         | 
| 55 | 
            +
            		  | remove | jessicaeto  | write      | tmp/jeka.git | write  | denied  |
         | 
| @@ -0,0 +1,8 @@ | |
| 1 | 
            +
            When /^I receive a "(.*?)" command$/ do |cmd|
         | 
| 2 | 
            +
              @access, @git_command, @repo = Gritano::Command.eval(cmd)
         | 
| 3 | 
            +
            end
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            Then /^I should see that it is a "(.*?)" access to "(.*?)"$/ do |access, repo|
         | 
| 6 | 
            +
              @access.to_s.should be == access
         | 
| 7 | 
            +
              @repo.to_s.should be == repo
         | 
| 8 | 
            +
            end
         | 
| @@ -0,0 +1,14 @@ | |
| 1 | 
            +
            Given /^I start the gritano console$/ do
         | 
| 2 | 
            +
              @console = Gritano::Console.new
         | 
| 3 | 
            +
              @console.ssh_path = 'tmp'
         | 
| 4 | 
            +
            end
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            When /^I execute "(.*?)"$/ do |command|
         | 
| 7 | 
            +
              @output = @console.execute(command.split(' '))
         | 
| 8 | 
            +
            end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            Then /^I should see a (success|error) message$/ do |ret|
         | 
| 11 | 
            +
              expected_output = true if ret == 'success'
         | 
| 12 | 
            +
              expected_output = false if ret == 'error'
         | 
| 13 | 
            +
              @output.should be == expected_output
         | 
| 14 | 
            +
            end
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            Given /^the following keys exist:$/ do |table|
         | 
| 2 | 
            +
              table.hashes.each do |key|
         | 
| 3 | 
            +
                Gritano::User.find_by_login(key['login']).keys.create(name: key["key"], key: "key")
         | 
| 4 | 
            +
              end
         | 
| 5 | 
            +
            end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            Given /^I add "(.*?)" key to "(.*?)"$/ do |key, login|
         | 
| 8 | 
            +
              ssh_key = File.open(File.join("features/data/keys/", key)).readlines.join
         | 
| 9 | 
            +
              Gritano::User.find_by_login(login).keys.create({name: key, key: ssh_key})
         | 
| 10 | 
            +
            end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            When /^I generate the authorized_keys$/ do
         | 
| 13 | 
            +
              @authorized_keys = Gritano::Key.authorized_keys
         | 
| 14 | 
            +
            end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            Then /^I should see "(.*?)" authorized_keys$/ do |authorized_keys|
         | 
| 17 | 
            +
              expected_authorized_keys = File.open(File.join("features/data/keys/", authorized_keys)).readlines.join
         | 
| 18 | 
            +
              @authorized_keys.should be == expected_authorized_keys
         | 
| 19 | 
            +
            end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            Then /^I should see that "(.*?)" has only one key$/ do |login|
         | 
| 22 | 
            +
              Gritano::User.find_by_login(login).keys.count.should be == 1
         | 
| 23 | 
            +
            end
         | 
| @@ -0,0 +1,54 @@ | |
| 1 | 
            +
            Given /^the following users exist:$/ do |table|
         | 
| 2 | 
            +
              table.hashes.each do |user|
         | 
| 3 | 
            +
                Gritano::User.create(user)
         | 
| 4 | 
            +
              end
         | 
| 5 | 
            +
            end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            Given /^the following repositories exist:$/ do |table|
         | 
| 8 | 
            +
              table.hashes.each do |repo|
         | 
| 9 | 
            +
                Gritano::Repository.create(repo)
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
            end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            Given /^the following permissions exist:$/ do |table|
         | 
| 14 | 
            +
              table.hashes.each do |permission|
         | 
| 15 | 
            +
                Gritano::User.find_by_login(permission['user'])
         | 
| 16 | 
            +
                  .add_access(Gritano::Repository.find_by_name(permission['repo']), permission['access'].to_sym)
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
            end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            Given /^I create a new user called "(.*?)"$/ do |login|
         | 
| 21 | 
            +
              @user = Gritano::User.create(login: login)
         | 
| 22 | 
            +
            end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            When /^I check if "(.*?)" has (read|write) access to "(.*?)"$/ do |login, access, repo|
         | 
| 25 | 
            +
              @access_result = @user.check_access(Gritano::Repository.find_by_name(repo), access.to_sym)
         | 
| 26 | 
            +
            end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            Then /^I should see that the access is (denied|allowed)$/ do |result|
         | 
| 29 | 
            +
              @expected_result = false if result == 'denied'
         | 
| 30 | 
            +
              @expected_result = true if result == 'allowed'
         | 
| 31 | 
            +
              @access_result.should be == @expected_result
         | 
| 32 | 
            +
            end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            Given /^I create a new repository called "(.*?)" to "(.*?)"$/ do |repo, login|
         | 
| 35 | 
            +
              Gritano::User.find_by_login(login).create_repository(name: repo)
         | 
| 36 | 
            +
            end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            Then /^I should see that only "(.*?)" has access to "(.*?)"$/ do |login, repo|
         | 
| 39 | 
            +
              repository = Gritano::Repository.find_by_name(repo)
         | 
| 40 | 
            +
              user = Gritano::User.find_by_login(login)
         | 
| 41 | 
            +
              user.check_access(repository, :read).should be_true
         | 
| 42 | 
            +
              user.check_access(repository, :write).should be_true
         | 
| 43 | 
            +
              Gritano::User.all.each do |u|
         | 
| 44 | 
            +
                unless u.login == user.login
         | 
| 45 | 
            +
                  u.check_access(repository, :read).should be_false
         | 
| 46 | 
            +
                  u.check_access(repository, :write).should be_false
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
            end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
            Given /^I (add|remove) "(.*?)" (read|write) access to "(.*?)"$/ do |op, user, permission, repo|
         | 
| 52 | 
            +
              @user = Gritano::User.find_by_login(user)
         | 
| 53 | 
            +
              @user.send("#{op}_access", Gritano::Repository.find_by_name(repo), permission.to_sym)
         | 
| 54 | 
            +
            end
         | 
| @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            begin
         | 
| 2 | 
            +
              require 'database_cleaner'
         | 
| 3 | 
            +
              require 'database_cleaner/cucumber'  
         | 
| 4 | 
            +
              DatabaseCleaner.strategy = :truncation
         | 
| 5 | 
            +
            rescue NameError
         | 
| 6 | 
            +
              raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it."
         | 
| 7 | 
            +
            end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            Before do
         | 
| 10 | 
            +
              DatabaseCleaner.start
         | 
| 11 | 
            +
            end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            After do |scenario|
         | 
| 14 | 
            +
              DatabaseCleaner.clean
         | 
| 15 | 
            +
            end
         | 
| @@ -0,0 +1,25 @@ | |
| 1 | 
            +
            require 'simplecov'
         | 
| 2 | 
            +
            SimpleCov.start do
         | 
| 3 | 
            +
              add_filter "/features/"
         | 
| 4 | 
            +
              add_filter "/spec/"
         | 
| 5 | 
            +
            end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            require 'bundler'
         | 
| 8 | 
            +
            begin
         | 
| 9 | 
            +
              Bundler.setup(:default, :development)
         | 
| 10 | 
            +
            rescue Bundler::BundlerError => e
         | 
| 11 | 
            +
              $stderr.puts e.message
         | 
| 12 | 
            +
              $stderr.puts "Run `bundle install` to install missing gems"
         | 
| 13 | 
            +
              exit e.status_code
         | 
| 14 | 
            +
            end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
         | 
| 17 | 
            +
            require 'gritano'
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            require 'rspec/expectations'
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            require 'active_record'
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            Before do
         | 
| 24 | 
            +
              ActiveRecord::Base.establish_connection(YAML::load(File.open('db/database.yml')))
         | 
| 25 | 
            +
            end
         | 
    
        data/lib/gritano.rb
    ADDED
    
    
| @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            module Gritano
         | 
| 2 | 
            +
              class Command
         | 
| 3 | 
            +
                def self.eval(cmd)
         | 
| 4 | 
            +
                  case cmd
         | 
| 5 | 
            +
                    when /^git-receive-pack/ then
         | 
| 6 | 
            +
                      return :write, "git-receive-pack", self.repo(cmd)
         | 
| 7 | 
            +
                    when /^git-upload-pack/ then
         | 
| 8 | 
            +
                      return :read, "git-upload-pack", self.repo(cmd)
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
                
         | 
| 12 | 
            +
                def self.repo(cmd)
         | 
| 13 | 
            +
                  cmd.gsub(/^git-receive-pack/, '').gsub(/^git-upload-pack/, '').gsub("'", '').strip
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
            end
         | 
| @@ -0,0 +1,119 @@ | |
| 1 | 
            +
            module Gritano
         | 
| 2 | 
            +
              class Console
         | 
| 3 | 
            +
                
         | 
| 4 | 
            +
                attr_accessor :repo_path
         | 
| 5 | 
            +
                attr_accessor :ssh_path
         | 
| 6 | 
            +
                
         | 
| 7 | 
            +
                def initialize
         | 
| 8 | 
            +
                  @repo_path = nil
         | 
| 9 | 
            +
                  @ssh_path = nil
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
                
         | 
| 12 | 
            +
                def execute(argv)
         | 
| 13 | 
            +
                  send(argv[0..1].join('_').gsub('+', 'add_').gsub('-', 'remove_'), argv[2..-1])
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
                
         | 
| 16 | 
            +
                def user_add(argv)
         | 
| 17 | 
            +
                  login, = argv
         | 
| 18 | 
            +
                  user = User.new(login: login)
         | 
| 19 | 
            +
                  return true if user.save
         | 
| 20 | 
            +
                  return false
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
                
         | 
| 23 | 
            +
                def user_rm(argv)
         | 
| 24 | 
            +
                  login, = argv
         | 
| 25 | 
            +
                  user = User.find_by_login(login)
         | 
| 26 | 
            +
                  if user
         | 
| 27 | 
            +
                    if user.destroy
         | 
| 28 | 
            +
                      return true 
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
                  return false
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
                
         | 
| 34 | 
            +
                def repo_add(argv)
         | 
| 35 | 
            +
                  name, = argv
         | 
| 36 | 
            +
                  repo = Repository.new(name: name, path: @repo_path)
         | 
| 37 | 
            +
                  return true if repo.save
         | 
| 38 | 
            +
                  return false
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
                
         | 
| 41 | 
            +
                def repo_rm(argv)
         | 
| 42 | 
            +
                  name, = argv
         | 
| 43 | 
            +
                  repo = Repository.find_by_name(name)
         | 
| 44 | 
            +
                  if repo
         | 
| 45 | 
            +
                    if repo.destroy
         | 
| 46 | 
            +
                      return true
         | 
| 47 | 
            +
                    end
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
                  return false
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
                
         | 
| 52 | 
            +
                def repo_add_read(argv)
         | 
| 53 | 
            +
                  repo_name, login = argv
         | 
| 54 | 
            +
                  user = User.find_by_login(login)
         | 
| 55 | 
            +
                  repo = Repository.find_by_name(repo_name)
         | 
| 56 | 
            +
                  if repo and user
         | 
| 57 | 
            +
                    return user.add_access(repo, :read)
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
                  return false
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
                
         | 
| 62 | 
            +
                def repo_add_write(argv)
         | 
| 63 | 
            +
                  repo_name, login = argv
         | 
| 64 | 
            +
                  user = User.find_by_login(login)
         | 
| 65 | 
            +
                  repo = Repository.find_by_name(repo_name)
         | 
| 66 | 
            +
                  if repo and user
         | 
| 67 | 
            +
                    return user.add_access(repo, :write)
         | 
| 68 | 
            +
                  end
         | 
| 69 | 
            +
                  return false
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
                
         | 
| 72 | 
            +
                def repo_remove_read(argv)
         | 
| 73 | 
            +
                  repo_name, login = argv
         | 
| 74 | 
            +
                  user = User.find_by_login(login)
         | 
| 75 | 
            +
                  repo = Repository.find_by_name(repo_name)
         | 
| 76 | 
            +
                  if repo and user
         | 
| 77 | 
            +
                    return user.remove_access(repo, :read)
         | 
| 78 | 
            +
                  end
         | 
| 79 | 
            +
                  return false
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
                
         | 
| 82 | 
            +
                def repo_remove_write(argv)
         | 
| 83 | 
            +
                  repo_name, login = argv
         | 
| 84 | 
            +
                  user = User.find_by_login(login)
         | 
| 85 | 
            +
                  repo = Repository.find_by_name(repo_name)
         | 
| 86 | 
            +
                  if repo and user
         | 
| 87 | 
            +
                    return user.remove_access(repo, :write)
         | 
| 88 | 
            +
                  end
         | 
| 89 | 
            +
                  return false
         | 
| 90 | 
            +
                end
         | 
| 91 | 
            +
                
         | 
| 92 | 
            +
                def user_add_key(argv)
         | 
| 93 | 
            +
                  login, key_name, key_file = argv
         | 
| 94 | 
            +
                  user = User.find_by_login(login)
         | 
| 95 | 
            +
                  if File.exist?(key_file)
         | 
| 96 | 
            +
                    if user
         | 
| 97 | 
            +
                      key = user.keys.create(name: key_name, key: File.open(key_file).readlines.join)
         | 
| 98 | 
            +
                      if key.valid?
         | 
| 99 | 
            +
                        File.open(File.join(@ssh_path, 'authorized_keys'), 'w').write(Key.authorized_keys)
         | 
| 100 | 
            +
                        return true
         | 
| 101 | 
            +
                      end
         | 
| 102 | 
            +
                    end
         | 
| 103 | 
            +
                  end
         | 
| 104 | 
            +
                  return false
         | 
| 105 | 
            +
                end
         | 
| 106 | 
            +
                
         | 
| 107 | 
            +
                def user_remove_key(argv)
         | 
| 108 | 
            +
                  login, key_name = argv
         | 
| 109 | 
            +
                  key = Key.where(name: key_name).includes(:user).where("users.login" => login).limit(1)[0]
         | 
| 110 | 
            +
                  if key
         | 
| 111 | 
            +
                    if key.destroy
         | 
| 112 | 
            +
                      File.open(File.join(@ssh_path, 'authorized_keys'), 'w').write(Key.authorized_keys)
         | 
| 113 | 
            +
                      return true
         | 
| 114 | 
            +
                    end
         | 
| 115 | 
            +
                  end
         | 
| 116 | 
            +
                  return false
         | 
| 117 | 
            +
                end
         | 
| 118 | 
            +
              end
         | 
| 119 | 
            +
            end
         | 
| @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            require 'active_record'
         | 
| 2 | 
            +
            require 'grit'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require File.join(ROOT_PATH, 'gritano/models/user')
         | 
| 5 | 
            +
            require File.join(ROOT_PATH, 'gritano/models/repository')
         | 
| 6 | 
            +
            require File.join(ROOT_PATH, 'gritano/models/permission')
         | 
| 7 | 
            +
            require File.join(ROOT_PATH, 'gritano/models/key')
         | 
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            module Gritano
         | 
| 2 | 
            +
              class Key < ActiveRecord::Base
         | 
| 3 | 
            +
                validates :name, :key, presence: true
         | 
| 4 | 
            +
                validates :name, :uniqueness => { :scope => :user_id, :message => "should happen once per user" }
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                belongs_to :user
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                def self.authorized_keys
         | 
| 9 | 
            +
                  authorized_keys = ""
         | 
| 10 | 
            +
                  keys = Key.find(:all)
         | 
| 11 | 
            +
                  keys.each do |k|
         | 
| 12 | 
            +
                    user_key = k.key
         | 
| 13 | 
            +
                    unless k.key[-1] == "\n"
         | 
| 14 | 
            +
                      user_key = user_key + "\n"
         | 
| 15 | 
            +
                    end
         | 
| 16 | 
            +
                    authorized_keys += "command=\"gritano-check #{k.user.login}\" #{user_key}"
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                  return authorized_keys
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
            end
         | 
| @@ -0,0 +1,39 @@ | |
| 1 | 
            +
            module Gritano
         | 
| 2 | 
            +
              class Permission < ActiveRecord::Base
         | 
| 3 | 
            +
                belongs_to :user
         | 
| 4 | 
            +
                belongs_to :repository
         | 
| 5 | 
            +
                
         | 
| 6 | 
            +
                READ = 1
         | 
| 7 | 
            +
                WRITE = 2
         | 
| 8 | 
            +
                
         | 
| 9 | 
            +
                def add_access(access)
         | 
| 10 | 
            +
                  if access == :read
         | 
| 11 | 
            +
                    self.access = READ | (self.access || 0)
         | 
| 12 | 
            +
                  elsif access == :write
         | 
| 13 | 
            +
                    self.access = WRITE | (self.access || 0)
         | 
| 14 | 
            +
                  else
         | 
| 15 | 
            +
                    return false
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
                  return true
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
                
         | 
| 20 | 
            +
                def remove_access(access)
         | 
| 21 | 
            +
                  if access == :read
         | 
| 22 | 
            +
                    self.access = (self.access || 0) & (~ READ)
         | 
| 23 | 
            +
                  elsif access == :write
         | 
| 24 | 
            +
                    self.access = (self.access || 0) & (~ WRITE)
         | 
| 25 | 
            +
                  else
         | 
| 26 | 
            +
                    return false
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
                  return true
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
                
         | 
| 31 | 
            +
                def is(access)
         | 
| 32 | 
            +
                  if access == :read
         | 
| 33 | 
            +
                    return (self.access & READ) == READ
         | 
| 34 | 
            +
                  elsif access == :write
         | 
| 35 | 
            +
                    return (self.access & WRITE) == WRITE
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
            end
         |