#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