diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/api/api.rb | 3 | ||||
-rw-r--r-- | lib/api/commits.rb | 64 | ||||
-rw-r--r-- | lib/api/entities.rb | 27 | ||||
-rw-r--r-- | lib/api/files.rb | 53 | ||||
-rw-r--r-- | lib/api/internal.rb | 4 | ||||
-rw-r--r-- | lib/api/merge_requests.rb | 2 | ||||
-rw-r--r-- | lib/api/projects.rb | 14 | ||||
-rw-r--r-- | lib/api/repositories.rb | 61 | ||||
-rw-r--r-- | lib/extracts_path.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/popen.rb | 6 | ||||
-rw-r--r-- | lib/redcarpet/render/gitlab_html.rb | 21 | ||||
-rw-r--r-- | lib/support/nginx/gitlab | 2 | ||||
-rw-r--r-- | lib/tasks/gitlab/bulk_add_permission.rake | 24 | ||||
-rw-r--r-- | lib/tasks/gitlab/check.rake | 48 |
14 files changed, 214 insertions, 117 deletions
diff --git a/lib/api/api.rb b/lib/api/api.rb index 283f7642f67..6bec8368b12 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -22,6 +22,8 @@ module API end format :json + content_type :txt, "text/plain" + helpers APIHelpers mount Groups @@ -40,6 +42,7 @@ module API mount ProjectHooks mount Services mount Files + mount Commits mount Namespaces end end diff --git a/lib/api/commits.rb b/lib/api/commits.rb new file mode 100644 index 00000000000..33b8b3d2244 --- /dev/null +++ b/lib/api/commits.rb @@ -0,0 +1,64 @@ +require 'mime/types' + +module API + # Projects API + class Commits < Grape::API + before { authenticate! } + before { authorize! :download_code, user_project } + + resource :projects do + helpers do + def handle_project_member_errors(errors) + if errors[:project_access].any? + error!(errors[:project_access], 422) + end + not_found! + end + end + + # Get a project repository commits + # + # Parameters: + # id (required) - The ID of a project + # ref_name (optional) - The name of a repository branch or tag, if not given the default branch is used + # Example Request: + # GET /projects/:id/repository/commits + get ":id/repository/commits" do + page = (params[:page] || 0).to_i + per_page = (params[:per_page] || 20).to_i + ref = params[:ref_name] || user_project.try(:default_branch) || 'master' + + commits = user_project.repository.commits(ref, nil, per_page, page * per_page) + present commits, with: Entities::RepoCommit + end + + # Get a specific commit of a project + # + # Parameters: + # id (required) - The ID of a project + # sha (required) - The commit hash or name of a repository branch or tag + # Example Request: + # GET /projects/:id/repository/commits/:sha + get ":id/repository/commits/:sha" do + sha = params[:sha] + commit = user_project.repository.commit(sha) + not_found! "Commit" unless commit + present commit, with: Entities::RepoCommitDetail + end + + # Get the diff for a specific commit of a project + # + # Parameters: + # id (required) - The ID of a project + # sha (required) - The commit or branch name + # Example Request: + # GET /projects/:id/repository/commits/:sha/diff + get ":id/repository/commits/:sha/diff" do + sha = params[:sha] + commit = user_project.repository.commit(sha) + not_found! "Commit" unless commit + commit.diffs + end + end + end +end diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 4f636fc54a3..8557fa074d4 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -6,6 +6,12 @@ module API expose :is_admin?, as: :is_admin expose :can_create_group?, as: :can_create_group expose :can_create_project?, as: :can_create_project + + expose :avatar_url do |user, options| + if user.avatar.present? + user.avatar.url + end + end end class UserSafe < Grape::Entity @@ -79,7 +85,16 @@ module API end class RepoObject < Grape::Entity - expose :name, :commit + expose :name + + expose :commit do |repo_obj, options| + if repo_obj.respond_to?(:commit) + repo_obj.commit + elsif options[:project] + options[:project].repository.commit(repo_obj.target) + end + end + expose :protected do |repo, options| if options[:project] options[:project].protected_branch? repo.name @@ -87,6 +102,16 @@ module API end end + class RepoTreeObject < Grape::Entity + expose :id, :name, :type + + expose :mode do |obj, options| + filemode = obj.mode.to_s(8) + filemode = "0" + filemode if filemode.length < 6 + filemode + end + end + class RepoCommit < Grape::Entity expose :id, :short_id, :title, :author_name, :author_email, :created_at end diff --git a/lib/api/files.rb b/lib/api/files.rb index 213604915a6..e0c46f92b84 100644 --- a/lib/api/files.rb +++ b/lib/api/files.rb @@ -5,10 +5,61 @@ module API before { authorize! :push_code, user_project } resource :projects do + # Get file from repository + # File content is Base64 encoded + # + # Parameters: + # file_path (required) - The path to the file. Ex. lib/class.rb + # ref (required) - The name of branch, tag or commit + # + # Example Request: + # GET /projects/:id/repository/files + # + # Example response: + # { + # "file_name": "key.rb", + # "file_path": "app/models/key.rb", + # "size": 1476, + # "encoding": "base64", + # "content": "IyA9PSBTY2hlbWEgSW5mb3...", + # "ref": "master", + # "blob_id": "79f7bbd25901e8334750839545a9bd021f0e4c83", + # "commit_id": "d5a3ff139356ce33e37e73add446f16869741b50" + # } + # + get ":id/repository/files" do + required_attributes! [:file_path, :ref] + attrs = attributes_for_keys [:file_path, :ref] + ref = attrs.delete(:ref) + file_path = attrs.delete(:file_path) + + commit = user_project.repository.commit(ref) + not_found! "Commit" unless commit + + blob = user_project.repository.blob_at(commit.sha, file_path) + + if blob + status(200) + + { + file_name: blob.name, + file_path: blob.path, + size: blob.size, + encoding: "base64", + content: Base64.encode64(blob.data), + ref: ref, + blob_id: blob.id, + commit_id: commit.id, + } + else + render_api_error!('File not found', 404) + end + end + # Create new file in repository # # Parameters: - # file_path (optional) - The path to new file. Ex. lib/class.rb + # file_path (required) - The path to new file. Ex. lib/class.rb # branch_name (required) - The name of branch # content (required) - File content # commit_message (required) - Commit message diff --git a/lib/api/internal.rb b/lib/api/internal.rb index ed6b50c3a6a..ebc9fef07b4 100644 --- a/lib/api/internal.rb +++ b/lib/api/internal.rb @@ -35,7 +35,9 @@ module API user = key.user return false if user.blocked? - return false if user.ldap_user? && Gitlab::LDAP::User.blocked?(user.extern_uid) + if Gitlab.config.ldap.enabled + return false if user.ldap_user? && Gitlab::LDAP::User.blocked?(user.extern_uid) + end action = case git_cmd when *DOWNLOAD_COMMANDS diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 0f62cac9a0c..58d2f79faff 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -116,8 +116,6 @@ module API authorize! :modify_merge_request, merge_request if merge_request.update_attributes attrs - merge_request.reload_code - merge_request.mark_as_unchecked present merge_request, with: Entities::MergeRequest else handle_merge_request_errors! merge_request.errors diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 888aa7e77d2..bcca69ff49a 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -11,7 +11,7 @@ module API end not_found! end - + def map_public_to_visibility_level(attrs) publik = attrs.delete(:public) publik = [ true, 1, '1', 't', 'T', 'true', 'TRUE', 'on', 'ON' ].include?(publik) @@ -308,6 +308,18 @@ module API projects = Project.where("(id in (?) OR visibility_level in (?)) AND (name LIKE (?))", ids, visibility_levels, "%#{params[:query]}%") present paginate(projects), with: Entities::Project end + + + # Get a users list + # + # Example Request: + # GET /users + get ':id/users' do + @users = User.where(id: user_project.team.users.map(&:id)) + @users = @users.search(params[:search]) if params[:search].present? + @users = paginate @users + present @users, with: Entities::User + end end end end diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb index 878929b8032..ba53bf9baa4 100644 --- a/lib/api/repositories.rb +++ b/lib/api/repositories.rb @@ -82,51 +82,7 @@ module API # Example Request: # GET /projects/:id/repository/tags get ":id/repository/tags" do - present user_project.repo.tags.sort_by(&:name).reverse, with: Entities::RepoObject - end - - # Get a project repository commits - # - # Parameters: - # id (required) - The ID of a project - # ref_name (optional) - The name of a repository branch or tag, if not given the default branch is used - # Example Request: - # GET /projects/:id/repository/commits - get ":id/repository/commits" do - page = (params[:page] || 0).to_i - per_page = (params[:per_page] || 20).to_i - ref = params[:ref_name] || user_project.try(:default_branch) || 'master' - - commits = user_project.repository.commits(ref, nil, per_page, page * per_page) - present commits, with: Entities::RepoCommit - end - - # Get a specific commit of a project - # - # Parameters: - # id (required) - The ID of a project - # sha (required) - The commit hash or name of a repository branch or tag - # Example Request: - # GET /projects/:id/repository/commits/:sha - get ":id/repository/commits/:sha" do - sha = params[:sha] - commit = user_project.repository.commit(sha) - not_found! "Commit" unless commit - present commit, with: Entities::RepoCommitDetail - end - - # Get the diff for a specific commit of a project - # - # Parameters: - # id (required) - The ID of a project - # sha (required) - The commit or branch name - # Example Request: - # GET /projects/:id/repository/commits/:sha/diff - get ":id/repository/commits/:sha/diff" do - sha = params[:sha] - commit = user_project.repository.commit(sha) - not_found! "Commit" unless commit - commit.diffs + present user_project.repo.tags.sort_by(&:name).reverse, with: Entities::RepoObject, project: user_project end # Get a project repository tree @@ -141,15 +97,9 @@ module API path = params[:path] || nil commit = user_project.repository.commit(ref) - tree = Tree.new(user_project.repository, commit.id, path) + tree = user_project.repository.tree(commit.id, path) - trees = [] - - %w(trees blobs submodules).each do |type| - trees += tree.send(type).map { |t| {name: t.name, type: type.singularize, mode: t.mode, id: t.id} } - end - - trees + present tree.sorted_entries, with: Entities::RepoTreeObject end # Get a raw file contents @@ -173,9 +123,7 @@ module API blob = Gitlab::Git::Blob.find(repo, commit.id, params[:filepath]) not_found! "File" unless blob - env['api.format'] = :txt - - content_type blob.mime_type + content_type 'text/plain' present blob.data end @@ -233,4 +181,3 @@ module API end end end - diff --git a/lib/extracts_path.rb b/lib/extracts_path.rb index 6e7872dcd03..e51cb30bdd9 100644 --- a/lib/extracts_path.rb +++ b/lib/extracts_path.rb @@ -117,7 +117,7 @@ module ExtractsPath end def tree - @tree ||= Tree.new(@repo, @commit.id, @path) + @tree ||= @repo.tree(@commit.id, @path) end private diff --git a/lib/gitlab/popen.rb b/lib/gitlab/popen.rb index 2f30fde2078..5283cf0b821 100644 --- a/lib/gitlab/popen.rb +++ b/lib/gitlab/popen.rb @@ -1,9 +1,15 @@ +require 'fileutils' + module Gitlab module Popen def popen(cmd, path) vars = { "PWD" => path } options = { chdir: path } + unless File.directory?(path) + FileUtils.mkdir_p(path) + end + @cmd_output = "" @cmd_status = 0 Open3.popen3(vars, cmd, options) do |stdin, stdout, stderr, wait_thr| diff --git a/lib/redcarpet/render/gitlab_html.rb b/lib/redcarpet/render/gitlab_html.rb index 2d1e0aec5e5..42f6316910a 100644 --- a/lib/redcarpet/render/gitlab_html.rb +++ b/lib/redcarpet/render/gitlab_html.rb @@ -8,14 +8,11 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML @project = @template.instance_variable_get("@project") @ref = @template.instance_variable_get("@ref") @request_path = @template.instance_variable_get("@path") + @options = options.dup super options end def block_code(code, language) - options = { options: {encoding: 'utf-8'} } - lexer = Pygments::Lexer.find(language) # language can be an alias - options.merge!(lexer: lexer.aliases[0].downcase) if lexer # downcase is required - # New lines are placed to fix an rendering issue # with code wrapped inside <h1> tag for next case: # @@ -25,7 +22,11 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML # <<-HTML - <div class="#{h.user_color_scheme_class}">#{Pygments.highlight(code, options)}</div> +<div class="highlighted-data #{h.user_color_scheme_class}"> + <div class="highlight"> + <pre><code class="#{language}">#{code}</code></pre> + </div> +</div> HTML end @@ -34,6 +35,16 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML h.link_to_gfm(content, link, title: title) end + def header(text, level) + if @options[:no_header_anchors] + "<h#{level}>#{text}</h#{level}>" + else + id = ActionController::Base.helpers.strip_tags(h.gfm(text)).downcase() \ + .gsub(/[^a-z0-9_-]/, '-').gsub(/-+/, '-').gsub(/^-/, '').gsub(/-$/, '') + "<h#{level} id=\"#{id}\">#{text}<a href=\"\##{id}\"></a></h#{level}>" + end + end + def preprocess(full_document) if @project h.create_relative_links(full_document, @project, @ref, @request_path, is_wiki?) diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab index 0860d2a8693..882f0386046 100644 --- a/lib/support/nginx/gitlab +++ b/lib/support/nginx/gitlab @@ -53,5 +53,7 @@ server { proxy_pass http://gitlab; } + + error_page 502 /502.html; } diff --git a/lib/tasks/gitlab/bulk_add_permission.rake b/lib/tasks/gitlab/bulk_add_permission.rake index 612a9ba93a8..0e1a3d071e9 100644 --- a/lib/tasks/gitlab/bulk_add_permission.rake +++ b/lib/tasks/gitlab/bulk_add_permission.rake @@ -20,5 +20,29 @@ namespace :gitlab do puts "Importing #{user.email} users into #{project_ids.size} projects" UsersProject.add_users_into_projects(project_ids, Array.wrap(user.id), UsersProject::DEVELOPER) end + + desc "GITLAB | Add all users to all groups (admin users are added as owners)" + task all_users_to_all_groups: :environment do |t, args| + user_ids = User.where(admin: false).pluck(:id) + admin_ids = User.where(admin: true).pluck(:id) + groups = Group.all + + puts "Importing #{user_ids.size} users into #{groups.size} groups" + puts "Importing #{admin_ids.size} admins into #{groups.size} groups" + groups.each do |group| + group.add_users(user_ids, UsersGroup::DEVELOPER) + group.add_users(admin_ids, UsersGroup::OWNER) + end + end + + desc "GITLAB | Add a specific user to all groups (as a developer)" + task :user_to_groups, [:email] => :environment do |t, args| + user = User.find_by_email args.email + groups = Group.all + puts "Importing #{user.email} users into #{groups.size} groups" + groups.each do |group| + group.add_users(Array.wrap(user.id), UsersGroup::DEVELOPER) + end + end end end diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index f48d26433c0..c91dedf74c7 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -279,8 +279,6 @@ namespace :gitlab do start_checking "Environment" check_gitlab_git_config - check_python2_exists - check_python2_version finished_checking "Environment" end @@ -314,52 +312,6 @@ namespace :gitlab do fix_and_rerun end end - - def check_python2_exists - print "Has python2? ... " - - # Python prints its version to STDERR - # so we can't just use run("python2 --version") - if run_and_match("which python2", /python2$/) - puts "yes".green - else - puts "no".red - try_fixing_it( - "Make sure you have Python 2.5+ installed", - "Link it to python2" - ) - for_more_information( - see_installation_guide_section "Packages / Dependencies" - ) - fix_and_rerun - end - end - - def check_python2_version - print "python2 is supported version? ... " - - # Python prints its version to STDERR - # so we can't just use run("python2 --version") - - unless run_and_match("which python2", /python2$/) - puts "can't check because of previous errors".magenta - return - end - - if `python2 --version 2>&1` =~ /2\.[567]\.\d/ - puts "yes".green - else - puts "no".red - try_fixing_it( - "Make sure you have Python 2.5+ installed", - "Link it to python2" - ) - for_more_information( - see_installation_guide_section "Packages / Dependencies" - ) - fix_and_rerun - end - end end |