diff options
author | Franz-Robert van Vugt <f.vanvugt@zeno.nu> | 2014-03-27 21:40:33 +0100 |
---|---|---|
committer | Franz-Robert van Vugt <f.vanvugt@zeno.nu> | 2014-03-27 21:40:33 +0100 |
commit | cfc4a2dbe3652180c1d08d5d9e154e28cbb340fb (patch) | |
tree | f9af595878a2789be45c612e26ced8c9f7c592ad /lib | |
parent | f03820ebf2f28ddb26e422322219a815d8cd3749 (diff) | |
parent | fc5ac1451dcfda7cf53d536db79b552b29849276 (diff) | |
download | gitlab-ce-cfc4a2dbe3652180c1d08d5d9e154e28cbb340fb.tar.gz |
Merge branch 'master' of https://github.com/gitlabhq/gitlabhq into patch-1
Diffstat (limited to 'lib')
-rw-r--r-- | lib/api/entities.rb | 4 | ||||
-rw-r--r-- | lib/api/internal.rb | 60 | ||||
-rw-r--r-- | lib/api/merge_requests.rb | 16 | ||||
-rw-r--r-- | lib/api/projects.rb | 11 | ||||
-rw-r--r-- | lib/gitlab/backend/grack_auth.rb | 106 | ||||
-rw-r--r-- | lib/gitlab/backend/grack_helpers.rb | 28 | ||||
-rw-r--r-- | lib/gitlab/git_access.rb | 74 | ||||
-rw-r--r-- | lib/gitlab/markdown.rb | 6 | ||||
-rw-r--r-- | lib/gitlab/satellite/satellite.rb | 17 | ||||
-rw-r--r-- | lib/gitlab/upgrader.rb | 1 | ||||
-rwxr-xr-x | lib/support/init.d/gitlab | 34 | ||||
-rw-r--r-- | lib/support/nginx/gitlab | 8 | ||||
-rw-r--r-- | lib/tasks/gitlab/check.rake | 17 |
13 files changed, 223 insertions, 159 deletions
diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 8b4519af2d1..9fa8506926c 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -187,5 +187,9 @@ module API end end end + + class Label < Grape::Entity + expose :name + end end end diff --git a/lib/api/internal.rb b/lib/api/internal.rb index 69aad3748b3..bcf97574673 100644 --- a/lib/api/internal.rb +++ b/lib/api/internal.rb @@ -1,16 +1,12 @@ module API # Internal access API class Internal < Grape::API - - DOWNLOAD_COMMANDS = %w{ git-upload-pack git-upload-archive } - PUSH_COMMANDS = %w{ git-receive-pack } - namespace 'internal' do - # - # Check if ssh key has access to project code + # Check if git command is allowed to project # # Params: - # key_id - SSH Key id + # key_id - ssh key id for Git over SSH + # user_id - user id for Git over HTTP # project - project path with namespace # action - git action (git-upload-pack or git-receive-pack) # ref - branch name @@ -22,43 +18,25 @@ module API # the wiki repository as well. project_path = params[:project] project_path.gsub!(/\.wiki/,'') if project_path =~ /\.wiki/ - - key = Key.find(params[:key_id]) project = Project.find_with_namespace(project_path) - git_cmd = params[:action] return false unless project - - if key.is_a? DeployKey - key.projects.include?(project) && DOWNLOAD_COMMANDS.include?(git_cmd) - else - user = key.user - - return false if user.blocked? - - if Gitlab.config.ldap.enabled - if user.ldap_user? - # Check if LDAP user exists and match LDAP user_filter - unless Gitlab::LDAP::Access.new.allowed?(user) - return false - end - end - end - - action = case git_cmd - when *DOWNLOAD_COMMANDS - then :download_code - when *PUSH_COMMANDS - then - if project.protected_branch?(params[:ref]) - :push_code_to_protected_branches - else - :push_code - end - end - - user.can?(action, project) - end + actor = if params[:key_id] + Key.find(params[:key_id]) + elsif params[:user_id] + User.find(params[:user_id]) + end + + return false unless actor + + Gitlab::GitAccess.new.allowed?( + actor, + params[:action], + project, + params[:ref], + params[:oldrev], + params[:newrev] + ) end # diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index e2458198411..3a1a00d0719 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -125,6 +125,22 @@ module API end end + # Get a merge request's comments + # + # Parameters: + # id (required) - The ID of a project + # merge_request_id (required) - ID of MR + # Examples: + # GET /projects/:id/merge_request/:merge_request_id/comments + # + get ":id/merge_request/:merge_request_id/comments" do + merge_request = user_project.merge_requests.find(params[:merge_request_id]) + + authorize! :read_merge_request, merge_request + + present paginate(merge_request.notes), with: Entities::MRNote + end + # Post comment to merge request # # Parameters: diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 4d48d2194f8..9d290c75ba9 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -215,6 +215,17 @@ module API @users = paginate @users present @users, with: Entities::User end + + # Get a project labels + # + # Parameters: + # id (required) - The ID of a project + # Example Request: + # GET /projects/:id/labels + get ':id/labels' do + @labels = user_project.issues_labels + present @labels, with: Entities::Label + end end end end diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb index 60c03ce1c04..c2f3b851c07 100644 --- a/lib/gitlab/backend/grack_auth.rb +++ b/lib/gitlab/backend/grack_auth.rb @@ -1,11 +1,9 @@ require_relative 'shell_env' -require_relative 'grack_helpers' module Grack class Auth < Rack::Auth::Basic - include Helpers - attr_accessor :user, :project, :ref, :env + attr_accessor :user, :project, :env def call(env) @env = env @@ -24,14 +22,16 @@ module Grack @env['SCRIPT_NAME'] = "" - auth! + if project + auth! + else + render_not_found + end end private def auth! - return render_not_found unless project - if @auth.provided? return bad_request unless @auth.basic? @@ -40,12 +40,8 @@ module Grack # Allow authentication for GitLab CI service # if valid token passed - if login == "gitlab-ci-token" && project.gitlab_ci? - token = project.gitlab_ci_service.token - - if token.present? && token == password && service_name == 'git-upload-pack' - return @app.call(env) - end + if gitlab_ci_request?(login, password) + return @app.call(env) end @user = authenticate_user(login, password) @@ -53,23 +49,26 @@ module Grack if @user Gitlab::ShellEnv.set_env(@user) @env['REMOTE_USER'] = @auth.username - else - return unauthorized end - - else - return unauthorized unless project.public? end - if authorized_git_request? + if authorized_request? @app.call(env) else unauthorized end end - def authorized_git_request? - authorize_request(service_name) + def gitlab_ci_request?(login, password) + if login == "gitlab-ci-token" && project.gitlab_ci? + token = project.gitlab_ci_service.token + + if token.present? && token == password && git_cmd == 'git-upload-pack' + return true + end + end + + false end def authenticate_user(login, password) @@ -77,31 +76,31 @@ module Grack auth.find(login, password) end - def authorize_request(service) - case service - when 'git-upload-pack' - can?(user, :download_code, project) - when'git-receive-pack' - refs.each do |ref| - action = if project.protected_branch?(ref) - :push_code_to_protected_branches - else - :push_code - end - - return false unless can?(user, action, project) + def authorized_request? + case git_cmd + when *Gitlab::GitAccess::DOWNLOAD_COMMANDS + if user + Gitlab::GitAccess.new.download_allowed?(user, project) + elsif project.public? + # Allow clone/fetch for public projects + true + else + false + end + when *Gitlab::GitAccess::PUSH_COMMANDS + if user + # Skip user authorization on upload request. + # It will be serverd by update hook in repository + true + else + false end - - # Never let git-receive-pack trough unauthenticated; it's - # harmless but git < 1.8 doesn't like it - return false if user.nil? - true else false end end - def service_name + def git_cmd if @request.get? @request.params['service'] elsif @request.post? @@ -115,28 +114,17 @@ module Grack @project ||= project_by_path(@request.path_info) end - def refs - @refs ||= parse_refs - end - - def parse_refs - input = if @env["HTTP_CONTENT_ENCODING"] =~ /gzip/ - Zlib::GzipReader.new(@request.body).read - else - @request.body.read - end - - # Need to reset seek point - @request.body.rewind - - # Parse refs - refs = input.force_encoding('ascii-8bit').scan(/refs\/heads\/([\/\w\.-]+)/n).flatten.compact + def project_by_path(path) + if m = /^([\w\.\/-]+)\.git/.match(path).to_a + path_with_namespace = m.last + path_with_namespace.gsub!(/\.wiki$/, '') - # Cleanup grabare from refs - # if push to multiple branches - refs.map do |ref| - ref.gsub(/00.*/, "") + Project.find_with_namespace(path_with_namespace) end end + + def render_not_found + [404, {"Content-Type" => "text/plain"}, ["Not Found"]] + end end end diff --git a/lib/gitlab/backend/grack_helpers.rb b/lib/gitlab/backend/grack_helpers.rb deleted file mode 100644 index cb747fe0137..00000000000 --- a/lib/gitlab/backend/grack_helpers.rb +++ /dev/null @@ -1,28 +0,0 @@ -module Grack - module Helpers - def project_by_path(path) - if m = /^([\w\.\/-]+)\.git/.match(path).to_a - path_with_namespace = m.last - path_with_namespace.gsub!(/\.wiki$/, '') - - Project.find_with_namespace(path_with_namespace) - end - end - - def render_not_found - [404, {"Content-Type" => "text/plain"}, ["Not Found"]] - end - - def can?(object, action, subject) - abilities.allowed?(object, action, subject) - end - - def abilities - @abilities ||= begin - abilities = Six.new - abilities << Ability - abilities - end - end - end -end diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb new file mode 100644 index 00000000000..1ab8f9213a3 --- /dev/null +++ b/lib/gitlab/git_access.rb @@ -0,0 +1,74 @@ +module Gitlab + class GitAccess + DOWNLOAD_COMMANDS = %w{ git-upload-pack git-upload-archive } + PUSH_COMMANDS = %w{ git-receive-pack } + + attr_reader :params, :project, :git_cmd, :user + + def allowed?(actor, cmd, project, ref = nil, oldrev = nil, newrev = nil) + case cmd + when *DOWNLOAD_COMMANDS + if actor.is_a? User + download_allowed?(actor, project) + elsif actor.is_a? DeployKey + actor.projects.include?(project) + elsif actor.is_a? Key + download_allowed?(actor.user, project) + else + raise 'Wrong actor' + end + when *PUSH_COMMANDS + if actor.is_a? User + push_allowed?(actor, project, ref, oldrev, newrev) + elsif actor.is_a? DeployKey + # Deploy key not allowed to push + return false + elsif actor.is_a? Key + push_allowed?(actor.user, project, ref, oldrev, newrev) + else + raise 'Wrong actor' + end + else + false + end + end + + def download_allowed?(user, project) + if user && user_allowed?(user) + user.can?(:download_code, project) + else + false + end + end + + def push_allowed?(user, project, ref, oldrev, newrev) + if user && user_allowed?(user) + action = if project.protected_branch?(ref) + :push_code_to_protected_branches + else + :push_code + end + user.can?(action, project) + else + false + end + end + + private + + def user_allowed?(user) + return false if user.blocked? + + if Gitlab.config.ldap.enabled + if user.ldap_user? + # Check if LDAP user exists and match LDAP user_filter + unless Gitlab::LDAP::Access.new.allowed?(user) + return false + end + end + end + + true + end + end +end diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb index e72f4f5d0ce..de14a3eca27 100644 --- a/lib/gitlab/markdown.rb +++ b/lib/gitlab/markdown.rb @@ -152,7 +152,7 @@ module Gitlab # # Returns boolean def valid_emoji?(emoji) - Emoji.names.include? emoji + Emoji.find_by_name emoji end # Private: Dispatches to a dedicated processing method based on reference @@ -166,8 +166,8 @@ module Gitlab end def reference_user(identifier) - if member = @project.team_members.find { |user| user.username == identifier } - link_to("@#{identifier}", user_url(identifier), html_options.merge(class: "gfm gfm-team_member #{html_options[:class]}")) if member + if user = User.find_by_username(identifier) + link_to("@#{identifier}", user_url(identifier), html_options.merge(class: "gfm gfm-team_member #{html_options[:class]}")) end end diff --git a/lib/gitlab/satellite/satellite.rb b/lib/gitlab/satellite/satellite.rb index bcf3012bd92..bdfcf254e9e 100644 --- a/lib/gitlab/satellite/satellite.rb +++ b/lib/gitlab/satellite/satellite.rb @@ -1,5 +1,9 @@ module Gitlab - class SatelliteNotExistError < StandardError; end + class SatelliteNotExistError < StandardError + def initialize(msg = "Satellite doesn't exist") + super + end + end module Satellite class Satellite @@ -17,14 +21,9 @@ module Gitlab Gitlab::Satellite::Logger.error(message) end - def raise_no_satellite - raise SatelliteNotExistError.new("Satellite doesn't exist") - end - def clear_and_update! - raise_no_satellite unless exists? + raise SatelliteNotExistError unless exists? - File.exists? path @repo = nil clear_working_dir! delete_heads! @@ -55,7 +54,7 @@ module Gitlab # * Changes the current directory to the satellite's working dir # * Yields def lock - raise_no_satellite unless exists? + raise SatelliteNotExistError unless exists? File.open(lock_file, "w+") do |f| begin @@ -77,7 +76,7 @@ module Gitlab end def repo - raise_no_satellite unless exists? + raise SatelliteNotExistError unless exists? @repo ||= Grit::Repo.new(path) end diff --git a/lib/gitlab/upgrader.rb b/lib/gitlab/upgrader.rb index 0fe4888665d..0846359f9b1 100644 --- a/lib/gitlab/upgrader.rb +++ b/lib/gitlab/upgrader.rb @@ -1,3 +1,4 @@ +require_relative "popen" require_relative "version_info" module Gitlab diff --git a/lib/support/init.d/gitlab b/lib/support/init.d/gitlab index c6e570784e0..3dd4465a6d8 100755 --- a/lib/support/init.d/gitlab +++ b/lib/support/init.d/gitlab @@ -40,7 +40,7 @@ test -f /etc/default/gitlab && . /etc/default/gitlab # Switch to the app_user if it is not he/she who is running the script. if [ "$USER" != "$app_user" ]; then - sudo -u "$app_user" -H -i $0 "$@"; exit; + eval su - "$app_user" -c $(echo \")$0 "$@"$(echo \"); exit; fi # Switch to the gitlab path, exit on failure. @@ -131,7 +131,7 @@ check_stale_pids(){ fi fi if [ "$spid" != "0" -a "$sidekiq_status" != "0" ]; then - echo "Removing stale Sidekiq web server pid. This is most likely caused by the Sidekiq crashing the last time it ran." + echo "Removing stale Sidekiq job dispatcher pid. This is most likely caused by Sidekiq crashing the last time it ran." if ! rm "$sidekiq_pid_path"; then echo "Unable to remove stale pid, exiting" exit 1 @@ -149,15 +149,15 @@ exit_if_not_running(){ } ## Starts Unicorn and Sidekiq if they're not running. -start() { +start_gitlab() { check_stale_pids if [ "$web_status" != "0" -a "$sidekiq_status" != "0" ]; then echo -n "Starting both the GitLab Unicorn and Sidekiq" elif [ "$web_status" != "0" ]; then - echo -n "Starting GitLab Sidekiq" - elif [ "$sidekiq_status" != "0" ]; then echo -n "Starting GitLab Unicorn" + elif [ "$sidekiq_status" != "0" ]; then + echo -n "Starting GitLab Sidekiq" fi # Then check if the service is running. If it is: don't start again. @@ -167,7 +167,7 @@ start() { # Remove old socket if it exists rm -f "$socket_path"/gitlab.socket 2>/dev/null # Start the web server - RAILS_ENV=$RAILS_ENV script/web start & + RAILS_ENV=$RAILS_ENV script/web start fi # If sidekiq is already running, don't start it again. @@ -184,15 +184,15 @@ start() { } ## Asks the Unicorn and the Sidekiq if they would be so kind as to stop, if not kills them. -stop() { +stop_gitlab() { exit_if_not_running if [ "$web_status" = "0" -a "$sidekiq_status" = "0" ]; then echo -n "Shutting down both Unicorn and Sidekiq" elif [ "$web_status" = "0" ]; then - echo -n "Shutting down Sidekiq" - elif [ "$sidekiq_status" = "0" ]; then echo -n "Shutting down Unicorn" + elif [ "$sidekiq_status" = "0" ]; then + echo -n "Shutting down Sidekiq" fi # If the Unicorn web server is running, tell it to stop; @@ -246,7 +246,7 @@ print_status() { } ## Tells unicorn to reload it's config and Sidekiq to restart -reload(){ +reload_gitlab(){ exit_if_not_running if [ "$wpid" = "0" ];then echo "The GitLab Unicorn Web server is not running thus its configuration can't be reloaded." @@ -263,12 +263,12 @@ reload(){ } ## Restarts Sidekiq and Unicorn. -restart(){ +restart_gitlab(){ check_status if [ "$web_status" = "0" -o "$sidekiq_status" = "0" ]; then - stop + stop_gitlab fi - start + start_gitlab } @@ -276,16 +276,16 @@ restart(){ case "$1" in start) - start + start_gitlab ;; stop) - stop + stop_gitlab ;; restart) - restart + restart_gitlab ;; reload|force-reload) - reload + reload_gitlab ;; status) print_status diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab index 7a0f3efbb53..5bff362da0e 100644 --- a/lib/support/nginx/gitlab +++ b/lib/support/nginx/gitlab @@ -54,6 +54,14 @@ server { proxy_pass http://gitlab; } + # Enable gzip compression as per rails guide: http://guides.rubyonrails.org/asset_pipeline.html#gzip-compression + location ~ ^/(assets)/ { + root /home/git/gitlab/public; + gzip_static on; # to serve pre-gzipped version + expires max; + add_header Cache-Control public; + } + error_page 502 /502.html; } diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index d4d5e48ce3f..3b9b2531bf7 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -677,7 +677,20 @@ namespace :gitlab do end def filter - Net::LDAP::Filter.present?(ldap_config.uid) + uid_filter = Net::LDAP::Filter.present?(ldap_config.uid) + if user_filter + Net::LDAP::Filter.join(uid_filter, user_filter) + else + uid_filter + end + end + + def user_filter + if ldap_config['user_filter'] && ldap_config.user_filter.present? + Net::LDAP::Filter.construct(ldap_config.user_filter) + else + nil + end end def ldap @@ -742,7 +755,7 @@ namespace :gitlab do end def check_gitlab_shell - required_version = Gitlab::VersionInfo.new(1, 8, 5) + required_version = Gitlab::VersionInfo.new(1, 9, 1) current_version = Gitlab::VersionInfo.parse(gitlab_shell_version) print "GitLab Shell version >= #{required_version} ? ... " |