mbbx6spp-gitauth 0.0.5.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,314 @@
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
+ require 'rack'
20
+ require 'sinatra'
21
+ require 'digest/sha2'
22
+
23
+ module GitAuth
24
+ class WebApp < Sinatra::Base
25
+ include GitAuth::Loggable
26
+
27
+ cattr_accessor :current_server
28
+
29
+ def self.has_auth?
30
+ username = GitAuth::Settings["web_username"]
31
+ password = GitAuth::Settings["web_password_hash"]
32
+ !(username.blank? || password.blank?)
33
+ end
34
+
35
+ def self.update_auth
36
+ raw_username = Readline.readline('GitAuth Username (default is \'gitauth\'): ')
37
+ raw_username = 'gitauth' if raw_username.blank?
38
+ raw_password = ''
39
+ while raw_password.blank?
40
+ system "stty -echo"
41
+ raw_password = Readline.readline('GitAuth Password: ')
42
+ system "stty echo"
43
+ print "\n"
44
+ puts "You need to provide a password, please try again" if raw_password.blank?
45
+ end
46
+ password_confirmation = nil
47
+ while password_confirmation != raw_password
48
+ system "stty -echo"
49
+ password_confirmation = Readline.readline('Confirm Password: ')
50
+ system "stty echo"
51
+ print "\n"
52
+ puts "The confirmation doesn't match your password, please try again" if raw_password != password_confirmation
53
+ end
54
+ GitAuth::Settings.update!({
55
+ :web_username => raw_username,
56
+ :web_password_hash => Digest::SHA256.hexdigest(raw_password)
57
+ })
58
+ end
59
+
60
+ def self.check_auth
61
+ GitAuth.prepare
62
+ if !has_auth?
63
+ if $stderr.tty?
64
+ logger.verbose = true
65
+ puts "For gitauth to continue, you need to provide a username and password."
66
+ update_auth
67
+ else
68
+ logger.fatal "You need to provide a username and password for GitAuth to function; Please run 'gitauth webapp` once"
69
+ exit!
70
+ end
71
+ end
72
+ end
73
+
74
+ def self.run(options = {})
75
+ check_auth
76
+ set options
77
+ handler = detect_rack_handler
78
+ handler_name = handler.name.gsub(/.*::/, '')
79
+ logger.info "Starting up web server on #{port}"
80
+ handler.run self, :Host => host, :Port => port do |server|
81
+ GitAuth::WebApp.current_server = server
82
+ set :running, true
83
+ end
84
+ rescue Errno::EADDRINUSE => e
85
+ logger.fatal "Server is already running on port #{port}"
86
+ end
87
+
88
+ def self.stop
89
+ if current_server.present?
90
+ current_server.respond_to?(:stop!) ? current_server.stop! : current_server.stop
91
+ end
92
+ exit!
93
+ logger.debug "Stopped Server."
94
+ end
95
+
96
+ unless GitAuth::ApacheAuthentication.setup?
97
+
98
+ use GitAuth::AuthSetupMiddleware
99
+
100
+ use Rack::Auth::Basic do |username, password|
101
+ [username, Digest::SHA256.hexdigest(password)] == [GitAuth::Settings["web_username"], GitAuth::Settings["web_password_hash"]]
102
+ end
103
+
104
+ end
105
+
106
+ configure do
107
+ set :port, 8998
108
+ set :views, GitAuth::BASE_DIR.join("views")
109
+ set :public, GitAuth::BASE_DIR.join("public")
110
+ set :static, true
111
+ set :methodoverride, true
112
+ end
113
+
114
+ before { GitAuth.reload_models! }
115
+
116
+ helpers do
117
+ include Rack::Utils
118
+ alias_method :h, :escape_html
119
+
120
+ def link_to(text, link)
121
+ "<a href='#{u link}'>#{text}</a>"
122
+ end
123
+
124
+ def u(url)
125
+ "#{request.script_name}#{url}"
126
+ end
127
+
128
+ def delete_link(text, url)
129
+ id = "deleteable-#{Digest::SHA256.hexdigest(url.to_s)[0, 6]}"
130
+ html = "<div class='deletable-container' style='display: none; margin: 0; padding: 0;'>"
131
+ html << "<form method='post' action='#{u url}' id='#{id}'>"
132
+ html << "<input name='_method' type='hidden' value='delete' />"
133
+ html << "</form></div>"
134
+ html << "<a href='#' onclick='if(confirm(\"Are you sure you want to do that? Deletion can not be reversed.\")) $(\"##{id}\").submit(); return false;'>#{text}</a>"
135
+ return html
136
+ end
137
+
138
+ def auto_link(member)
139
+ member = member.to_s
140
+ url = (member[0] == ?@ ? "/groups/#{URI.encode(member[1..-1])}" : "/users/#{URI.encode(member)}")
141
+ return link_to(member, url)
142
+ end
143
+
144
+ end
145
+
146
+ get '/' do
147
+ @repos = GitAuth::Repo.all
148
+ @users = GitAuth::User.all
149
+ @groups = GitAuth::Group.all
150
+ erb :index
151
+ end
152
+
153
+ # Listing / Index Page
154
+
155
+ get '/repos/:name' do
156
+ @repo = GitAuth::Repo.get(params[:name])
157
+ if @repo.nil?
158
+ redirect root_with_message("The given repository couldn't be found.")
159
+ else
160
+ read_perms, write_perms = (@repo.permissions[:read]||[]), (@repo.permissions[:write]||[])
161
+ @all_access = read_perms & write_perms
162
+ @read_only = read_perms - @all_access
163
+ @write_only = write_perms - @all_access
164
+ erb :repo
165
+ end
166
+ end
167
+
168
+ get '/users/:name' do
169
+ @user = GitAuth::User.get(params[:name])
170
+ if @user.nil?
171
+ redirect root_with_message("The given user couldn't be found.")
172
+ else
173
+ repos = GitAuth::Repo.all
174
+ read_perms = repos.select { |r| r.readable_by?(@user) }
175
+ write_perms = repos.select { |r| r.writeable_by?(@user) }
176
+ @all_access = read_perms & write_perms
177
+ @read_only = read_perms - @all_access
178
+ @write_only = write_perms - @all_access
179
+ @groups = GitAuth::Group.all.select { |g| g.member?(@user) }
180
+ erb :user
181
+ end
182
+ end
183
+
184
+ get '/groups/:name' do
185
+ @group = GitAuth::Group.get(params[:name])
186
+ if @group.nil?
187
+ redirect root_with_message("The given group could not be found.")
188
+ else
189
+ erb :group
190
+ end
191
+ end
192
+
193
+ # Create and update repos
194
+
195
+ post '/repos' do
196
+ name = params[:repo][:name]
197
+ path = params[:repo][:path]
198
+ path = name if path.to_s.strip.empty?
199
+ if repo = GitAuth::Repo.create(name, path)
200
+ make_empty = (params[:repo][:make_empty] == "1")
201
+ repo.make_empty! if make_empty
202
+ if repo.execute_post_create_hook!
203
+ redirect u("/?repo_name=#{URI.encode(name)}&made_empty=#{make_empty ? "yes" : "no"}")
204
+ else
205
+ redirect root_with_message("Repository added but the post-create hook exited unsuccessfully.")
206
+ end
207
+ else
208
+ redirect root_with_message("There was an error adding the repository.")
209
+ end
210
+ end
211
+
212
+ post '/repos/:name' do
213
+ repo = GitAuth::Repo.get(params[:name])
214
+ if repo.nil?
215
+ redirect root_with_message("The given repository couldn't be found.")
216
+ else
217
+ new_permissions = Hash.new([])
218
+ [:all, :read, :write].each do |k|
219
+ if params[:repo][k]
220
+ perm_lines = params[:repo][k].to_s.split("\n")
221
+ new_permissions[k] = perm_lines.map do |l|
222
+ i = GitAuth.get_user_or_group(l.strip)
223
+ i.nil? ? nil : i.to_s
224
+ end.compact
225
+ end
226
+ end
227
+ all = new_permissions.delete(:all)
228
+ new_permissions[:read] |= all
229
+ new_permissions[:write] |= all
230
+ new_permissions.each_value { |v| v.uniq! }
231
+ repo.permissions = new_permissions
232
+ GitAuth::Repo.save!
233
+ redirect u("/repos/#{URI.encode(repo.name)}")
234
+ end
235
+ end
236
+
237
+ delete '/repos/:name' do
238
+ repo = GitAuth::Repo.get(params[:name])
239
+ if repo.nil?
240
+ redirect root_with_message("The given repository couldn't be found.")
241
+ else
242
+ repo.destroy!
243
+ redirect root_with_message("Repository removed.")
244
+ end
245
+ end
246
+
247
+ # Create, delete and update users
248
+
249
+ post '/users' do
250
+ name = params[:user][:name]
251
+ admin = params[:user][:admin].to_s == "1"
252
+ key = params[:user][:key]
253
+ if GitAuth::User.create(name, admin, key)
254
+ redirect root_with_message("User Added")
255
+ else
256
+ redirect root_with_message("There was an error adding the requested user.")
257
+ end
258
+ end
259
+
260
+ delete '/users/:name' do
261
+ user = GitAuth::User.get(params[:name])
262
+ if user.nil?
263
+ redirect root_with_message("The specified user couldn't be found.")
264
+ else
265
+ user.destroy!
266
+ redirect root_with_message("User removed.")
267
+ end
268
+ end
269
+
270
+ # Create and Update Groups
271
+
272
+ post '/groups' do
273
+ if GitAuth::Group.create(params[:group][:name])
274
+ redirect root_with_message("Group added")
275
+ else
276
+ redirect root_with_message("There was an error adding the requested group.")
277
+ end
278
+ end
279
+
280
+ post '/groups/:name' do
281
+ group = GitAuth::Group.get(params[:name])
282
+ if group.nil?
283
+ redirect root_with_message("The specified group couldn't be found.")
284
+ else
285
+ if params[:group][:members]
286
+ member_lines = params[:group][:members].to_s.split("\n")
287
+ group.members = member_lines.map do |l|
288
+ i = GitAuth.get_user_or_group(l.strip)
289
+ i.nil? ? nil : i.to_s
290
+ end.compact - [group.to_s]
291
+ GitAuth::Group.save!
292
+ end
293
+ redirect u("/groups/#{URI.encode(group.name)}")
294
+ end
295
+ end
296
+
297
+ delete '/groups/:name' do
298
+ group = GitAuth::Group.get(params[:name])
299
+ if group.nil?
300
+ redirect root_with_message("The specified group couldn't be found.")
301
+ else
302
+ group.destroy!
303
+ redirect root_with_message("Group removed.")
304
+ end
305
+ end
306
+
307
+ # Misc Helpers
308
+
309
+ def root_with_message(message)
310
+ u("/?message=#{URI.encode(message)}")
311
+ end
312
+
313
+ end
314
+ end
data/lib/gitauth.rb ADDED
@@ -0,0 +1,101 @@
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
+ require 'rubygems'
20
+ require 'pathname'
21
+
22
+ # Prepend lib dir + any vendored lib's to the front of the load
23
+ # path to ensure they're loaded first.
24
+ $LOAD_PATH.unshift(*Dir[Pathname(__FILE__).dirname.join("../{lib,vendor/*/lib}").expand_path.to_s])
25
+
26
+ require 'perennial'
27
+
28
+ module GitAuth
29
+ include Perennial
30
+ include Loggable
31
+
32
+ VERSION = [0, 0, 5, 2]
33
+ BASE_DIR = Pathname(__FILE__).dirname.join("..").expand_path
34
+ GITAUTH_DIR = Pathname("~/.gitauth/").expand_path
35
+
36
+ manifest do |m, l|
37
+ Settings.root = File.dirname(__FILE__)
38
+ Settings.default_settings_path = GITAUTH_DIR.join("settings.yml")
39
+ Settings.lookup_key_path = []
40
+ Logger.default_logger_path = GITAUTH_DIR.join("gitauth.log")
41
+ # Register stuff on the loader.
42
+ l.register_controller :web_app, 'GitAuth::WebApp'
43
+ l.before_run { GitAuth.prepare }
44
+ end
45
+
46
+ require 'gitauth/message' # Basic error messages etc (as of yet unushed)
47
+ require 'gitauth/saveable_class' # Simple YAML store for dumpables classes
48
+ require 'gitauth/repo' # The basic GitAuth repo object
49
+ require 'gitauth/user' # The basic GitAuth user object
50
+ require 'gitauth/group' # The basic GitAuth group object (collection of users)
51
+ require 'gitauth/command' # Processes / filters commands
52
+ require 'gitauth/client' # Handles the actual SSH interaction / bringing it together
53
+
54
+ autoload :AuthSetupMiddleware, 'gitauth/auth_setup_middleware'
55
+ autoload :ApacheAuthentication, 'gitauth/apache_authentication'
56
+ autoload :WebApp, 'gitauth/web_app'
57
+
58
+ class << self
59
+
60
+ def prepare
61
+ GitAuth::Settings.setup!
62
+ reload_models!
63
+ end
64
+
65
+ def version
66
+ VERSION.join(".")
67
+ end
68
+
69
+ def msg(type, message)
70
+ Message.new(type, message)
71
+ end
72
+
73
+ def get_user_or_group(name)
74
+ name = name.to_s.strip
75
+ return if name.empty?
76
+ (name =~ /^@/ ? Group : User).get(name)
77
+ end
78
+
79
+ def has_git?
80
+ !`which git`.blank?
81
+ end
82
+
83
+ def each_model(method = nil, &blk)
84
+ [Repo, User, Group].each { |m| m.send(method) } if method.present?
85
+ [Repo, User, Group].each(&blk) unless blk.nil?
86
+ end
87
+
88
+ def reload_models!
89
+ each_model(:load!)
90
+ end
91
+
92
+ def run(command)
93
+ GitAuth::Logger.info "Running command: #{command}"
94
+ result = system "#{command} 2> /dev/null 1> /dev/null"
95
+ GitAuth::Logger.info "Command was #{"not " if !result}successful"
96
+ return result
97
+ end
98
+
99
+ end
100
+
101
+ end