brownbeagle-gitauth 0.0.1 → 0.0.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/README.rdoc +11 -1
- data/bin/gitauth +100 -24
- data/bin/gitauth-shell +2 -32
- data/lib/gitauth/client.rb +17 -19
- data/lib/gitauth/command.rb +2 -2
- data/lib/gitauth/group.rb +86 -0
- data/lib/gitauth/repo.rb +43 -40
- data/lib/gitauth/saveable_class.rb +60 -0
- data/lib/gitauth/{users.rb → user.rb} +35 -31
- data/lib/gitauth/web_app.rb +230 -0
- data/lib/gitauth.rb +29 -5
- data/public/gitauth.css +264 -0
- data/public/gitauth.js +17 -0
- data/public/jquery.js +19 -0
- data/views/group.erb +24 -0
- data/views/index.erb +80 -0
- data/views/layout.erb +27 -0
- data/views/repo.erb +56 -0
- data/views/user.erb +51 -0
- metadata +26 -5
data/README.rdoc
CHANGED
@@ -48,9 +48,19 @@ Would initialize an admin user with the given public key.
|
|
48
48
|
Note that from now on, all gitauth keys should be run either logged in as
|
49
49
|
git (via the admin user and ssh) or by being prefixed with asgit or "sudo -H -u git"
|
50
50
|
|
51
|
+
=== Web Interface
|
52
|
+
|
53
|
+
To start the web interface, just run:
|
54
|
+
|
55
|
+
gitauth webapp
|
56
|
+
|
57
|
+
The first time you boot the web app, you will be prompted
|
58
|
+
to enter a username and a password. Please do so
|
59
|
+
and then surf to http://your-server-ip:8998/
|
60
|
+
|
51
61
|
=== Adding Users
|
52
62
|
|
53
|
-
Whenever you want to add a user, it's
|
63
|
+
Whenever you want to add a user, it's as simple as:
|
54
64
|
|
55
65
|
gitauth adduser user-name path-to-public-key
|
56
66
|
|
data/bin/gitauth
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright (C) 2009
|
4
|
+
# Copyright (C) 2009 Brown Beagle Software
|
5
5
|
# Copyright (C) 2008 Darcy Laycock <sutto@sutto.net>
|
6
6
|
#
|
7
7
|
# This program is free software: you can redistribute it and/or modify
|
@@ -26,6 +26,7 @@ require File.join(File.dirname(__FILE__), "..", "lib", "gitauth")
|
|
26
26
|
|
27
27
|
class GitAuthRunner < Thor
|
28
28
|
|
29
|
+
# Adding users, groups and repos
|
29
30
|
|
30
31
|
desc "addrepo REPO-NAME [PATH-PART]", "Adds a new repository"
|
31
32
|
def addrepo(name, path = name)
|
@@ -43,7 +44,7 @@ class GitAuthRunner < Thor
|
|
43
44
|
def adduser(name, key_path)
|
44
45
|
GitAuth.setup!
|
45
46
|
admin = !!(options && options[:admin])
|
46
|
-
if GitAuth::
|
47
|
+
if GitAuth::User.create(name, admin, File.read(key_path).strip)
|
47
48
|
$stdout.puts "User added"
|
48
49
|
else
|
49
50
|
$stderr.puts "There was an error adding the given user"
|
@@ -51,41 +52,34 @@ class GitAuthRunner < Thor
|
|
51
52
|
end
|
52
53
|
end
|
53
54
|
|
54
|
-
desc "
|
55
|
-
def
|
55
|
+
desc "addgroup NAME", "Adds a group with the specified name"
|
56
|
+
def addgroup(name)
|
56
57
|
GitAuth.setup!
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
desc "users", "Lists all users in the system"
|
64
|
-
def users
|
65
|
-
GitAuth.setup!
|
66
|
-
$stdout.puts "users:"
|
67
|
-
GitAuth::Users.all.each do |user|
|
68
|
-
$stdout.puts "- #{user.name}"
|
58
|
+
if GitAuth::Group.create(name)
|
59
|
+
$stdout.puts "The group was added"
|
60
|
+
else
|
61
|
+
$stderr.puts "There was an error creating the aforementioned group"
|
62
|
+
exit! 1
|
69
63
|
end
|
70
64
|
end
|
71
65
|
|
66
|
+
# Misc. operations
|
72
67
|
|
73
|
-
desc "permissions REPO
|
74
|
-
def permissions(repo,
|
68
|
+
desc "permissions REPO USERORGROUP [PERMISION=all,read,write]", "Adds Permissions for a user or group to a repository"
|
69
|
+
def permissions(repo, user_or_group, permissions = "all")
|
75
70
|
GitAuth.setup!
|
76
71
|
unless %w(read write all).include?(permissions)
|
77
72
|
$stderr.puts "Invalid permissions: #{permissions}"
|
78
73
|
exit! 1
|
79
74
|
end
|
80
75
|
repo = GitAuth::Repo.get(repo)
|
81
|
-
|
82
|
-
if repo.nil? ||
|
76
|
+
uog = GitAuth.get_user_or_group(user_or_group)
|
77
|
+
if repo.nil? || uog.nil?
|
83
78
|
$stderr.puts "Invalid repository or user, please check the name"
|
84
79
|
exit! 1
|
85
80
|
end
|
86
|
-
repo.writeable_by(
|
87
|
-
repo.readable_by(
|
88
|
-
GitAuth::Users.save!
|
81
|
+
repo.writeable_by(uog) if %w(all write).include?(permissions)
|
82
|
+
repo.readable_by(uog) if %w(all read).include?(permissions)
|
89
83
|
GitAuth::Repo.save!
|
90
84
|
$stdout.puts "Permissions Added"
|
91
85
|
end
|
@@ -99,6 +93,10 @@ class GitAuthRunner < Thor
|
|
99
93
|
$stderr.puts "Please log in as the correct user and re-run"
|
100
94
|
exit! 1
|
101
95
|
end
|
96
|
+
if !GitAuth::Repo.has_git?
|
97
|
+
$stderr.puts "'git' was not found in your path - please install it before continuing."
|
98
|
+
exit! 1
|
99
|
+
end
|
102
100
|
require 'fileutils'
|
103
101
|
folder = File.expand_path("~/.ssh")
|
104
102
|
if !File.exist?(folder) || !File.directory?(folder)
|
@@ -139,7 +137,7 @@ class GitAuthRunner < Thor
|
|
139
137
|
end
|
140
138
|
if !public_key_path.nil? && File.exist?(public_key_path)
|
141
139
|
GitAuth.setup!
|
142
|
-
created = GitAuth::
|
140
|
+
created = GitAuth::User.create("admin", true, File.read(public_key_path).strip)
|
143
141
|
if created
|
144
142
|
$stdout.puts "Admin User Created."
|
145
143
|
else
|
@@ -153,6 +151,84 @@ class GitAuthRunner < Thor
|
|
153
151
|
exit! 1
|
154
152
|
end
|
155
153
|
|
154
|
+
# Viewing Users etc
|
155
|
+
|
156
|
+
desc "repos", "Lists all the current repos handled by gitauth"
|
157
|
+
def repos
|
158
|
+
GitAuth.setup!
|
159
|
+
$stdout.puts "Repositories:"
|
160
|
+
GitAuth::Repo.all.each do |repo|
|
161
|
+
line = " - #{repo.name}"
|
162
|
+
line << " (#{repo.path})" if repo.path != repo.name
|
163
|
+
$stdout.puts line
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
desc "users", "Lists all users handled by gitauth"
|
168
|
+
def users
|
169
|
+
GitAuth.setup!
|
170
|
+
$stdout.puts "Users:"
|
171
|
+
GitAuth::User.all.each do |user|
|
172
|
+
line = "- #{user}"
|
173
|
+
line << " (admin)" if user.admin?
|
174
|
+
$stdout.puts line
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
desc "groups", "Lists all groups handled by gitauth"
|
179
|
+
def groups
|
180
|
+
GitAuth.setup!
|
181
|
+
$stdout.puts "Groups:"
|
182
|
+
GitAuth::Group.all.each do |group|
|
183
|
+
$stdout.puts "- #{group} - #{group.members.empty? ? "no members" : group.members.join(", ")}"
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
desc "webapp", "starts serving the GitAuth web-app on Port 8998"
|
188
|
+
def webapp
|
189
|
+
s = GitAuth.settings
|
190
|
+
if s.web_username.to_s.empty? || s.web_password_hash.to_s.empty?
|
191
|
+
$stdout.puts "To use the web interface you must first setup some credentials:"
|
192
|
+
$stdout.print "What username would you like to use? (default is 'gitauth'): "
|
193
|
+
username = Readline.readline.strip
|
194
|
+
username = "gitauth" if username.empty?
|
195
|
+
$stdout.print "What password would you like to use?: "
|
196
|
+
password = read_password
|
197
|
+
while password.empty?
|
198
|
+
$stdout.print "Please try again, What password would you like to use?: "
|
199
|
+
password = read_password
|
200
|
+
end
|
201
|
+
print "Please enter your password again: "
|
202
|
+
confirmation = read_password
|
203
|
+
while confirmation != password
|
204
|
+
print "Wrong password, please confirm again: "
|
205
|
+
confirmation = read_password
|
206
|
+
end
|
207
|
+
require 'digest/sha2'
|
208
|
+
settings = YAML.load_file(File.join(GitAuth::GITAUTH_DIR, "settings.yml"))
|
209
|
+
settings.merge!({
|
210
|
+
"web_username" => username,
|
211
|
+
"web_password_hash" => Digest::SHA256.hexdigest(password)
|
212
|
+
})
|
213
|
+
File.open(File.join(GitAuth::GITAUTH_DIR, "settings.yml"), "w+") { |f| f.write settings.to_yaml }
|
214
|
+
puts "Username and Password saved."
|
215
|
+
GitAuth.reload_settings!
|
216
|
+
end
|
217
|
+
GitAuth.serve_web!
|
218
|
+
rescue Interrupt
|
219
|
+
exit! 1
|
220
|
+
end
|
221
|
+
|
222
|
+
protected
|
223
|
+
|
224
|
+
def read_password
|
225
|
+
system "stty -echo"
|
226
|
+
line = Readline.readline.strip
|
227
|
+
system "stty echo"
|
228
|
+
print "\n"
|
229
|
+
return line
|
230
|
+
end
|
231
|
+
|
156
232
|
end
|
157
233
|
|
158
234
|
if ARGV.empty?
|
data/bin/gitauth-shell
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright (C) 2009
|
4
|
+
# Copyright (C) 2009 Brown Beagle Software
|
5
5
|
# Copyright (C) 2008 Darcy Laycock <sutto@sutto.net>
|
6
6
|
#
|
7
7
|
# This program is free software: you can redistribute it and/or modify
|
@@ -32,35 +32,5 @@ File.umask(0022)
|
|
32
32
|
user_name = ARGV[0]
|
33
33
|
command = ENV["SSH_ORIGINAL_COMMAND"]
|
34
34
|
|
35
|
-
GitAuth::Client.start!(user_name, command)
|
36
|
-
|
37
|
-
c.on(:invalid_user) do |c|
|
38
|
-
c.exit_with_error "An invalid user / key was used. Please ensure it is setup with GitAuth"
|
39
|
-
end
|
40
|
-
|
41
|
-
c.on(:invalid_command) do |c|
|
42
|
-
if c.user.shell_accessible?
|
43
|
-
exec(ENV["SHELL"])
|
44
|
-
else
|
45
|
-
c.exit_with_error "SSH_ORIGINAL_COMMAND is needed, mmmkay?"
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
c.on(:invalid_repository) do |c|
|
50
|
-
c.exit_with_error "Ze repository you specified does not exist."
|
51
|
-
end
|
52
|
-
|
53
|
-
c.on(:bad_command) do |c|
|
54
|
-
c.exit_with_error "A Bad Command Has Failed Ye, Thou Shalt Not Continue."
|
55
|
-
end
|
56
|
-
|
57
|
-
c.on(:access_denied) do |c|
|
58
|
-
c.exit_with_error "These are not the droids you are looking for"
|
59
|
-
end
|
60
|
-
|
61
|
-
c.on(:fatal_error) do |c|
|
62
|
-
c.exit_with_error "Holy crap, we've imploded cap'n!"
|
63
|
-
end
|
64
|
-
|
65
|
-
end
|
35
|
+
GitAuth::Client.start!(user_name, command)
|
66
36
|
|
data/lib/gitauth/client.rb
CHANGED
@@ -25,20 +25,12 @@ module GitAuth
|
|
25
25
|
attr_accessor :user, :command
|
26
26
|
|
27
27
|
def initialize(user_name, command)
|
28
|
-
GitAuth.logger.debug "Initializing client with command:
|
28
|
+
GitAuth.logger.debug "Initializing client with command: #{command.inspect} and user name #{user_name.inspect}"
|
29
29
|
@callbacks = Hash.new { |h,k| h[k] = [] }
|
30
|
-
@user = GitAuth::
|
30
|
+
@user = GitAuth::User.get(user_name.to_s.strip)
|
31
31
|
@command = command
|
32
32
|
end
|
33
33
|
|
34
|
-
def on(command, &blk)
|
35
|
-
@callbacks[command.to_sym] << blk
|
36
|
-
end
|
37
|
-
|
38
|
-
def execute_callback!(command)
|
39
|
-
@callbacks[command.to_sym].each { |c| c.call(self) }
|
40
|
-
end
|
41
|
-
|
42
34
|
def exit_with_error(error)
|
43
35
|
GitAuth.logger.warn "Exiting with error: #{error}"
|
44
36
|
$stderr.puts error
|
@@ -47,24 +39,30 @@ module GitAuth
|
|
47
39
|
|
48
40
|
def run!
|
49
41
|
if @user.nil?
|
50
|
-
|
42
|
+
exit_with_error "An invalid user / key was used. Please ensure it is setup with GitAuth"
|
51
43
|
elsif @command.to_s.strip.empty?
|
52
|
-
|
44
|
+
if user.shell_accessible?
|
45
|
+
exec(ENV["SHELL"])
|
46
|
+
else
|
47
|
+
exit_with_error "SSH_ORIGINAL_COMMAND is needed, mmmkay?"
|
48
|
+
end
|
53
49
|
else
|
54
50
|
command = Command.parse!(@command)
|
55
|
-
repo = Repo.get(extract_repo_name(command))
|
51
|
+
repo = command.bad? ? nil : Repo.get(extract_repo_name(command))
|
56
52
|
if command.bad?
|
57
|
-
|
53
|
+
if user.shell_accessible?
|
54
|
+
exec(@command)
|
55
|
+
else
|
56
|
+
exit_with_error "A Bad Command Has Failed Ye, Thou Shalt Not Continue."
|
57
|
+
end
|
58
58
|
elsif repo.nil?
|
59
|
-
|
59
|
+
exit_with_error "Ze repository you specified does not exist."
|
60
60
|
elsif user.can_execute?(command, repo)
|
61
|
-
# We can go ahead.
|
62
61
|
git_shell_argument = "#{command.verb} '#{repo.real_path}'"
|
63
|
-
# And execute that soab.
|
64
62
|
GitAuth.logger.info "Running command: #{git_shell_argument} for user: #{@user.name}"
|
65
63
|
exec("git-shell", "-c", git_shell_argument)
|
66
64
|
else
|
67
|
-
|
65
|
+
exit_with_error "These are not the droids you are looking for"
|
68
66
|
end
|
69
67
|
end
|
70
68
|
rescue Exception => e
|
@@ -72,7 +70,7 @@ module GitAuth
|
|
72
70
|
e.backtrace.each do |l|
|
73
71
|
GitAuth.logger.fatal " => #{l}"
|
74
72
|
end
|
75
|
-
|
73
|
+
exit_with_error "Holy crap, we've imploded cap'n!"
|
76
74
|
end
|
77
75
|
|
78
76
|
def self.start!(user, command)
|
data/lib/gitauth/command.rb
CHANGED
@@ -34,7 +34,7 @@ module GitAuth
|
|
34
34
|
# Standard Commands
|
35
35
|
READ_COMMANDS = ["git-upload-pack", "git upload-pack"]
|
36
36
|
WRITE_COMMANDS = ["git-receive-pack", "git receive-pack"]
|
37
|
-
PATH_REGEXP = /^'([
|
37
|
+
PATH_REGEXP = /^'([\w\_\-\.\+]+(\.git)?)'$/i.freeze
|
38
38
|
|
39
39
|
attr_reader :path, :verb, :command
|
40
40
|
|
@@ -61,7 +61,7 @@ module GitAuth
|
|
61
61
|
# These exceptions are FUGLY.
|
62
62
|
# Clean up, mmkay?
|
63
63
|
def process!
|
64
|
-
raise BadCommandError if @command.include?("\n")
|
64
|
+
raise BadCommandError if @command.include?("\n") || @command !~ /^git/i
|
65
65
|
@verb, @argument = split_command
|
66
66
|
raise BadCommandError if @argument.nil? || @argument.is_a?(Array)
|
67
67
|
# Check if it's read / write
|
@@ -0,0 +1,86 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (C) 2009 Brown Beagle Software
|
3
|
+
# Copyright (C) 2008 Darcy Laycock <sutto@sutto.net>
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU Affero General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU Affero General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Affero General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
#++
|
18
|
+
|
19
|
+
|
20
|
+
module GitAuth
|
21
|
+
class Group < SaveableClass(:groups)
|
22
|
+
|
23
|
+
attr_accessor :name, :members
|
24
|
+
|
25
|
+
def initialize(name)
|
26
|
+
@name = name
|
27
|
+
@members = []
|
28
|
+
end
|
29
|
+
|
30
|
+
def destroy!
|
31
|
+
GitAuth::Repo.all.each { |r| r.remove_permissions_for(self) }
|
32
|
+
self.class.all.each { |r| r.remove_member(self) }
|
33
|
+
self.class.all.reject! { |g| g == self }
|
34
|
+
GitAuth::Repo.save!
|
35
|
+
self.class.save!
|
36
|
+
end
|
37
|
+
|
38
|
+
def add_member(member)
|
39
|
+
return if member == self
|
40
|
+
@members << member.to_s
|
41
|
+
@members.uniq!
|
42
|
+
end
|
43
|
+
|
44
|
+
def remove_member(member)
|
45
|
+
@members.reject! { |m| m == member.to_s }
|
46
|
+
end
|
47
|
+
|
48
|
+
def ==(group)
|
49
|
+
group.is_a?(Group) && group.name == self.name
|
50
|
+
end
|
51
|
+
|
52
|
+
def member?(user_or_group, recurse = false, level = 0)
|
53
|
+
member = @members.include?(user_or_group.to_s)
|
54
|
+
Thread.current[:checked_groups] = [] if level == 0
|
55
|
+
if !member
|
56
|
+
return false if level > 0 && Thread.current[:checked_groups].include?(self)
|
57
|
+
Thread.current[:checked_groups] << self
|
58
|
+
member = recurse && @members.map { |m| Group.get(m) }.compact.any? { |g| g.member?(user_or_group, true, level + 1) }
|
59
|
+
end
|
60
|
+
Thread.current[:checked_groups] = nil if level == 0
|
61
|
+
return member
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_s
|
65
|
+
"@#{name}"
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.create(name)
|
69
|
+
name = name.to_s.strip.gsub(/^@/, "")
|
70
|
+
return false if name.empty? || name !~ /^([\w\_\-\.]+)$/
|
71
|
+
self.add_item self.new(name)
|
72
|
+
return true
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.get(name)
|
76
|
+
GitAuth.logger.debug "Getting group named #{name.inspect}"
|
77
|
+
real_name = name.to_s.gsub(/^@/, "")
|
78
|
+
self.all.detect { |g| g.name == real_name }
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.group?(name)
|
82
|
+
name.to_s =~ /^@/ && !get(name).nil?
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
data/lib/gitauth/repo.rb
CHANGED
@@ -18,28 +18,8 @@
|
|
18
18
|
|
19
19
|
require 'fileutils'
|
20
20
|
module GitAuth
|
21
|
-
class Repo
|
22
|
-
|
23
|
-
|
24
|
-
def self.all
|
25
|
-
@@all_repositories ||= nil
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.load!
|
29
|
-
self.all = YAML.load_file(REPOS_PATH) rescue nil if File.exist?(REPOS_PATH)
|
30
|
-
self.all = [] unless self.all.is_a?(Array)
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.save!
|
34
|
-
load! if self.all.nil?
|
35
|
-
File.open(REPOS_PATH, "w+") do |f|
|
36
|
-
f.write self.all.to_yaml
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.all=(value)
|
41
|
-
@@all_repositories = value
|
42
|
-
end
|
21
|
+
class Repo < SaveableClass(:repositories)
|
22
|
+
NAME_RE = /^([\w\_\-\.\+]+(\.git)?)$/i
|
43
23
|
|
44
24
|
def self.get(name)
|
45
25
|
GitAuth.logger.debug "Getting Repo w/ name: '#{name}'"
|
@@ -47,43 +27,55 @@ module GitAuth
|
|
47
27
|
end
|
48
28
|
|
49
29
|
def self.create(name, path = name)
|
50
|
-
return false
|
30
|
+
return false if name.nil? || path.nil?
|
31
|
+
return false if self.get(name) || self.all.any? { |r| r.path == path } || name !~ NAME_RE || path !~ NAME_RE
|
51
32
|
repository = self.new(name, path)
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
self.save!
|
56
|
-
return true
|
57
|
-
else
|
58
|
-
return false
|
59
|
-
end
|
33
|
+
return false unless repository.create_repo!
|
34
|
+
self.add_item(repository)
|
35
|
+
return true
|
60
36
|
end
|
61
37
|
|
62
|
-
attr_accessor :name, :path
|
38
|
+
attr_accessor :name, :path, :permissions
|
63
39
|
|
64
40
|
def initialize(name, path, auto_create = false)
|
65
41
|
@name, @path = name, path
|
66
42
|
@permissions = {}
|
67
43
|
end
|
68
44
|
|
69
|
-
def
|
45
|
+
def ==(other)
|
46
|
+
other.is_a?(Repo) && other.name == name && other.path == path
|
47
|
+
end
|
48
|
+
|
49
|
+
def writeable_by(user_or_group)
|
70
50
|
@permissions[:write] ||= []
|
71
|
-
@permissions[:write] <<
|
51
|
+
@permissions[:write] << user_or_group.to_s
|
72
52
|
@permissions[:write].uniq!
|
73
53
|
end
|
74
54
|
|
75
|
-
def readable_by(
|
55
|
+
def readable_by(user_or_group)
|
76
56
|
@permissions[:read] ||= []
|
77
|
-
@permissions[:read] <<
|
57
|
+
@permissions[:read] << user_or_group.to_s
|
78
58
|
@permissions[:read].uniq!
|
79
59
|
end
|
80
60
|
|
81
|
-
def writeable_by?(
|
82
|
-
(@permissions[:write] || []).
|
61
|
+
def writeable_by?(user_or_group)
|
62
|
+
!(@permissions[:write] || []).detect do |writer|
|
63
|
+
writer = GitAuth.get_user_or_group(writer)
|
64
|
+
writer == user_or_group || (writer.is_a?(Group) && writer.member?(user_or_group, true))
|
65
|
+
end.nil?
|
83
66
|
end
|
84
67
|
|
85
|
-
def readable_by?(
|
86
|
-
(@permissions[:read] || []).
|
68
|
+
def readable_by?(user_or_group)
|
69
|
+
!(@permissions[:read] || []).detect do |reader|
|
70
|
+
reader = GitAuth.get_user_or_group(reader)
|
71
|
+
reader == user_or_group || (reader.is_a?(Group) && reader.member?(user_or_group, true))
|
72
|
+
end.nil?
|
73
|
+
end
|
74
|
+
|
75
|
+
def remove_permissions_for(user_or_group)
|
76
|
+
@permissions.each_value do |val|
|
77
|
+
val.reject! { |m| m == user_or_group.to_s }
|
78
|
+
end
|
87
79
|
end
|
88
80
|
|
89
81
|
def real_path
|
@@ -91,6 +83,7 @@ module GitAuth
|
|
91
83
|
end
|
92
84
|
|
93
85
|
def create_repo!
|
86
|
+
return false if !self.class.has_git?
|
94
87
|
path = self.real_path
|
95
88
|
unless File.exist?(path) && File.directory?(path)
|
96
89
|
FileUtils.mkdir_p(path)
|
@@ -102,5 +95,15 @@ module GitAuth
|
|
102
95
|
end
|
103
96
|
end
|
104
97
|
|
98
|
+
def destroy!
|
99
|
+
FileUtils.rm_rf(self.real_path) if File.exist?(self.real_path)
|
100
|
+
self.class.all.reject! { |r| r == self }
|
101
|
+
self.class.save!
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.has_git?
|
105
|
+
!`which git`.strip.empty?
|
106
|
+
end
|
107
|
+
|
105
108
|
end
|
106
109
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (C) 2009 Brown Beagle Software
|
3
|
+
# Copyright (C) 2008 Darcy Laycock <sutto@sutto.net>
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU Affero General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU Affero General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Affero General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
#++
|
18
|
+
|
19
|
+
|
20
|
+
module GitAuth
|
21
|
+
def self.SaveableClass(kind)
|
22
|
+
klass = Class.new
|
23
|
+
path_name = "#{kind.to_s.upcase}_PATH"
|
24
|
+
yaml_file_name = "#{kind}.yml"
|
25
|
+
|
26
|
+
saveable_class_def = <<-END
|
27
|
+
|
28
|
+
#{path_name} = File.join(GitAuth::GITAUTH_DIR, #{yaml_file_name.inspect})
|
29
|
+
|
30
|
+
def self.all
|
31
|
+
@@all_#{kind} ||= nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.all=(value)
|
35
|
+
@@all_#{kind} = value
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.load!
|
39
|
+
self.all = YAML.load_file(#{path_name}) rescue nil if File.exist?(#{path_name})
|
40
|
+
self.all = [] unless self.all.is_a?(Array)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.save!
|
44
|
+
load! if self.all.nil?
|
45
|
+
File.open(#{path_name}, "w+") do |f|
|
46
|
+
f.write self.all.to_yaml
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.add_item(item)
|
51
|
+
self.load! if self.all.nil?
|
52
|
+
self.all << item
|
53
|
+
self.save!
|
54
|
+
end
|
55
|
+
|
56
|
+
END
|
57
|
+
klass.class_eval(saveable_class_def)
|
58
|
+
return klass
|
59
|
+
end
|
60
|
+
end
|