mbbx6spp-gitauth 0.0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +661 -0
- data/README.rdoc +141 -0
- data/USAGE +70 -0
- data/bin/gitauth +261 -0
- data/bin/gitauth-shell +30 -0
- data/config.ru +16 -0
- data/lib/gitauth/apache_authentication.rb +64 -0
- data/lib/gitauth/auth_setup_middleware.rb +53 -0
- data/lib/gitauth/client.rb +95 -0
- data/lib/gitauth/command.rb +101 -0
- data/lib/gitauth/group.rb +87 -0
- data/lib/gitauth/message.rb +69 -0
- data/lib/gitauth/repo.rb +155 -0
- data/lib/gitauth/saveable_class.rb +54 -0
- data/lib/gitauth/user.rb +135 -0
- data/lib/gitauth/web_app.rb +314 -0
- data/lib/gitauth.rb +101 -0
- data/public/gitauth.css +316 -0
- data/public/gitauth.js +17 -0
- data/public/jquery.js +19 -0
- data/resources/messages.yml +9 -0
- data/views/auth_setup.erb +27 -0
- data/views/clone_repo.erb +24 -0
- data/views/group.erb +24 -0
- data/views/index.erb +88 -0
- data/views/layout.erb +27 -0
- data/views/repo.erb +57 -0
- data/views/user.erb +51 -0
- metadata +196 -0
data/README.rdoc
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
== GitAuth - SSH-based authentication for Shared Git Repositories.
|
2
|
+
|
3
|
+
If you've heard of Gitosis before, GitAuth is like Gitosis but A) in Ruby, B) slightly simpler to get going and C) doesn't use a git repository to manage users.
|
4
|
+
|
5
|
+
At the moment configuration / adding users is done via a single command - +gitauth+. For usage, see below.
|
6
|
+
|
7
|
+
=== License
|
8
|
+
|
9
|
+
GitAuth is licensed under AGPL, with parts of the code being derived
|
10
|
+
from Gitorius - http://gitorious.org
|
11
|
+
|
12
|
+
=== Installing GitAuth
|
13
|
+
|
14
|
+
Getting started is relatively simple. First of, you'll need to log onto the remote server / your git host. Next, you'll need to install the gem:
|
15
|
+
|
16
|
+
sudo gem install gitauth --source http://gemcutter.org/
|
17
|
+
|
18
|
+
Or, if you want to avoid the gems approach, you can use simply clone the repository
|
19
|
+
as follows and use the git submodule setup in order to vendor rack, sinatra and perennial:
|
20
|
+
|
21
|
+
git clone git://github.com/brownbeagle/gitauth.git
|
22
|
+
cd gitauth
|
23
|
+
git submodule init
|
24
|
+
git submodule update
|
25
|
+
|
26
|
+
With the gitauth binary being in the bin folder.
|
27
|
+
|
28
|
+
Once that's done, the +gitauth+ and +gitauth-shell+ commands should be in your path.
|
29
|
+
Next, you'll want to (in most cases anyway) use a specific +git+ user to host repositories.
|
30
|
+
|
31
|
+
Using the example of ubuntu, we'll add a git user under which all actions will now take place (note, this is essentially the same as gitosis):
|
32
|
+
|
33
|
+
sudo adduser --disabled-password --shell /bin/bash --group --home /home/git --system --gecos 'gitauth user for version control' git
|
34
|
+
|
35
|
+
Now, whenever you run the +gitauth+ executable, you'll do so as the user you just created
|
36
|
+
above. For example purposes, I suggest using the following in order to run all commands
|
37
|
+
as the 'git' user:
|
38
|
+
|
39
|
+
sudo -H -u git -i
|
40
|
+
|
41
|
+
And finally, to create a settings file and initialize .ssh and authorized_keys, perform the
|
42
|
+
following:
|
43
|
+
|
44
|
+
gitauth install
|
45
|
+
|
46
|
+
Note that when it asks you for the gitauth shell path, the default will lock
|
47
|
+
it to the current gitauth version SO if you want it to stay up to date between gem versions
|
48
|
+
point it to the path for always-current executable (e.g. on Ubuntu 9.04 w/ apt-get ruby + gems,
|
49
|
+
+/var/lib/gems/1.8/bin/gitauth-shell+)
|
50
|
+
|
51
|
+
Also, Note that if use the --admin option with path to a public key to the end of the install command,
|
52
|
+
it will initialize a new +admin+ user who can also login via SSH. e.g.
|
53
|
+
|
54
|
+
gitauth install --admin id_rsa.pub
|
55
|
+
|
56
|
+
Would initialize an admin user with the given public key.
|
57
|
+
|
58
|
+
Note that from now on, all gitauth keys should be run either logged in as
|
59
|
+
git (via the admin user and ssh) or by being prefixed with asgit or "sudo -H -u git"
|
60
|
+
|
61
|
+
=== Web Interface
|
62
|
+
|
63
|
+
To start the web interface, just run:
|
64
|
+
|
65
|
+
gitauth web-app
|
66
|
+
|
67
|
+
The first time you boot the web app, you will be prompted
|
68
|
+
to enter a username and a password. Please do so
|
69
|
+
and then surf to http://your-server-ip:8998/
|
70
|
+
|
71
|
+
For people running passenger, you can simply point it at
|
72
|
+
the public subdirectory and it will act as any normal passenger
|
73
|
+
web app. It's worth noting that in this approach you need
|
74
|
+
to run gitauth web-app at least once to setup a username and
|
75
|
+
password.
|
76
|
+
|
77
|
+
=== Adding Users
|
78
|
+
|
79
|
+
Whenever you want to add a user, it's as simple as:
|
80
|
+
|
81
|
+
gitauth add-user user-name path-to-public-key
|
82
|
+
|
83
|
+
Note that if the --admin option is specified, the user will
|
84
|
+
be able to log in to the shell via SSH and will also be able
|
85
|
+
to access any repository.
|
86
|
+
|
87
|
+
=== Adding Repositories
|
88
|
+
|
89
|
+
Adding a repository is a two step process. First, you create it:
|
90
|
+
|
91
|
+
gitauth add-repo repo-name
|
92
|
+
|
93
|
+
If you wish to initialize the repository with a blank commit (so
|
94
|
+
git clone works straight away), simply pass --make-empty / -m as
|
95
|
+
an option. e.g.:
|
96
|
+
|
97
|
+
gitauth add-repo repo-name --make-empty
|
98
|
+
|
99
|
+
Then, for every user who needs access, you do:
|
100
|
+
|
101
|
+
gitauth permissions repo-name user-name --type=permission-type
|
102
|
+
|
103
|
+
Where permission type is read, write or all. If permission
|
104
|
+
type isn't specified, it will default to all. If you wish
|
105
|
+
to remove a user from a repository, you can simply pass
|
106
|
+
use the type as none.
|
107
|
+
|
108
|
+
=== Accessing repos:
|
109
|
+
|
110
|
+
Finally, once you've added users / repos, using them is as simple
|
111
|
+
as doing the following on each users computer:
|
112
|
+
|
113
|
+
git clone git@your-remote-host:repo-name
|
114
|
+
|
115
|
+
Or
|
116
|
+
|
117
|
+
git clone git@your-remote-host:repo-name.git
|
118
|
+
|
119
|
+
Either form working just as well.
|
120
|
+
|
121
|
+
Note that for the first time you push, you will need
|
122
|
+
to use the full form (as below) unless you've used
|
123
|
+
the --make-empty / -m option when you created the repo.
|
124
|
+
|
125
|
+
git push origin master
|
126
|
+
|
127
|
+
As it starts as an empty repo.
|
128
|
+
|
129
|
+
Alternatively, if you get the error "fatal: no matching remote head" when you
|
130
|
+
clone and it doesn't create a local copy, you'll instead have to do the following
|
131
|
+
on your local PC (due to the way git handles remote repositories):
|
132
|
+
|
133
|
+
mkdir my-repo
|
134
|
+
cd my-repo
|
135
|
+
git init
|
136
|
+
touch README
|
137
|
+
git add .
|
138
|
+
git commit -m "Added blank readme"
|
139
|
+
git add remote origin git@your-server:my-repo.git
|
140
|
+
git push origin master
|
141
|
+
|
data/USAGE
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
GitAuth is a tool to provide authenticated git hosting from any unix like
|
2
|
+
box using ruby, git-shell and a whole lot of awesomeness.
|
3
|
+
|
4
|
+
Available commands include:
|
5
|
+
|
6
|
+
ls-users - Lists all users handled by GitAuth
|
7
|
+
|
8
|
+
ls-groups - Lists all groups handled by GitAuth
|
9
|
+
|
10
|
+
ls-repos - Lists all repositories handled by GitAuth
|
11
|
+
|
12
|
+
show-user - Shows information about a user with a given name
|
13
|
+
e.g: gitauth show-user darcy
|
14
|
+
|
15
|
+
show-group - Shows information about a group with a given name
|
16
|
+
e.g: gitauth show-group brownbeagle
|
17
|
+
or,: gitauth show-group @brownbeagle
|
18
|
+
|
19
|
+
show-repo - Shows information about a repository with a given name
|
20
|
+
e.g: gitauth show-repo project-a
|
21
|
+
|
22
|
+
add-user - adds a user with a specific name and ssh key
|
23
|
+
e.g. gitauth add-user darcy ~/id_rsa-one.pub
|
24
|
+
or,: gitauth add-user sutto ~/id_rsa-two.pub --admin
|
25
|
+
|
26
|
+
Would create two users, one an admin and one a normal user.
|
27
|
+
|
28
|
+
add-group - Adds a group with a specified name.
|
29
|
+
e.g: gitauth add-group brownbeagle
|
30
|
+
or,: gitauth add-group brownbeagle
|
31
|
+
|
32
|
+
From there on in, you can refer to the group as @brownbeagle
|
33
|
+
|
34
|
+
add-repo - Adds a repository with a specific name and an optional path
|
35
|
+
e.g: gitauth add-repo project-a
|
36
|
+
or,: gitauth add-repo project-b --make-empty
|
37
|
+
or,: gitauth add-repo project-c my-path-to-repo.git
|
38
|
+
or,: gitauth add-repo project-d my-path-to-other-repo --make-empty
|
39
|
+
|
40
|
+
--make-empty initializes it with a blank commit whilst
|
41
|
+
a second argument sets the path for the created repository.
|
42
|
+
The path is only ever used internally, the user refers to
|
43
|
+
it externally. e.g, project-c above would be accessible by:
|
44
|
+
user@your-server.com:project-c or user@your-server.com:project-c.git
|
45
|
+
|
46
|
+
rm-user - Removes a user with the given name
|
47
|
+
e.g: gitauth rm-user darcy
|
48
|
+
|
49
|
+
rm-group - Removes a specific group from GitAuth
|
50
|
+
e.g: gitauth rm-group brownbeagle
|
51
|
+
or,: gitauth rm-group @brownbeagle
|
52
|
+
|
53
|
+
rm-repo - Removes a repository from gitauth (destroys it on the filesystem as well)
|
54
|
+
e.g: gitauth rm-repo project-a
|
55
|
+
|
56
|
+
permissions - Set the permissions for a given user or group on a specific repository.
|
57
|
+
e.g: gitauth permissions project-a darcy
|
58
|
+
or,: gitauth permissions project-b darcy --type read
|
59
|
+
or,: gitauth permissions project-c darcy --type none
|
60
|
+
or,: gitauth permissions project-a @brownbeagle -t read
|
61
|
+
or,: gitauth permissions project-b @brownbeagle
|
62
|
+
|
63
|
+
The first argument being the repository name, the second a target -
|
64
|
+
either a user (e.g. darcy), or, if prefixed with an @-symbol, a group.
|
65
|
+
An optional --type argument specifies what permissions to use (all, read, write
|
66
|
+
or none - defaulting to all).
|
67
|
+
|
68
|
+
web-app - Starts up the web app, serving on port 8998
|
69
|
+
e.g: gitauth web-app
|
70
|
+
|
data/bin/gitauth
ADDED
@@ -0,0 +1,261 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "gitauth"))
|
3
|
+
|
4
|
+
GitAuth::Application.processing(ARGV) do |a|
|
5
|
+
a.banner = "GitAuth v#{GitAuth.version}"
|
6
|
+
|
7
|
+
a.generator!
|
8
|
+
|
9
|
+
a.option(:force, "force the creation of the settings file")
|
10
|
+
a.option(:admin, "pass the path to a ssh public key and it adds a default admin user")
|
11
|
+
a.add("install", "Sets up GitAuth for the current user") do |options|
|
12
|
+
|
13
|
+
setup_generator ".", :silent => true
|
14
|
+
|
15
|
+
# Check for a valid admin key
|
16
|
+
if options.has_key?(:admin) && (!options[:admin].is_a?(String) || !file?(options[:admin]))
|
17
|
+
puts "You provided the admin option but didn't provide it with a path to public key."
|
18
|
+
die! "Please re-run again with a path to a key, e.g. --admin=~/id_rsa.pub"
|
19
|
+
end
|
20
|
+
|
21
|
+
if !yes?("Are you logged in as the correct user?")
|
22
|
+
die!("Please log in as the correct user and re-run")
|
23
|
+
end
|
24
|
+
|
25
|
+
if !GitAuth.has_git?
|
26
|
+
die!("'git' was not found in your path - please install it / add it to your path before continuing.")
|
27
|
+
end
|
28
|
+
|
29
|
+
ssh_folder = "~/.ssh"
|
30
|
+
if !folder?(ssh_folder)
|
31
|
+
folders ssh_folder
|
32
|
+
chmod 0700, ssh_folder
|
33
|
+
end
|
34
|
+
|
35
|
+
authorized_keys = ssh_folder / "authorized_keys"
|
36
|
+
if !file?(authorized_keys)
|
37
|
+
file authorized_keys, "\n\n## GitAuth - DO NO EDIT BELOW THIS LINE ##\n"
|
38
|
+
chmod 0600, authorized_keys
|
39
|
+
end
|
40
|
+
|
41
|
+
gitauth_folder = "~/.gitauth/"
|
42
|
+
folders gitauth_folder
|
43
|
+
|
44
|
+
settings_file = gitauth_folder / "settings.yml"
|
45
|
+
if !file?(settings_file) || options[:force]
|
46
|
+
repo_path = ask("Where did you want repositories to be stored?", "~/repositories")
|
47
|
+
repo_path = File.expand_path(repo_path)
|
48
|
+
folders repo_path
|
49
|
+
|
50
|
+
default_shell_path = GitAuth::BASE_DIR.join("bin", "gitauth-shell").to_s
|
51
|
+
gitauth_shell_path = ""
|
52
|
+
gitauth_shell_set = false
|
53
|
+
while gitauth_shell_path.blank? || !(file?(gitauth_shell_path) && executable?(gitauth_shell_path))
|
54
|
+
# A Give the user a message if the path doesn't exist.
|
55
|
+
if gitauth_shell_set
|
56
|
+
puts "The shell you provided, #{gitauth_shell_path}, isn't executable"
|
57
|
+
else
|
58
|
+
gitauth_shell_set = true
|
59
|
+
end
|
60
|
+
gitauth_shell_path = ask("What is the path to your gitauth-shell?", default_shell_path)
|
61
|
+
gitauth_shell_path = File.expand_path(gitauth_shell_path)
|
62
|
+
end
|
63
|
+
|
64
|
+
GitAuth::Settings.update!({
|
65
|
+
:base_path => File.expand_path(repo_path),
|
66
|
+
:authorized_keys_file => File.expand_path(authorized_keys),
|
67
|
+
:shell_executable => File.expand_path(gitauth_shell_path)
|
68
|
+
})
|
69
|
+
end
|
70
|
+
|
71
|
+
if options[:admin]
|
72
|
+
key_contents = File.read(options[:admin]).strip
|
73
|
+
if GitAuth::User.create("admin", true, key_contents)
|
74
|
+
puts "Default admin user added with key '#{options[:admin]}'"
|
75
|
+
else
|
76
|
+
die! "Error adding default admin user with key at '#{options[:admin]}'"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
a.controller!(:web_app, "Starts the gitauth frontend using the default sintra runner", :skip_path => true)
|
83
|
+
|
84
|
+
a.option(:force, "Skip the verification / confirmation part of adding the permissions")
|
85
|
+
a.option(:type, "The type of permissions - one of all, read, write or none. Defaults to all")
|
86
|
+
full_desc = "Gives a specific user or group the specified permissions to a given repository"
|
87
|
+
a.add("permissions REPOSITORY USER-OR-GROUP", full_desc) do |repo, target, options|
|
88
|
+
GitAuth.prepare
|
89
|
+
permissions = options[:type] || 'all'
|
90
|
+
|
91
|
+
if !%w(all read write none).include? permissions
|
92
|
+
die! "'#{permissions}' is not a valid permission type. It must be all, read, write or none"
|
93
|
+
end
|
94
|
+
|
95
|
+
real_permissions = ({"all" => ["read", "write"], "none" => []}[permissions] || [permissions])
|
96
|
+
repository = GitAuth::Repo.get(repo)
|
97
|
+
real_target = GitAuth.get_user_or_group(target)
|
98
|
+
|
99
|
+
die! "Unknown repository '#{repo}'" if repository.blank?
|
100
|
+
die! "Unknown user or group '#{target}'" if real_target.blank?
|
101
|
+
|
102
|
+
if options[:force] || yes?("Adding '#{permissions}' permissions for #{real_target} to #{repository.name}")
|
103
|
+
repository.update_permissions!(real_target, real_permissions)
|
104
|
+
puts "Permissions updated."
|
105
|
+
else
|
106
|
+
puts "Permissions not added, exiting."
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
a.option(:admin, "Makes a user an admin user")
|
111
|
+
a.add("add-user NAME PATH-TO-PUBLIC-KEY", "Creates a user with a given public key") do |name, ssh_key, options|
|
112
|
+
GitAuth.prepare
|
113
|
+
die! "'#{ssh_key}' is not a valid path to a public key" if !File.file?(ssh_key)
|
114
|
+
admin = !!options[:admin]
|
115
|
+
contents = File.read(ssh_key).strip
|
116
|
+
if GitAuth::User.create(name, admin, contents)
|
117
|
+
puts "Successfully added user '#{name}' (user #{admin ? 'is' : 'is not'} an admin)"
|
118
|
+
else
|
119
|
+
die! "There was an unknown error attempting to add a user called '#{name}'"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
a.option(:make_empty, "Initializes the repository to be empty / have an initial blank commit")
|
124
|
+
a.add("add-repo NAME [PATH=NAME]", "Creates a named repository, with an optional path on the file system") do |name, *args|
|
125
|
+
GitAuth.prepare
|
126
|
+
options = args.extract_options!
|
127
|
+
path = (args.shift || name)
|
128
|
+
if (repo = GitAuth::Repo.create(name, path))
|
129
|
+
puts "Successfully created repository '#{name}' located at '#{path}'"
|
130
|
+
if options[:make_empty]
|
131
|
+
puts "Attempting to make empty repository"
|
132
|
+
repo.make_empty!
|
133
|
+
end
|
134
|
+
else
|
135
|
+
die! "Unable to create repository '#{name}' in location '#{path}'"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
a.add("add-group NAME", "Creates a group with a given name") do |name, options|
|
140
|
+
GitAuth.prepare
|
141
|
+
if GitAuth::Group.create(name)
|
142
|
+
puts "Successfully created group '#{name}'"
|
143
|
+
else
|
144
|
+
die! "Unable to create group '#{name}'"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
a.add("ls-users", "Lists all users currently managed by gitauth") do |options|
|
149
|
+
GitAuth.prepare
|
150
|
+
puts "Users:"
|
151
|
+
(GitAuth::User.all || []).each do |user|
|
152
|
+
line = "- #{user}"
|
153
|
+
line << " (admin)" if user.admin?
|
154
|
+
puts line
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
a.add("ls-repos", "Lists all repositories currently managed by gitauth") do |options|
|
159
|
+
GitAuth.prepare
|
160
|
+
puts "Repositories:"
|
161
|
+
(GitAuth::Repo.all || []).each do |repo|
|
162
|
+
line = " - #{repo.name}"
|
163
|
+
line << " (#{repo.path})" if repo.path != repo.name
|
164
|
+
puts line
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
a.add("ls-groups", "Lists all groups currently managed by gitauth") do |options|
|
169
|
+
GitAuth.prepare
|
170
|
+
puts "Groups:"
|
171
|
+
(GitAuth::Group.all || []).each do |group|
|
172
|
+
puts "- #{group} (#{group.members.empty? ? "no members" : group.members.join(", ")})"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
a.add("rm-user NAME", "Removes the specified user") do |name, options|
|
177
|
+
GitAuth.prepare
|
178
|
+
user = GitAuth::User.get(name)
|
179
|
+
die! "Unknown user '#{name}'" if user.blank?
|
180
|
+
user.destroy!
|
181
|
+
puts "Removed user '#{name}' - Please note you will manually need to remove this users line from authorized_keys"
|
182
|
+
end
|
183
|
+
|
184
|
+
a.add("rm-repo NAME", "Removes the specified repo") do |name, options|
|
185
|
+
GitAuth.prepare
|
186
|
+
repo = GitAuth::Repo.get(name)
|
187
|
+
die! "Unknown repo '#{name}'" if repo.blank?
|
188
|
+
repo.destroy!
|
189
|
+
puts "Removed repo '#{name}'"
|
190
|
+
end
|
191
|
+
|
192
|
+
a.add("rm-group NAME", "Removes the specified group") do |name, options|
|
193
|
+
GitAuth.prepare
|
194
|
+
group = GitAuth::Group.get(name)
|
195
|
+
die! "Unknown group '#{name}'" if group.blank?
|
196
|
+
group.destroy!
|
197
|
+
puts "Removed group '#{name}'"
|
198
|
+
end
|
199
|
+
|
200
|
+
a.add("usage", "Prints out the sample usage instructions") do |options|
|
201
|
+
pager = nil
|
202
|
+
if ENV.has_key?('PAGER')
|
203
|
+
pager = ENV['PAGER'].blank? ? 'cat' : ENV['PAGER']
|
204
|
+
else
|
205
|
+
pager = "less"
|
206
|
+
end
|
207
|
+
exec "#{pager} '#{GitAuth::BASE_DIR.join("USAGE")}'"
|
208
|
+
end
|
209
|
+
|
210
|
+
a.add("show-repo NAME", "Shows information for a repository with a given name") do |name, options|
|
211
|
+
GitAuth.prepare
|
212
|
+
repo = GitAuth::Repo.get(name)
|
213
|
+
die! "Unknown repository '#{repo}'" if repo.blank?
|
214
|
+
puts "Repository Name: #{repo.name}"
|
215
|
+
puts "Repository Path: #{repo.path}"
|
216
|
+
puts "Actual Path: #{repo.real_path}"
|
217
|
+
puts "\nRead Permissions:"
|
218
|
+
read_perms = repo.permissions.fetch(:read, [])
|
219
|
+
read_perms.each { |item| puts " - #{item}" }
|
220
|
+
puts " - No read permissions" if read_perms.blank?
|
221
|
+
puts "\nWrite Permissions:"
|
222
|
+
write_perms = repo.permissions.fetch(:write, [])
|
223
|
+
write_perms.each { |item| puts " - #{item}" }
|
224
|
+
puts " - No write permissions" if write_perms.blank?
|
225
|
+
end
|
226
|
+
|
227
|
+
a.add("show-group NAME", "Shows information for a group with a given name") do |name, options|
|
228
|
+
GitAuth.prepare
|
229
|
+
group = GitAuth::Group.get(name)
|
230
|
+
die! "Unable to find a group named '#{name}'" if group.blank?
|
231
|
+
puts "Group Name: #{group.name}"
|
232
|
+
puts "Reference Name: #{group.to_s}"
|
233
|
+
puts "\nGroup Members:"
|
234
|
+
group.members.each { |member| puts " - #{member}" }
|
235
|
+
puts " - This group has no members" if group.members.blank?
|
236
|
+
end
|
237
|
+
|
238
|
+
a.add("show-user NAME", "Shows details for a user with a specific name") do |name, options|
|
239
|
+
GitAuth.prepare
|
240
|
+
user = GitAuth::User.get(name)
|
241
|
+
die! "Unable to find a user named '#{name}'" if user.blank?
|
242
|
+
puts "User Name: #{user.name}"
|
243
|
+
groups = user.groups
|
244
|
+
puts "\nGroups:"
|
245
|
+
puts " - This user isn't a member of any groups" if groups.blank?
|
246
|
+
groups.each { |g| puts " - #{g.to_s}" }
|
247
|
+
end
|
248
|
+
|
249
|
+
a.add("enable-htaccess-auth", "Generates .htaccess and .htpasswd files, disabling the built in auth") do |options|
|
250
|
+
die! "Apache-based authentication is already used" if GitAuth::ApacheAuthentication.setup?
|
251
|
+
GitAuth::ApacheAuthentication.setup
|
252
|
+
puts "Apache-based authentication setup."
|
253
|
+
end
|
254
|
+
|
255
|
+
a.add("disable-htaccess-auth", "Removes .htaccess and .htpasswd files, enabling the built in auth") do |options|
|
256
|
+
die! "Apache-based authentication is not currently used" unless GitAuth::ApacheAuthentication.setup?
|
257
|
+
GitAuth::ApacheAuthentication.remove
|
258
|
+
puts "Removed Apache-based authentication"
|
259
|
+
end
|
260
|
+
|
261
|
+
end
|
data/bin/gitauth-shell
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright (C) 2009 Brown Beagle Software
|
5
|
+
# Copyright (C) 2009 Darcy Laycock <sutto@sutto.net>
|
6
|
+
#
|
7
|
+
# This program is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Affero General Public License as published by
|
9
|
+
# the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Affero General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Affero General Public License
|
18
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#++
|
20
|
+
|
21
|
+
|
22
|
+
base = __FILE__
|
23
|
+
# Get out of symlink-hell and then require the gitauth file.
|
24
|
+
base = File.readlink(base) while File.symlink?(base)
|
25
|
+
|
26
|
+
require File.expand_path(File.join(File.dirname(base), "..", "lib", "gitauth"))
|
27
|
+
|
28
|
+
# Start the cli client.
|
29
|
+
GitAuth::Client.start!(ARGV[0], ENV["SSH_ORIGINAL_COMMAND"])
|
30
|
+
|
data/config.ru
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "lib", "gitauth")
|
2
|
+
require GitAuth::BASE_DIR.join("lib", "gitauth", "web_app")
|
3
|
+
|
4
|
+
GitAuth::Settings.setup!
|
5
|
+
|
6
|
+
output = File.open(GitAuth::Logger.default_logger_path, "a+")
|
7
|
+
STDOUT.reopen(output)
|
8
|
+
STDERR.reopen(output)
|
9
|
+
|
10
|
+
{:root => GitAuth::BASE_DIR, :run => false, :env => :production}.each_pair do |key, value|
|
11
|
+
GitAuth::WebApp.configure do
|
12
|
+
set key, value
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
run GitAuth::WebApp.new
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'digest/sha2'
|
3
|
+
|
4
|
+
module GitAuth
|
5
|
+
class ApacheAuthentication
|
6
|
+
PUBLIC_DIR = GitAuth::BASE_DIR.join("public")
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
def setup?
|
11
|
+
PUBLIC_DIR.join(".htaccess").file? && PUBLIC_DIR.join(".htpasswd").file?
|
12
|
+
end
|
13
|
+
|
14
|
+
def setup
|
15
|
+
GitAuth::WebApp.check_auth
|
16
|
+
puts "To continue, we require you re-enter the password you wish to use."
|
17
|
+
raw_password = ''
|
18
|
+
password_hash = ''
|
19
|
+
existing_hash = GitAuth::Settings.web_password_hash
|
20
|
+
while raw_password.blank? && password_hash != existing_hash
|
21
|
+
raw_password = read_password('GitAuth Password: ')
|
22
|
+
password_hash = sha256_password(raw_password)
|
23
|
+
if raw_password.blank?
|
24
|
+
puts "You need to provide a password, please try again"
|
25
|
+
elsif password_hash != existing_hash
|
26
|
+
puts "Your password doesn't match the stored password. Please try again."
|
27
|
+
end
|
28
|
+
end
|
29
|
+
raw_username = GitAuth::Settings.web_username
|
30
|
+
encoded_password = "{SHA}#{[Digest::SHA1.digest(raw_password)].pack('m').strip}"
|
31
|
+
File.open(PUBLIC_DIR.join(".htpasswd"), "w+") do |file|
|
32
|
+
file.puts "#{raw_username}:#{encoded_password}"
|
33
|
+
end
|
34
|
+
File.open(PUBLIC_DIR.join(".htaccess"), "w+") do |file|
|
35
|
+
file.puts "AuthType Basic"
|
36
|
+
file.puts "AuthName \"GitAuth\""
|
37
|
+
file.puts "AuthUserFile #{PUBLIC_DIR.join(".htpasswd").expand_path}"
|
38
|
+
file.puts "Require valid-user"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def remove
|
43
|
+
PUBLIC_DIR.join(".htaccess").delete
|
44
|
+
PUBLIC_DIR.join(".htpasswd").delete
|
45
|
+
rescue Errno::ENOENT
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
|
50
|
+
def read_password(text)
|
51
|
+
system "stty -echo"
|
52
|
+
password = Readline.readline(text)
|
53
|
+
system "stty echo"
|
54
|
+
print "\n"
|
55
|
+
return password
|
56
|
+
end
|
57
|
+
|
58
|
+
def sha256_password(pass)
|
59
|
+
Digest::SHA256.hexdigest(pass)
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (C) 2009 Brown Beagle Software
|
3
|
+
# Copyright (C) 2009 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
|
+
module GitAuth
|
20
|
+
class AuthSetupMiddleware
|
21
|
+
|
22
|
+
def initialize(app)
|
23
|
+
@app = app
|
24
|
+
@files = Rack::File.new(GitAuth::BASE_DIR.join("public").to_s)
|
25
|
+
end
|
26
|
+
|
27
|
+
def call(env)
|
28
|
+
dup._call(env)
|
29
|
+
end
|
30
|
+
|
31
|
+
def _call(env)
|
32
|
+
@request = Rack::Request.new(env)
|
33
|
+
if GitAuth::WebApp.has_auth?
|
34
|
+
@app.call(env)
|
35
|
+
elsif env["PATH_INFO"].include?("/gitauth.css")
|
36
|
+
@files.call(env)
|
37
|
+
else
|
38
|
+
content = ERB.new(File.read(GitAuth::BASE_DIR.join("views", "auth_setup.erb"))).result(binding)
|
39
|
+
headers = {"Content-Type" => "text/html", "Content-Length" => Rack::Utils.bytesize(content).to_s}
|
40
|
+
[403, headers, [content]]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def u(path)
|
45
|
+
"#{@request.script_name}#{path}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def request
|
49
|
+
@request
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|