socialforge/lib/trustie/grack/auth.rb

104 lines
2.4 KiB
Ruby

#coding=utf-8
#
require 'rack/auth/basic'
require 'rack/auth/abstract/handler'
require 'rack/auth/abstract/request'
module Grack
class Auth < Rack::Auth::Basic
DOWNLOAD_COMMANDS = %w{ git-upload-pack git-upload-archive }
PUSH_COMMANDS = %w{ git-receive-pack }
attr_accessor :user, :repository
def call(env)
@env = env
@request = Rack::Request.new(env)
@auth = Request.new(env)
if not @auth.provided?
unauthorized
elsif not @auth.basic?
bad_request
else
result = if (access = valid?(@auth) and access == true)
@env['REMOTE_USER'] = @auth.username
env['REP_PATH'] = repository.root_url
@app.call(env)
else
if access == '404'
render_not_found
elsif access == '403'
#render_no_access
unauthorized
else
unauthorized
end
end
result
end
end# method call
def render_not_found
[404, {"Content-Type" => "text/plain"}, ["Not Found"]]
end
def valid?(auth)
self.repository = auth_rep
return "404" unless repository
username, password = auth.credentials
self.user = auth_user(username, password)
return '403' unless user
access = auth_request
puts "access #{access}"
access
end
def auth_rep
rep = nil
match = @request.path_info.match(/(\/.+\.git)\//)
if match
rep = Repository.where("root_url like ?", "%#{match[1]}").first
end
rep
end
def auth_user(username, password)
u, last_login_on = User.try_to_login(username, password)
unless u && (u.member_of?(repository.project) || u.admin?)
u = nil
end
u
end
def auth_request
case git_cmd
when *DOWNLOAD_COMMANDS
user != nil
when *PUSH_COMMANDS
unless user
false
else
### 只有Manager和Development才有push权限
repository.project.members.where(user_id: user.id).first.roles.any?{|r| r.name == 'Manager' || r.name == 'Developer'}
end
else
false
end
end
def git_cmd
if @request.get?
@request.params['service']
elsif @request.post?
File.basename(@request.path)
else
nil
end
end
end# class Auth
end# module Grack