From 6c9f527b3f3f0c47438e0722792ca247a44e4964 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Thu, 16 Jul 2015 22:33:58 -0700 Subject: [PATCH 01/79] Return comments in created order in merge request API Closes #1832 --- CHANGELOG | 1 + lib/api/merge_requests.rb | 2 +- spec/requests/api/merge_requests_spec.rb | 6 ++++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 12564b3bb5..dbd3975095 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 7.13.0 (unreleased) + - Return comments in created order in merge request API (Stan Hu) - Only enable HSTS header for HTTPS and port 443 (Stan Hu) - Fix user autocomplete for unauthenticated users accessing public projects (Stan Hu) - Fix redirection to home page URL for unauthorized users (Daniel Gerhardt) diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index aa43e1dffd..ce21c699e8 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -229,7 +229,7 @@ module API authorize! :read_merge_request, merge_request - present paginate(merge_request.notes), with: Entities::MRNote + present paginate(merge_request.notes.fresh), with: Entities::MRNote end # Post comment to merge request diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb index 7030c105b5..29db035b2d 100644 --- a/spec/requests/api/merge_requests_spec.rb +++ b/spec/requests/api/merge_requests_spec.rb @@ -8,6 +8,7 @@ describe API::API, api: true do let!(:merge_request_closed) { create(:merge_request, state: "closed", author: user, assignee: user, source_project: project, target_project: project, title: "Closed test") } let!(:merge_request_merged) { create(:merge_request, state: "merged", author: user, assignee: user, source_project: project, target_project: project, title: "Merged test") } let!(:note) { create(:note_on_merge_request, author: user, project: project, noteable: merge_request, note: "a comment on a MR") } + let!(:note2) { create(:note_on_merge_request, author: user, project: project, noteable: merge_request, note: "another comment on a MR") } before do project.team << [user, :reporters] @@ -397,13 +398,14 @@ describe API::API, api: true do end describe "GET :id/merge_request/:merge_request_id/comments" do - it "should return merge_request comments" do + it "should return merge_request comments ordered by created_at" do get api("/projects/#{project.id}/merge_request/#{merge_request.id}/comments", user) expect(response.status).to eq(200) expect(json_response).to be_an Array - expect(json_response.length).to eq(1) + expect(json_response.length).to eq(2) expect(json_response.first['note']).to eq("a comment on a MR") expect(json_response.first['author']['id']).to eq(user.id) + expect(json_response.last['note']).to eq("another comment on a MR") end it "should return a 404 error if merge_request_id not found" do From a364d4260d357c10d45108da8f8ab55426c64fa2 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Sat, 18 Jul 2015 17:54:56 -0400 Subject: [PATCH 02/79] Make username parameter for Users#show case-insensitive Closes #2012 --- app/controllers/users_controller.rb | 2 +- spec/controllers/users_controller_spec.rb | 35 ++++++++++++++++------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 2bb5c338cf..a67325ae65 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -50,7 +50,7 @@ class UsersController < ApplicationController private def set_user - @user = User.find_by_username!(params[:username]) + @user = User.find_by!('lower(username) = ?', params[:username].downcase) unless current_user || @user.public_profile? return authenticate_user! diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index d47a37914d..9f89101d7f 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -1,25 +1,38 @@ require 'spec_helper' describe UsersController do - let(:user) { create(:user, username: 'user1', name: 'User 1', email: 'user1@gitlab.com') } - - before do - sign_in(user) - end + let(:user) { create(:user) } describe 'GET #show' do - render_views + it 'is case-insensitive' do + user = create(:user, username: 'CamelCaseUser') + sign_in(user) - it 'renders the show template' do - get :show, username: user.username - expect(response.status).to eq(200) - expect(response).to render_template('show') + get :show, username: user.username.downcase + + expect(response).to be_success + end + + context 'with rendered views' do + render_views + + it 'renders the show template' do + sign_in(user) + + get :show, username: user.username + + expect(response).to be_success + expect(response).to render_template('show') + end end end describe 'GET #calendar' do it 'renders calendar' do + sign_in(user) + get :calendar, username: user.username + expect(response).to render_template('calendar') end end @@ -30,6 +43,8 @@ describe UsersController do before do allow_any_instance_of(User).to receive(:contributed_projects_ids).and_return([project.id]) + + sign_in(user) project.team << [user, :developer] end From aee579eac2389fdf9ec8e3e60f2c8cabeac10f3d Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Wed, 22 Jul 2015 11:31:15 +0200 Subject: [PATCH 03/79] Use mdash to prevent breaking html emails. --- app/views/layouts/notify.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/layouts/notify.html.haml b/app/views/layouts/notify.html.haml index ee1b57278b..c8662a15ad 100644 --- a/app/views/layouts/notify.html.haml +++ b/app/views/layouts/notify.html.haml @@ -33,7 +33,7 @@ = yield %div.footer{style: "margin-top: 10px;"} %p - \— + — %br - if @target_url #{link_to "View it on GitLab", @target_url} From ca451365abc26ede22f9b13482e3120fd61833de Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Wed, 22 Jul 2015 11:46:08 +0200 Subject: [PATCH 04/79] Remove docs and rake task for gmail actions to prevent problems with registration. --- doc/integration/gitlab_actions.png | Bin 17321 -> 0 bytes doc/integration/gitlab_buttons_in_gmail.md | 28 ------- .../mail_google_schema_whitelisting.rake | 73 ------------------ 3 files changed, 101 deletions(-) delete mode 100644 doc/integration/gitlab_actions.png delete mode 100644 doc/integration/gitlab_buttons_in_gmail.md delete mode 100644 lib/tasks/gitlab/mail_google_schema_whitelisting.rake diff --git a/doc/integration/gitlab_actions.png b/doc/integration/gitlab_actions.png deleted file mode 100644 index b08f54d137bd9ab1bde8471211f95016a9ee6aa0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17321 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 - - - - GitLab - - - - - -
-
-

I like it :+1:

-
-
- -
- - " - end - - def send_now - if ENV['SEND'] == "true" - true - else - false - end - end -end From dbff6bc106c679edbd135a69ba74532fabe1e996 Mon Sep 17 00:00:00 2001 From: ngentile Date: Wed, 22 Jul 2015 09:58:17 -0400 Subject: [PATCH 05/79] Gitlab Issue 707: Indent unfolded code 1 character --- app/assets/javascripts/diff.js.coffee | 4 ++++ app/views/projects/blob/diff.html.haml | 2 +- lib/unfold_form.rb | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/diff.js.coffee b/app/assets/javascripts/diff.js.coffee index 069f91c30e..6d9b364cb8 100644 --- a/app/assets/javascripts/diff.js.coffee +++ b/app/assets/javascripts/diff.js.coffee @@ -31,6 +31,10 @@ class @Diff bottom: unfoldBottom offset: offset unfold: unfold + # indent is used to compensate for single space indent to fit + # '+' and '-' prepended to diff lines, + # see https://gitlab.com/gitlab-org/gitlab-ce/issues/707 + indent: 1 $.get(link, params, (response) => target.parent().replaceWith(response) diff --git a/app/views/projects/blob/diff.html.haml b/app/views/projects/blob/diff.html.haml index 8474260898..f3b01ff328 100644 --- a/app/views/projects/blob/diff.html.haml +++ b/app/views/projects/blob/diff.html.haml @@ -11,7 +11,7 @@ %td.old_line.diff-line-num{data: {linenumber: line_old}} = link_to raw(line_old), "#" %td.new_line= link_to raw(line_new) , "#" - %td.line_content.noteable_line= line + %td.line_content.noteable_line= ' ' * @form.indent + line - if @form.unfold? && @form.bottom? && @form.to < @blob.loc %tr.line_holder{ id: @form.to } diff --git a/lib/unfold_form.rb b/lib/unfold_form.rb index 46b12beeaa..fcd01503d1 100644 --- a/lib/unfold_form.rb +++ b/lib/unfold_form.rb @@ -8,4 +8,5 @@ class UnfoldForm attribute :bottom, Boolean attribute :unfold, Boolean, default: true attribute :offset, Integer + attribute :indent, Integer, default: 0 end From 70a3c165a9f3882a82cf8946a783ace091635797 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Thu, 2 Jul 2015 16:33:38 +0200 Subject: [PATCH 06/79] Allow custom label to be set for authentication providers. --- CHANGELOG | 1 + .../bitbucket_64.png | Bin app/assets/images/auth_buttons/github_64.png | Bin 0 -> 2625 bytes app/assets/images/auth_buttons/gitlab_64.png | Bin 0 -> 2849 bytes .../google_64.png | Bin .../twitter_64.png | Bin app/assets/images/authbuttons/github_64.png | Bin 4196 -> 0 bytes app/assets/images/authbuttons/gitlab_64.png | Bin 6559 -> 0 bytes app/controllers/application_controller.rb | 6 +-- .../omniauth_callbacks_controller.rb | 5 +- app/controllers/sessions_controller.rb | 2 +- app/helpers/auth_helper.rb | 50 ++++++++++++++++++ app/helpers/oauth_helper.rb | 34 ------------ app/helpers/profile_helper.rb | 13 ----- app/views/admin/identities/_form.html.haml | 3 +- .../admin/identities/_identity.html.haml | 2 +- app/views/devise/sessions/_new_ldap.html.haml | 2 +- .../devise/shared/_omniauth_box.html.haml | 8 ++- app/views/devise/shared/_signin_box.html.haml | 2 +- app/views/profiles/accounts/show.html.haml | 14 ++--- config/gitlab.yml.example | 25 ++++++--- doc/integration/omniauth.md | 2 +- features/steps/admin/users.rb | 9 +++- lib/gitlab/o_auth/provider.rb | 30 +++++++---- spec/helpers/auth_helper_spec.rb | 20 +++++++ spec/helpers/oauth_helper_spec.rb | 20 ------- 26 files changed, 140 insertions(+), 108 deletions(-) rename app/assets/images/{authbuttons => auth_buttons}/bitbucket_64.png (100%) create mode 100644 app/assets/images/auth_buttons/github_64.png create mode 100644 app/assets/images/auth_buttons/gitlab_64.png rename app/assets/images/{authbuttons => auth_buttons}/google_64.png (100%) rename app/assets/images/{authbuttons => auth_buttons}/twitter_64.png (100%) delete mode 100644 app/assets/images/authbuttons/github_64.png delete mode 100644 app/assets/images/authbuttons/gitlab_64.png create mode 100644 app/helpers/auth_helper.rb delete mode 100644 app/helpers/oauth_helper.rb delete mode 100644 app/helpers/profile_helper.rb create mode 100644 spec/helpers/auth_helper_spec.rb delete mode 100644 spec/helpers/oauth_helper_spec.rb diff --git a/CHANGELOG b/CHANGELOG index c6c5bc0aac..b31ef35254 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -72,6 +72,7 @@ v 7.12.2 - Faster automerge check and merge itself when source and target branches are in same repository - Audit log for user authentication - Fix transferring of project to another group using the API. + - Allow custom label to be set for authentication providers. v 7.12.1 - Fix error when deleting a user who has projects (Stan Hu) diff --git a/app/assets/images/authbuttons/bitbucket_64.png b/app/assets/images/auth_buttons/bitbucket_64.png similarity index 100% rename from app/assets/images/authbuttons/bitbucket_64.png rename to app/assets/images/auth_buttons/bitbucket_64.png diff --git a/app/assets/images/auth_buttons/github_64.png b/app/assets/images/auth_buttons/github_64.png new file mode 100644 index 0000000000000000000000000000000000000000..182a1a3f734fc1b7d712c68b04c29bad9460d6cd GIT binary patch literal 2625 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 literal 0 HcmV?d00001 diff --git a/app/assets/images/authbuttons/google_64.png b/app/assets/images/auth_buttons/google_64.png similarity index 100% rename from app/assets/images/authbuttons/google_64.png rename to app/assets/images/auth_buttons/google_64.png diff --git a/app/assets/images/authbuttons/twitter_64.png b/app/assets/images/auth_buttons/twitter_64.png similarity index 100% rename from app/assets/images/authbuttons/twitter_64.png rename to app/assets/images/auth_buttons/twitter_64.png diff --git a/app/assets/images/authbuttons/github_64.png b/app/assets/images/authbuttons/github_64.png deleted file mode 100644 index dc7c03d10052a596f062207ae0fd8e9cf384b2aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4196 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

X%~0la9wB4oXwju zWm>O7AtSrGx?Jpb0$5Bs!C)}RhQ=msdiu(q=H`|-Hj8EEayWgJMl2SaauZ8PfCdN- z3hY|Dc8wt+F`kVmKsGx;r_q2Rc9+n-y}g+%HaiLc*mvns`qA+i=z4o=3i7ir3>lg@ z#7!(2j3^4#)KoWY-?sVip~FXWfwI)}eUP0LA3f`*gZnZK2E7I$gjA}owv#80>}_jn zDZUREa6gEv`R=<-1pv@6bLNao8jZTG&oh+OYVBUNGW`Mo+*-c;?HYox_xz{*uwJKC zWSu&eQC(G0fDocclBCK@Z&baqXu&D~2psVAHZdVO?eyu)EUVS3LkJ;RXGg<_2MfR2$CczlA@|^R^EK&g;CC-RfRM{oowAO0Q*v^0h`ZRshsWm&SuB>l zurRMmBJrg2`2z97_WKASV6#}7g!rMYQ>RUj=5l%7aQixrBU&*`EEeOju|rgYV}=Ob z-Nh2@5qf9<0IS8)ed%IO9*fCljTo6chQVO4+S^;}zWnm@1KYOmJ_rEP2N@@L!^i7B zF_}z?+vjq2OG!!b#a%mo*wNjs>U@;*K8hkO1VN|}MOht>Qg@2IXMU+0wIJf7K`$1 z*2$yCj~%+8)Abr3!3osEk^v7hEY~a)alWF zegWYCKx=7flz;Z=KM$6c*PL*GtcRAckJtZgN4H98cDh@oQZ|3E`n~VYW}P}nlBBjT z+`3;P>{2S4Uw?gZ<*=lr?$M)1Ym$?b)yc`p>X9QyX-1D4)v|5tmLi+YrhU*=cLa;Q zrKPEC#XEofy13})EGG-4QYlUA|MB5=00?^|_VMMHr`_hp1H8xV+_5#wXfQa#p6uw5 zRxf&K-j|mP^DiNU?0tKL`|MHOkt2tSA|k>o9YiYOcq!(lr4=+cHPsBn>-e!F=k0d8#i>AB zYwNAI-dvLT^OeFngpmCqct1^bbye%MY15hjphqlr@A>e<52|~6b)64r{GDku8jXC- z2k)IbnR)z*qlrT{o6U0c=%KR-af4^wgYomR@zU;xaLQD+ik?ztkbn?*Q`9%-P7Iq7>>{#&LRza_w2g-#b=*f z?d|RDb)FsEtSrx;oHBM90Qfwq!&hHEm+@?I(a)I_McHp7E|YcV_N|vb|JR27dc96| zpOB^yqDYFO2#TTzM~^|>D_BU9H0GQ?m%rxymB-|Ane(i{UQ~4DB$tgp`>4j_kLUos z%}&V=?8`7DB*ck=fK-Mt3}Itsb0Zqb7IU!BZ6ewrjndsS8Ct(ED^KlgAK4jHJq`ELpa0DkkHO?~Im z#he<1C_*liUrC)kX~X4$ON9@5p~7jsR;!gQ{>zL1K7Q;JLeZZO^gW34^?|qvE}H-rQYNQ`K@mCpe8a8V&l5UwnG*?3t4n zEEbb;Z^n+?sHl)M01!AQd3NUDKlUXh8o=n)E8p2Im9}Z6()QZVKilwQds|!m{c63% zV(HnlXJ=N<`Ll(sEzOFxAFSMmW03r~^u!;>pq>H%gB7HguM|}@HP&i}3>g|fC_F-R z{rc64fPg@Ti;IhUzw0HOCR~O{vUM1{yjKkr$ezM{3yMEZZ>stg+>Fo|+F#j)c zfbo}`INJJKO(o@}MRFf6ZwZ&faaVT9Y6Aj-M07esvdH(%M0@Ja@7ijqIcWY zANFToDA?urh00?w{;@gWH$PNz_?bP^#4{$C2?zw}e~{{cDhNt3<1 Rz)t`G002ovPDHLkV1k8$(}Ms2 diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 362b03e0d5..3ce8dbc940 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -299,14 +299,14 @@ class ApplicationController < ActionController::Base end def github_import_enabled? - OauthHelper.enabled_oauth_providers.include?(:github) + Gitlab::OAuth::Provider.enabled?(:github) end def gitlab_import_enabled? - OauthHelper.enabled_oauth_providers.include?(:gitlab) + Gitlab::OAuth::Provider.enabled?(:gitlab) end def bitbucket_import_enabled? - OauthHelper.enabled_oauth_providers.include?(:bitbucket) && Gitlab::BitbucketImport.public_key.present? + Gitlab::OAuth::Provider.enabled?(:bitbucket) && Gitlab::BitbucketImport.public_key.present? end end diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index fd51b380da..523264b8ea 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -72,10 +72,11 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController end end rescue Gitlab::OAuth::SignupDisabledError => e - message = "Signing in using your #{oauth['provider']} account without a pre-existing GitLab account is not allowed." + label = Gitlab::OAuth::Provider.label_for(oauth['provider']) + message = "Signing in using your #{label} account without a pre-existing GitLab account is not allowed." if current_application_settings.signup_enabled? - message << " Create a GitLab account first, and then connect it to your #{oauth['provider']} account." + message << " Create a GitLab account first, and then connect it to your #{label} account." end flash[:notice] = message diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 89629bc058..796cbe4c58 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -90,7 +90,7 @@ class SessionsController < Devise::SessionsController # Prevent alert from popping up on the first page shown after authentication. flash[:alert] = nil - redirect_to omniauth_authorize_path(:user, provider.to_sym) + redirect_to user_omniauth_authorize_path(provider.to_sym) end def valid_otp_attempt?(user) diff --git a/app/helpers/auth_helper.rb b/app/helpers/auth_helper.rb new file mode 100644 index 0000000000..0e7a37b4cc --- /dev/null +++ b/app/helpers/auth_helper.rb @@ -0,0 +1,50 @@ +module AuthHelper + PROVIDERS_WITH_ICONS = %w(twitter github gitlab bitbucket google_oauth2).freeze + FORM_BASED_PROVIDERS = [/\Aldap/, 'kerberos'].freeze + + def ldap_enabled? + Gitlab.config.ldap.enabled + end + + def provider_has_icon?(name) + PROVIDERS_WITH_ICONS.include?(name.to_s) + end + + def auth_providers + Gitlab::OAuth::Provider.providers + end + + def label_for_provider(name) + Gitlab::OAuth::Provider.label_for(name) + end + + def form_based_provider?(name) + FORM_BASED_PROVIDERS.any? { |pattern| pattern === name.to_s } + end + + def form_based_providers + auth_providers.select { |provider| form_based_provider?(provider) } + end + + def button_based_providers + auth_providers.reject { |provider| form_based_provider?(provider) } + end + + def provider_image_tag(provider, size = 64) + label = label_for_provider(provider) + + if provider_has_icon?(provider) + file_name = "#{provider.to_s.split('_').first}_#{size}.png" + + image_tag(image_path("auth_buttons/#{file_name}"), alt: label, title: "Sign in with #{label}") + else + label + end + end + + def auth_active?(provider) + current_user.identities.exists?(provider: provider.to_s) + end + + extend self +end diff --git a/app/helpers/oauth_helper.rb b/app/helpers/oauth_helper.rb deleted file mode 100644 index 2fdca13ed4..0000000000 --- a/app/helpers/oauth_helper.rb +++ /dev/null @@ -1,34 +0,0 @@ -module OauthHelper - def ldap_enabled? - Gitlab.config.ldap.enabled - end - - def default_providers - [:twitter, :github, :gitlab, :bitbucket, :google_oauth2, :ldap] - end - - def enabled_oauth_providers - Devise.omniauth_providers - end - - def enabled_social_providers - enabled_oauth_providers.select do |name| - [:saml, :twitter, :gitlab, :github, :bitbucket, :google_oauth2].include?(name.to_sym) - end - end - - def additional_providers - enabled_oauth_providers.reject{|provider| provider.to_s.starts_with?('ldap')} - end - - def oauth_image_tag(provider, size = 64) - file_name = "#{provider.to_s.split('_').first}_#{size}.png" - image_tag(image_path("authbuttons/#{file_name}"), alt: "Sign in with #{provider.to_s.titleize}") - end - - def oauth_active?(provider) - current_user.identities.exists?(provider: provider.to_s) - end - - extend self -end diff --git a/app/helpers/profile_helper.rb b/app/helpers/profile_helper.rb deleted file mode 100644 index 780c7cd513..0000000000 --- a/app/helpers/profile_helper.rb +++ /dev/null @@ -1,13 +0,0 @@ -module ProfileHelper - def show_profile_username_tab? - current_user.can_change_username? - end - - def show_profile_social_tab? - enabled_social_providers.any? - end - - def show_profile_remove_tab? - signup_enabled? - end -end diff --git a/app/views/admin/identities/_form.html.haml b/app/views/admin/identities/_form.html.haml index 0525552ebf..3a78855822 100644 --- a/app/views/admin/identities/_form.html.haml +++ b/app/views/admin/identities/_form.html.haml @@ -8,7 +8,8 @@ .form-group = f.label :provider, class: 'control-label' .col-sm-10 - = f.select :provider, Gitlab::OAuth::Provider.names, { allow_blank: false }, class: 'form-control' + - values = Gitlab::OAuth::Provider.providers.map { |name| ["#{Gitlab::OAuth::Provider.label_for(name)} (#{name})", name] } + = f.select :provider, values, { allow_blank: false }, class: 'form-control' .form-group = f.label :extern_uid, "Identifier", class: 'control-label' .col-sm-10 diff --git a/app/views/admin/identities/_identity.html.haml b/app/views/admin/identities/_identity.html.haml index 671c4fbc67..7362d904b9 100644 --- a/app/views/admin/identities/_identity.html.haml +++ b/app/views/admin/identities/_identity.html.haml @@ -1,6 +1,6 @@ %tr %td - = identity.provider + = "#{Gitlab::OAuth::Provider.label_for(identity.provider)} (#{identity.provider})" %td = identity.extern_uid %td diff --git a/app/views/devise/sessions/_new_ldap.html.haml b/app/views/devise/sessions/_new_ldap.html.haml index 6ec741e488..689cd6ed66 100644 --- a/app/views/devise/sessions/_new_ldap.html.haml +++ b/app/views/devise/sessions/_new_ldap.html.haml @@ -6,4 +6,4 @@ %label{for: "remember_me"} = check_box_tag :remember_me, '1', false, id: 'remember_me' %span Remember me - = button_tag "#{server['label']} Sign in", class: "btn-save btn" + = button_tag "Sign in", class: "btn-save btn" diff --git a/app/views/devise/shared/_omniauth_box.html.haml b/app/views/devise/shared/_omniauth_box.html.haml index f8ba9d80ae..ecf680e7b2 100644 --- a/app/views/devise/shared/_omniauth_box.html.haml +++ b/app/views/devise/shared/_omniauth_box.html.haml @@ -1,10 +1,8 @@ %p %span.light Sign in with   - - providers = additional_providers + - providers = button_based_providers - providers.each do |provider| %span.light - - if default_providers.include?(provider) - = link_to oauth_image_tag(provider), omniauth_authorize_path(resource_name, provider), method: :post, class: 'oauth-image-link' - - else - = link_to provider.to_s.titleize, omniauth_authorize_path(resource_name, provider), method: :post, class: "btn", "data-no-turbolink" => "true" + - has_icon = provider_has_icon?(provider) + = link_to provider_image_tag(provider), user_omniauth_authorize_path(provider), method: :post, class: (has_icon ? 'oauth-image-link' : 'btn'), "data-no-turbolink" => "true" diff --git a/app/views/devise/shared/_signin_box.html.haml b/app/views/devise/shared/_signin_box.html.haml index c76574db45..bb5e479697 100644 --- a/app/views/devise/shared/_signin_box.html.haml +++ b/app/views/devise/shared/_signin_box.html.haml @@ -6,7 +6,7 @@ .login-heading %h3 Sign in .login-body - - if ldap_enabled? + - if form_based_providers.any? %ul.nav.nav-tabs - @ldap_servers.each_with_index do |server, i| %li{class: (:active if i.zero?)} diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml index 378dfa2dce..767fe2e0e9 100644 --- a/app/views/profiles/accounts/show.html.haml +++ b/app/views/profiles/accounts/show.html.haml @@ -59,22 +59,22 @@ %div = link_to 'Enable Two-factor Authentication', new_profile_two_factor_auth_path, class: 'btn btn-success' - - if show_profile_social_tab? + - if button_based_providers.any? .panel.panel-default .panel-heading Connected Accounts .panel-body .oauth-buttons.append-bottom-10 %p Click on icon to activate signin with one of the following services - - enabled_social_providers.each do |provider| + - button_based_providers.each do |provider| .btn-group - = link_to oauth_image_tag(provider), omniauth_authorize_path(User, provider), - method: :post, class: "btn btn-lg #{'active' if oauth_active?(provider)}" - - if oauth_active?(provider) + = link_to provider_image_tag(provider), user_omniauth_authorize_path(provider), method: :post, class: "btn btn-lg #{'active' if auth_active?(provider)}", "data-no-turbolink" => "true" + + - if auth_active?(provider) = link_to unlink_profile_account_path(provider: provider), method: :delete, class: 'btn btn-lg' do = icon('close') - - if show_profile_username_tab? + - if current_user.can_change_username? .panel.panel-warning.update-username .panel-heading Change Username @@ -94,7 +94,7 @@ %div = f.submit 'Save username', class: "btn btn-warning" - - if show_profile_remove_tab? + - if signup_enabled? .panel.panel-danger.remove-account .panel-heading Remove account diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index c32ac2042d..41a01e7703 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -209,20 +209,29 @@ production: &base # arguments, followed by optional 'args' which can be either a hash or an array. # Documentation for this is available at http://doc.gitlab.com/ce/integration/omniauth.html providers: - # - { name: 'google_oauth2', app_id: 'YOUR_APP_ID', + # - { name: 'google_oauth2', + # label: 'Google', + # app_id: 'YOUR_APP_ID', # app_secret: 'YOUR_APP_SECRET', # args: { access_type: 'offline', approval_prompt: '' } } - # - { name: 'twitter', app_id: 'YOUR_APP_ID', - # app_secret: 'YOUR_APP_SECRET'} - # - { name: 'github', app_id: 'YOUR_APP_ID', + # - { name: 'twitter', + # app_id: 'YOUR_APP_ID', + # app_secret: 'YOUR_APP_SECRET' } + # - { name: 'github', + # label: 'GitHub', + # app_id: 'YOUR_APP_ID', # app_secret: 'YOUR_APP_SECRET', # args: { scope: 'user:email' } } - # - { name: 'gitlab', app_id: 'YOUR_APP_ID', + # - { name: 'gitlab', + # label: 'GitLab.com', + # app_id: 'YOUR_APP_ID', # app_secret: 'YOUR_APP_SECRET', # args: { scope: 'api' } } - # - { name: 'bitbucket', app_id: 'YOUR_APP_ID', - # app_secret: 'YOUR_APP_SECRET'} - # - { name: 'saml', + # - { name: 'bitbucket', + # app_id: 'YOUR_APP_ID', + # app_secret: 'YOUR_APP_SECRET' } + # - { name: 'saml', + # label: 'Our SAML Provider', # args: { # assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback', # idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8', diff --git a/doc/integration/omniauth.md b/doc/integration/omniauth.md index 8e2a602ec3..2010cb9b8a 100644 --- a/doc/integration/omniauth.md +++ b/doc/integration/omniauth.md @@ -84,7 +84,7 @@ Existing users can enable OmniAuth for specific providers after the account is c 1. Sign in normally - whether standard sign in, LDAP, or another OmniAuth provider. 1. Go to profile settings (the silhouette icon in the top right corner). 1. Select the "Account" tab. -1. Under "Social Accounts" select the desired OmniAuth provider, such as Twitter. +1. Under "Connected Accounts" select the desired OmniAuth provider, such as Twitter. 1. The user will be redirected to the provider. Once the user authorized GitLab they will be redirected back to GitLab. The chosen OmniAuth provider is now active and can be used to sign in to GitLab from then on. diff --git a/features/steps/admin/users.rb b/features/steps/admin/users.rb index 6c4b91586d..49e64eeff7 100644 --- a/features/steps/admin/users.rb +++ b/features/steps/admin/users.rb @@ -3,6 +3,14 @@ class Spinach::Features::AdminUsers < Spinach::FeatureSteps include SharedPaths include SharedAdmin + before do + allow(Devise).to receive(:omniauth_providers).and_return([:twitter, :twitter_updated]) + end + + after do + allow(Devise).to receive(:omniauth_providers).and_call_original + end + step 'I should see all users' do User.all.each do |user| expect(page).to have_content user.name @@ -121,7 +129,6 @@ class Spinach::Features::AdminUsers < Spinach::FeatureSteps end step 'I visit "Pete" identities page in admin' do - allow(Gitlab::OAuth::Provider).to receive(:names).and_return(%w(twitter twitter_updated)) visit admin_user_identities_path(@user) end diff --git a/lib/gitlab/o_auth/provider.rb b/lib/gitlab/o_auth/provider.rb index f986499a27..90c3fe8da3 100644 --- a/lib/gitlab/o_auth/provider.rb +++ b/lib/gitlab/o_auth/provider.rb @@ -1,18 +1,30 @@ module Gitlab module OAuth class Provider - def self.names - providers = [] + def self.providers + Devise.omniauth_providers + end - Gitlab.config.ldap.servers.values.each do |server| - providers << server['provider_name'] + def self.enabled?(name) + providers.include?(name.to_sym) + end + + def self.ldap_provider?(name) + name.to_s.start_with?('ldap') + end + + def self.config_for(name) + name = name.to_s + if ldap_provider?(name) + Gitlab::LDAP::Config.new(name).options + else + Gitlab.config.omniauth.providers.find { |provider| provider.name == name } end + end - Gitlab.config.omniauth.providers.each do |provider| - providers << provider['name'] - end - - providers + def self.label_for(name) + config = config_for(name) + (config && config['label']) || name.to_s.titleize end end end diff --git a/spec/helpers/auth_helper_spec.rb b/spec/helpers/auth_helper_spec.rb new file mode 100644 index 0000000000..e47a54fdac --- /dev/null +++ b/spec/helpers/auth_helper_spec.rb @@ -0,0 +1,20 @@ +require "spec_helper" + +describe AuthHelper do + describe "button_based_providers" do + it 'returns all enabled providers' do + allow(helper).to receive(:auth_providers) { [:twitter, :github] } + expect(helper.button_based_providers).to include(*[:twitter, :github]) + end + + it 'does not return ldap provider' do + allow(helper).to receive(:auth_providers) { [:twitter, :ldapmain] } + expect(helper.button_based_providers).to include(:twitter) + end + + it 'returns empty array' do + allow(helper).to receive(:auth_providers) { [] } + expect(helper.button_based_providers).to eq([]) + end + end +end diff --git a/spec/helpers/oauth_helper_spec.rb b/spec/helpers/oauth_helper_spec.rb deleted file mode 100644 index 3ef35f3510..0000000000 --- a/spec/helpers/oauth_helper_spec.rb +++ /dev/null @@ -1,20 +0,0 @@ -require "spec_helper" - -describe OauthHelper do - describe "additional_providers" do - it 'returns all enabled providers' do - allow(helper).to receive(:enabled_oauth_providers) { [:twitter, :github] } - expect(helper.additional_providers).to include(*[:twitter, :github]) - end - - it 'does not return ldap provider' do - allow(helper).to receive(:enabled_oauth_providers) { [:twitter, :ldapmain] } - expect(helper.additional_providers).to include(:twitter) - end - - it 'returns empty array' do - allow(helper).to receive(:enabled_oauth_providers) { [] } - expect(helper.additional_providers).to eq([]) - end - end -end From f6ba8c41e23e449da52c019b7faf3e07a33bd9d7 Mon Sep 17 00:00:00 2001 From: Sytse Sijbrandij Date: Thu, 23 Jul 2015 14:47:15 +0000 Subject: [PATCH 07/79] Clarify some things in monthly.md --- doc/release/monthly.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/release/monthly.md b/doc/release/monthly.md index ca9696e957..552b24195b 100644 --- a/doc/release/monthly.md +++ b/doc/release/monthly.md @@ -68,7 +68,7 @@ Xth: (2 working days before the 22nd) Xth: (1 working day before the 22nd) - [ ] Merge CE stable into EE stable -- [ ] Create (hopefully final) CE, EE, CI release candidates (#LINK) +- [ ] Create CE, EE, CI release candidates (#LINK) (hopefully final ones with the same commit as the release tomorrow) - [ ] Create Omnibus tags and build packages for the latest release candidates - [ ] Update GitLab.com with the latest RC (#LINK) - [ ] Update ci.gitLab.com with the latest RC (#LINK) @@ -81,10 +81,10 @@ workday to quickly fix any issues. - [ ] Merge CE stable into EE stable (#LINK) - [ ] Create the 'x.y.0' tag with the [release tools](https://dev.gitlab.org/gitlab/release-tools) (#LINK) -- [ ] BEFORE 11AM CET Create and push omnibus tags for x.y.0 (will auto-release the packages) (#LINK) -- [ ] BEFORE 12AM CET Publish the release blog post (#LINK) +- [ ] Try to do before 11AM CET: Create and push omnibus tags for x.y.0 (will auto-release the packages) (#LINK) +- [ ] Try to do before 12AM CET: Publish the release blog post (#LINK) - [ ] Tweet about the release (blog post) (#LINK) -- [ ] Schedule a second tweet of the release announcement at 6PM CET / 9AM PST +- [ ] Schedule a second tweet of the release announcement with the same text at 6PM CET / 9AM PST ``` @@ -220,4 +220,4 @@ Consider creating a post on Hacker News. ## Create a WIP blogpost for the next release -Create a WIP blogpost using [release blog template](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/doc/release_blog_template.md). +Create a WIP blogpost using [release blog template](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/doc/release_blog_template.md). \ No newline at end of file From 01d29ae66127845df42b3dcb915162b3def71f61 Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Thu, 23 Jul 2015 15:12:44 +0000 Subject: [PATCH 08/79] update changelog1 --- CHANGELOG | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index c6c5bc0aac..10c755403e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -14,8 +14,14 @@ v 7.14.0 (unreleased) - Fix bug causing "Remove source-branch" option not to work for merge requests from the same project. v 7.13.1 - - Revert issue caching - - Reverted cache for events + - Fix: Label modifications are not reflected in existing notes and in the issue list + - Fix: Label not shown in the Issue list, although it's set through web interface + - Fix: Group/project references are linked incorrectly + - Improve documentation + - Fix of migration: Check if session_expire_delay column exists before adding the column + - Fix: ActionView::Template::Error + - Fix: "Create Merge Request" isn't always shown in event for newly pushed branch + - Fix bug causing "Remove source-branch" option not to work for merge requests from the same project. v 7.13.0 (unreleased) - Remove repository graph log to fix slow cache updates after push event (Stan Hu) @@ -1594,4 +1600,4 @@ v 0.8.0 - stability - security fixes - increased test coverage - - email notification + - email notification \ No newline at end of file From 2e5be9c9942fc6f8e20bb76a6daa73a6acf48d51 Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Thu, 23 Jul 2015 15:13:47 +0000 Subject: [PATCH 09/79] update changelog --- CHANGELOG | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 10c755403e..9371877dcb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -10,8 +10,7 @@ v 7.14.0 (unreleased) - Set OmniAuth full_host parameter to ensure redirect URIs are correct (Stan Hu) - Expire Rails cache entries after two weeks to prevent endless Redis growth - Add support for destroying project milestones (Stan Hu) - - Add fetch command to the MR page. - - Fix bug causing "Remove source-branch" option not to work for merge requests from the same project. + - Add fetch command to the MR page v 7.13.1 - Fix: Label modifications are not reflected in existing notes and in the issue list @@ -23,7 +22,7 @@ v 7.13.1 - Fix: "Create Merge Request" isn't always shown in event for newly pushed branch - Fix bug causing "Remove source-branch" option not to work for merge requests from the same project. -v 7.13.0 (unreleased) +v 7.13.0 - Remove repository graph log to fix slow cache updates after push event (Stan Hu) - Only enable HSTS header for HTTPS and port 443 (Stan Hu) - Fix user autocomplete for unauthenticated users accessing public projects (Stan Hu) From 9a7645c8a4336ac592fb159ea5d39e6397ad56d9 Mon Sep 17 00:00:00 2001 From: karen Carias Date: Thu, 23 Jul 2015 12:30:05 -0700 Subject: [PATCH 10/79] added note about labels in MR --- doc/workflow/labels.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/workflow/labels.md b/doc/workflow/labels.md index 085b7baf5c..6e4840ca5a 100644 --- a/doc/workflow/labels.md +++ b/doc/workflow/labels.md @@ -1,6 +1,6 @@ # Labels -In GitLab, you can easily tag issues and merge requests. If you have permission level `Developer` or higher, you can manage labels. To create, edit or delete a label, go to a project and then to `Issues` and then `Labels`. +In GitLab, you can easily tag issues and Merge Requests. If you have permission level `Developer` or higher, you can manage labels. To create, edit or delete a label, go to a project and then to `Issues` and then `Labels`. Here you can create a new label. @@ -14,3 +14,5 @@ If you want to change an existing label, press edit next to the listed label. You will be presented with the same form as when creating a new label. ![edit label](labels/label3.png) + +You can add labels to Merge Requests when you create or edit them. From ae3f869fd1f4326e26805606197dea4ea15c67bb Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Tue, 21 Jul 2015 17:37:33 -0700 Subject: [PATCH 11/79] Fix the "Reload with full diff" URL button On the first load, the merge request tabs would be requested in JSON format to render the HTML. This would cause the "Reload with full diff" button to create a link to diff.json. Closes #2041 --- CHANGELOG | 1 + app/assets/javascripts/merge_request_tabs.js.coffee | 10 ++-------- app/views/projects/diffs/_warning.html.haml | 2 +- app/views/projects/merge_requests/_show.html.haml | 6 ++---- spec/javascripts/merge_request_tabs_spec.js.coffee | 6 ++++++ 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index c6c5bc0aac..9610a35044 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 7.14.0 (unreleased) - Fix full screen mode for snippet comments (Daniel Gerhardt) - Fix 404 error in files view after deleting the last file in a repository (Stan Hu) + - Fix the "Reload with full diff" URL button (Stan Hu) - Fix label read access for unauthenticated users (Daniel Gerhardt) - Fix access to disabled features for unauthenticated users (Daniel Gerhardt) - Fix OAuth provider bug where GitLab would not go return to the redirect_uri after sign-in (Stan Hu) diff --git a/app/assets/javascripts/merge_request_tabs.js.coffee b/app/assets/javascripts/merge_request_tabs.js.coffee index a132a0a9dc..19a07b6a03 100644 --- a/app/assets/javascripts/merge_request_tabs.js.coffee +++ b/app/assets/javascripts/merge_request_tabs.js.coffee @@ -49,12 +49,6 @@ class @MergeRequestTabs # Store the `location` object, allowing for easier stubbing in tests @_location = location - switch @opts.action - when 'commits' - @commitsLoaded = true - when 'diffs' - @diffsLoaded = true - @bindEvents() @activateTab(@opts.action) @@ -102,7 +96,7 @@ class @MergeRequestTabs action = 'notes' if action == 'show' # Remove a trailing '/commits' or '/diffs' - new_state = @_location.pathname.replace(/\/(commits|diffs)\/?$/, '') + new_state = @_location.pathname.replace(/\/(commits|diffs)(\.html)?\/?$/, '') # Append the new action if we're on a tab other than 'notes' unless action == 'notes' @@ -133,7 +127,7 @@ class @MergeRequestTabs return if @diffsLoaded @_get - url: "#{source}.json" + url: "#{source}.json" + @_location.search success: (data) => document.getElementById('diffs').innerHTML = data.html @diffsLoaded = true diff --git a/app/views/projects/diffs/_warning.html.haml b/app/views/projects/diffs/_warning.html.haml index da3d4be84b..caed0e69dc 100644 --- a/app/views/projects/diffs/_warning.html.haml +++ b/app/views/projects/diffs/_warning.html.haml @@ -3,7 +3,7 @@ Too many changes to show. .pull-right - unless diff_hard_limit_enabled? - = link_to "Reload with full diff", url_for(params.merge(force_show_diff: true)), class: "btn btn-sm btn-warning" + = link_to "Reload with full diff", url_for(params.merge(force_show_diff: true, format: :html)), class: "btn btn-sm btn-warning" - if current_controller?(:commit) or current_controller?(:merge_requests) - if current_controller?(:commit) diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml index faaa85896c..c57eee1414 100644 --- a/app/views/projects/merge_requests/_show.html.haml +++ b/app/views/projects/merge_requests/_show.html.haml @@ -66,11 +66,9 @@ #notes.notes.tab-pane.voting_notes = render "projects/merge_requests/discussion" #commits.commits.tab-pane - - if current_page?(action: 'commits') - = render "projects/merge_requests/show/commits" + - # This tab is always loaded via AJAX #diffs.diffs.tab-pane - - if current_page?(action: 'diffs') - = render "projects/merge_requests/show/diffs" + - # This tab is always loaded via AJAX .mr-loading-status = spinner diff --git a/spec/javascripts/merge_request_tabs_spec.js.coffee b/spec/javascripts/merge_request_tabs_spec.js.coffee index 6cc96fb68a..a0cfba455e 100644 --- a/spec/javascripts/merge_request_tabs_spec.js.coffee +++ b/spec/javascripts/merge_request_tabs_spec.js.coffee @@ -51,6 +51,12 @@ describe 'MergeRequestTabs', -> expect(@subject('notes')).toBe('/foo/bar/merge_requests/1') expect(@subject('commits')).toBe('/foo/bar/merge_requests/1/commits') + it 'changes from diffs.html', -> + @class._location = stubLocation(pathname: '/foo/bar/merge_requests/1/diffs.html') + + expect(@subject('notes')).toBe('/foo/bar/merge_requests/1') + expect(@subject('commits')).toBe('/foo/bar/merge_requests/1/commits') + it 'changes from notes', -> @class._location = stubLocation(pathname: '/foo/bar/merge_requests/1') From cad0e848b099ab1993d1088e317fb6e5307862ad Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Thu, 23 Jul 2015 15:55:49 -0400 Subject: [PATCH 12/79] Fix and style the "Changes suppressed" link. --- app/assets/javascripts/application.js.coffee | 7 ++++--- app/assets/stylesheets/generic/common.scss | 2 +- app/assets/stylesheets/pages/diff.scss | 11 +++++++++++ app/views/projects/diffs/_text_file.html.haml | 3 ++- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee index 8b041c490d..bb0a0c51fd 100644 --- a/app/assets/javascripts/application.js.coffee +++ b/app/assets/javascripts/application.js.coffee @@ -164,9 +164,10 @@ $ -> $('.account-box').hover -> $(@).toggleClass('hover') # Commit show suppressed diff - $(".diff-content").on "click", ".supp_diff_link", -> - $(@).next('table').show() - $(@).remove() + $(document).on 'click', '.diff-content .js-show-suppressed-diff', -> + $container = $(@).parent() + $container.next('table').show() + $container.remove() $('.navbar-toggle').on 'click', -> $('.header-content .title').toggle() diff --git a/app/assets/stylesheets/generic/common.scss b/app/assets/stylesheets/generic/common.scss index 961ac793de..d36530169a 100644 --- a/app/assets/stylesheets/generic/common.scss +++ b/app/assets/stylesheets/generic/common.scss @@ -184,7 +184,7 @@ li.note { } } -.supp_diff_link, +.show-suppressed-diff, .show-all-commits { cursor: pointer; } diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss index af6ea58382..1557c243db 100644 --- a/app/assets/stylesheets/pages/diff.scss +++ b/app/assets/stylesheets/pages/diff.scss @@ -65,6 +65,17 @@ color: #777; } + .suppressed-container { + padding: ($padding-base-vertical + 5px) $padding-base-horizontal; + text-align: center; + + // "Changes suppressed. Click to show." link + .show-suppressed-diff { + font-size: 110%; + font-weight: bold; + } + } + table { width: 100%; font-family: $monospace_font; diff --git a/app/views/projects/diffs/_text_file.html.haml b/app/views/projects/diffs/_text_file.html.haml index ed4c601bcd..977ca423f7 100644 --- a/app/views/projects/diffs/_text_file.html.haml +++ b/app/views/projects/diffs/_text_file.html.haml @@ -1,6 +1,7 @@ - too_big = diff_file.diff_lines.count > Commit::DIFF_SAFE_LINES - if too_big - %a.supp_diff_link Changes suppressed. Click to show + .suppressed-container + %a.show-suppressed-diff.js-show-suppressed-diff Changes suppressed. Click to show. %table.text-file{class: "#{'hide' if too_big}"} - last_line = 0 From 5ce6d18681ee7b74ba0c443672224dd580bd34b0 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Thu, 23 Jul 2015 17:16:39 -0400 Subject: [PATCH 13/79] Add User.find_by_username! --- app/controllers/users_controller.rb | 2 +- app/models/user.rb | 4 ++++ spec/models/user_spec.rb | 12 ++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index a67325ae65..2bb5c338cf 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -50,7 +50,7 @@ class UsersController < ApplicationController private def set_user - @user = User.find_by!('lower(username) = ?', params[:username].downcase) + @user = User.find_by_username!(params[:username]) unless current_user || @user.public_profile? return authenticate_user! diff --git a/app/models/user.rb b/app/models/user.rb index fb330ff718..4a10520b20 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -274,6 +274,10 @@ class User < ActiveRecord::Base value: login.to_s.downcase).first end + def find_by_username!(username) + find_by!('lower(username) = ?', username.downcase) + end + def by_username_or_id(name_or_id) where('users.username = ? OR users.id = ?', name_or_id.to_s, name_or_id.to_i).first end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 16902317f1..76f16323e2 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -442,6 +442,18 @@ describe User do end end + describe '.find_by_username!' do + it 'raises RecordNotFound' do + expect { described_class.find_by_username!('JohnDoe') }. + to raise_error(ActiveRecord::RecordNotFound) + end + + it 'is case-insensitive' do + user = create(:user, username: 'JohnDoe') + expect(described_class.find_by_username!('JOHNDOE')).to eq user + end + end + describe 'all_ssh_keys' do it { is_expected.to have_many(:keys).dependent(:destroy) } From a1ca9b5220f5b47bc834378d632b3e7f90dde236 Mon Sep 17 00:00:00 2001 From: karen Carias Date: Thu, 23 Jul 2015 16:38:22 -0700 Subject: [PATCH 14/79] added info about repo size --- doc/workflow/importing/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/workflow/importing/README.md b/doc/workflow/importing/README.md index 1939565771..c6cd4d34cc 100644 --- a/doc/workflow/importing/README.md +++ b/doc/workflow/importing/README.md @@ -6,4 +6,6 @@ 4. [SVN](migrating_from_svn.md) ### Note -* If you'd like to migrate from a self-hosted GitLab instance to GitLab.com, you can copy your repos by changing the remote and pushing to the new server; but issues and merge requests can't be imported. \ No newline at end of file +* If you'd like to migrate from a self-hosted GitLab instance to GitLab.com, you can copy your repos by changing the remote and pushing to the new server; but issues and merge requests can't be imported. + +* When you migrate repositories to GitLab, there is no restriction on maximum size. They are imported via HTTP, but if the repository is too large, it can timeout. From 50b36c0ae73085faee73e2fb53224d116884fa6c Mon Sep 17 00:00:00 2001 From: karen Carias Date: Thu, 23 Jul 2015 17:11:17 -0700 Subject: [PATCH 15/79] added new document about adding new files --- doc/gitlab-basics/README.md | 4 +++- doc/gitlab-basics/add-file.md | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 doc/gitlab-basics/add-file.md diff --git a/doc/gitlab-basics/README.md b/doc/gitlab-basics/README.md index d6272cd591..538894f584 100644 --- a/doc/gitlab-basics/README.md +++ b/doc/gitlab-basics/README.md @@ -2,7 +2,7 @@ Step-by-step guides on the basics of working with Git and GitLab. -* [Start using Git on the commandline](start-using-git.md) +* [Start using Git on the command line](start-using-git.md) * [Create and add your SSH Keys](create-your-ssh-keys.md) @@ -17,3 +17,5 @@ Step-by-step guides on the basics of working with Git and GitLab. * [Create a branch](create-branch.md) * [Fork a project](fork-project.md) + +* [Add a file](add-file.md) diff --git a/doc/gitlab-basics/add-file.md b/doc/gitlab-basics/add-file.md new file mode 100644 index 0000000000..ac0d98085a --- /dev/null +++ b/doc/gitlab-basics/add-file.md @@ -0,0 +1,31 @@ +# How to add a file + +You can create a file in your [shell](command-line-commands.md) or in GitLab. + +To create a file in GitLab, sign in to [GitLab.com](https://gitlab.com). + +Select a project on the right side of your screen: + +![Select a project](basicsimages/select_project.png) + +[Create a branch](create-branch.md). + +Go to the directory where you'd like to add the file and click on the "+" sign next to the name of the project and directory: + +![Create a file](basicsimages/create_file.png) + +Add a name to your file, use .md or .html at the end, depending on which markup language you'd like to use (you can't add spaces, so you can use hyphens or underscores): + +![File name](basicsimages/file_name.png) + +Add all the information that you'd like to include in your file: + +![Add information](basicsimages/white_space.png) + +Add a commit message based on what you just added and then click on "commit changes": + +![Commit changes](basicsimages/commit_changes.png) + +### Note +Besides its regular files, every directory needs a README.md or README.html file which works like an index, telling +what the directory is about. It's the first document you'll find when you open a directory. From d3cae9278fe36e8c7731aa6e7aaaf33014c8df7d Mon Sep 17 00:00:00 2001 From: Daniel Gerhardt Date: Fri, 24 Jul 2015 16:09:19 +0200 Subject: [PATCH 16/79] Add rake task 'gitlab:update_commit_count' Starting with migration `20150717130904` commit count is stored in the database. For existing projects it defaults to `0` and is updated to the correct value when commits are pushed. The newly introduced rake task updates the commit count for all projects which have not been updated yet. Refs !986, !989, #2040. --- CHANGELOG | 1 + lib/tasks/gitlab/update_commit_count.rake | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 lib/tasks/gitlab/update_commit_count.rake diff --git a/CHANGELOG b/CHANGELOG index 9ffbf64fe1..e8c27a52d7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 7.14.0 (unreleased) + - Add rake task 'gitlab:update_commit_count' (Daniel Gerhardt) - Fix full screen mode for snippet comments (Daniel Gerhardt) - Fix 404 error in files view after deleting the last file in a repository (Stan Hu) - Fix label read access for unauthenticated users (Daniel Gerhardt) diff --git a/lib/tasks/gitlab/update_commit_count.rake b/lib/tasks/gitlab/update_commit_count.rake new file mode 100644 index 0000000000..9b636f12d9 --- /dev/null +++ b/lib/tasks/gitlab/update_commit_count.rake @@ -0,0 +1,20 @@ +namespace :gitlab do + desc "GitLab | Update commit count for projects" + task update_commit_count: :environment do + projects = Project.where(commit_count: 0) + puts "#{projects.size} projects need to be updated. This might take a while." + ask_to_continue unless ENV['force'] == 'yes' + + projects.find_each(batch_size: 100) do |project| + print "#{project.name_with_namespace.yellow} ... " + + unless project.repo_exists? + puts "skipping, because the repo is empty".magenta + next + end + + project.update_commit_count + puts project.commit_count.to_s.green + end + end +end From a5e8ea54eceeb02fe34f0265d8cfe6af8b599098 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Thu, 23 Jul 2015 23:52:21 -0700 Subject: [PATCH 17/79] Fix Error 500 when browsing projects with no HEAD Steps to reproduce: 1. Create a project with a README 2. In the actual remote, type: `git symbolic-ref HEAD refs/heads/nowhere` 3. Check that HEAD is gone via `git ls-remote .` 4. Go to the projects page and see the Error 500 Closes https://github.com/gitlabhq/gitlabhq/issues/9484 --- CHANGELOG | 1 + app/helpers/projects_helper.rb | 3 ++- spec/helpers/projects_helper_spec.rb | 20 +++++++++++++++++++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index c6c5bc0aac..580f20558f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 7.14.0 (unreleased) + - Fix Error 500 when browsing projects with no HEAD (Stan Hu) - Fix full screen mode for snippet comments (Daniel Gerhardt) - Fix 404 error in files view after deleting the last file in a repository (Stan Hu) - Fix label read access for unauthenticated users (Daniel Gerhardt) diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 3cd52b381b..a675a29243 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -278,7 +278,8 @@ module ProjectsHelper end def readme_cache_key - [@project.id, @project.commit.sha, "readme"].join('-') + sha = @project.commit.try(:sha) || 'nil' + [@project.id, sha, "readme"].join('-') end def round_commit_count(project) diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb index beb9b4e438..99abb95d90 100644 --- a/spec/helpers/projects_helper_spec.rb +++ b/spec/helpers/projects_helper_spec.rb @@ -22,7 +22,7 @@ describe ProjectsHelper do let(:user) { create(:user) } - it "returns false if there are no approipriate permissions" do + it "returns false if there are no appropriate permissions" do allow(helper).to receive(:can?) { false } expect(helper.can_change_visibility_level?(project, user)).to be_falsey @@ -52,4 +52,22 @@ describe ProjectsHelper do end end end + + describe "readme_cache_key" do + let(:project) { create(:project) } + + before do + helper.instance_variable_set(:@project, project) + end + + it "returns a valid cach key" do + expect(helper.send(:readme_cache_key)).to eq("#{project.id}-#{project.commit.id}-readme") + end + + it "returns a valid cache key if HEAD does not exist" do + allow(project).to receive(:commit) { nil } + + expect(helper.send(:readme_cache_key)).to eq("#{project.id}-nil-readme") + end + end end From 31dc5e7034b8cace96477f23d06182c22d09b570 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Thu, 23 Jul 2015 14:48:55 -0400 Subject: [PATCH 18/79] Add admin_merge_request ability to Developer level and up This was necessary because this permission is checked dynamically by `app/views/shared/issuable/_context` when on a Merge Request. Closes #2058 --- app/models/ability.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/models/ability.rb b/app/models/ability.rb index 9258d981ac..6a8f683bc8 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -140,12 +140,13 @@ class Ability :create_project_snippet, :update_issue, :admin_issue, - :admin_label, + :admin_label ] end def project_dev_rules project_report_rules + [ + :admin_merge_request, :create_merge_request, :create_wiki, :push_code From b5e6ffa6165e9bbb999dd6b69e6161da80f66e7f Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Fri, 24 Jul 2015 14:59:02 -0400 Subject: [PATCH 19/79] Add "Manage merge requests" permission to docs --- doc/permissions/permissions.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/permissions/permissions.md b/doc/permissions/permissions.md index 70b7e17795..e81432c600 100644 --- a/doc/permissions/permissions.md +++ b/doc/permissions/permissions.md @@ -17,6 +17,7 @@ If a user is a GitLab administrator they receive all permissions. | Create code snippets | | ✓ | ✓ | ✓ | ✓ | | Manage issue tracker | | ✓ | ✓ | ✓ | ✓ | | Manage labels | | ✓ | ✓ | ✓ | ✓ | +| Manage merge requests | | | ✓ | ✓ | ✓ | | Create new merge request | | | ✓ | ✓ | ✓ | | Create new branches | | | ✓ | ✓ | ✓ | | Push to non-protected branches | | | ✓ | ✓ | ✓ | From 37bc7bac19599092b25f5aa30705fb1bf89e4f42 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Fri, 24 Jul 2015 15:31:15 -0400 Subject: [PATCH 20/79] Add Issuable#to_ability_name --- app/models/concerns/issuable.rb | 10 ++++++++++ app/views/shared/issuable/_context.html.haml | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index 97846b06d7..c21e7fd0e3 100644 --- a/app/models/concerns/issuable.rb +++ b/app/models/concerns/issuable.rb @@ -159,6 +159,16 @@ module Issuable end end + # Convert this Issuable class name to a format usable by Ability definitions + # + # Examples: + # + # issuable.class # => MergeRequest + # issuable.to_ability_name # => "merge_request" + def to_ability_name + self.class.to_s.underscore + end + private def filter_superceded_votes(votes, notes) diff --git a/app/views/shared/issuable/_context.html.haml b/app/views/shared/issuable/_context.html.haml index d1bd5ef968..19e8c31975 100644 --- a/app/views/shared/issuable/_context.html.haml +++ b/app/views/shared/issuable/_context.html.haml @@ -8,7 +8,7 @@ - else none .issuable-context-selectbox - - if can?(current_user, :"admin_#{issuable.class.to_s.underscore}", @project) + - if can?(current_user, :"admin_#{issuable.to_ability_name}", @project) = users_select_tag("#{issuable.class.table_name.singularize}[assignee_id]", placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: issuable.assignee_id, project: @target_project, null_user: true) %div.prepend-top-20.clearfix @@ -24,7 +24,7 @@ - else none .issuable-context-selectbox - - if can?(current_user, :"admin_#{issuable.class.to_s.underscore}", @project) + - if can?(current_user, :"admin_#{issuable.to_ability_name}", @project) = f.select(:milestone_id, milestone_options(issuable), { include_blank: 'Select milestone' }, {class: 'select2 select2-compact js-select2 js-milestone'}) = hidden_field_tag :issuable_context = f.submit class: 'btn hide' From e496c35fedeb44648dec363acac1e6e30722d1b7 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Fri, 24 Jul 2015 15:31:21 -0400 Subject: [PATCH 21/79] Dynamically check `:admin_*` ability on issuable form Closes #2092 --- app/views/shared/issuable/_form.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml index e434e1b6b9..8cc0b517cd 100644 --- a/app/views/shared/issuable/_form.html.haml +++ b/app/views/shared/issuable/_form.html.haml @@ -38,7 +38,7 @@ .clearfix .error-alert %hr -- if can?(current_user, :admin_issue, @project) +- if can?(current_user, :"admin_#{issuable.to_ability_name}", @project) .form-group .issue-assignee = f.label :assignee_id, class: 'control-label' do From b9b2d08638131be9861cb8d7e4f645a9013dd03f Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Fri, 24 Jul 2015 15:46:40 -0400 Subject: [PATCH 22/79] Dynamically check `:admin_*` ability in IssuableBaseService Closes #2092 --- app/services/issuable_base_service.rb | 6 ++++-- app/services/issues/base_service.rb | 4 ++++ app/services/merge_requests/base_service.rb | 6 ++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb index f1ef5ca84f..15b3825f96 100644 --- a/app/services/issuable_base_service.rb +++ b/app/services/issuable_base_service.rb @@ -27,8 +27,10 @@ class IssuableBaseService < BaseService old_branch, new_branch) end - def filter_params - unless can?(current_user, :admin_issue, project) + def filter_params(issuable_ability_name = :issue) + ability = :"admin_#{issuable_ability_name}" + + unless can?(current_user, ability, project) params.delete(:milestone_id) params.delete(:label_ids) params.delete(:assignee_id) diff --git a/app/services/issues/base_service.rb b/app/services/issues/base_service.rb index c3ca04a434..770f32de94 100644 --- a/app/services/issues/base_service.rb +++ b/app/services/issues/base_service.rb @@ -10,6 +10,10 @@ module Issues private + def filter_params + super(:issue) + end + def execute_hooks(issue, action = 'open') issue_data = hook_data(issue, action) issue.project.execute_hooks(issue_data, :issue_hooks) diff --git a/app/services/merge_requests/base_service.rb b/app/services/merge_requests/base_service.rb index e455fe9579..7b306a8a53 100644 --- a/app/services/merge_requests/base_service.rb +++ b/app/services/merge_requests/base_service.rb @@ -20,5 +20,11 @@ module MergeRequests merge_request.project.execute_services(merge_data, :merge_request_hooks) end end + + private + + def filter_params + super(:merge_request) + end end end From f8471cd1872aec5141cab4e1dce715741f9eb9d3 Mon Sep 17 00:00:00 2001 From: karen Carias Date: Fri, 24 Jul 2015 18:05:52 -0700 Subject: [PATCH 23/79] added note about unique SSH keys --- doc/ssh/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/ssh/README.md b/doc/ssh/README.md index 5f44f9351d..7cdcd11c04 100644 --- a/doc/ssh/README.md +++ b/doc/ssh/README.md @@ -105,3 +105,6 @@ IdentityFile ~/my-ssh-key-directory/company-com-private-key-filename Note in the gitlab.com example above a username was specified to override the default chosen by OpenSSH (your local username). This is only required if your local and remote usernames differ. Due to the wide variety of SSH clients and their very large number of configuration options, further explanation of these topics is beyond the scope of this document. + +Public SSH keys need to be unique, as they will bind to your account. Your SSH key is the only identifier you'll +have when pushing code via SSH. That's why it needs to uniquely map to a single user. From 779318398c1b74ebde29cd72d656882e21e121dd Mon Sep 17 00:00:00 2001 From: Arno Fleming Date: Sat, 25 Jul 2015 18:43:58 +0200 Subject: [PATCH 24/79] Minor styling fixes. - Link to rendered html instead of markdown source. - Removed typos --- doc/workflow/gitlab_flow.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/workflow/gitlab_flow.md b/doc/workflow/gitlab_flow.md index 0e87dc7421..f608674faf 100644 --- a/doc/workflow/gitlab_flow.md +++ b/doc/workflow/gitlab_flow.md @@ -31,7 +31,7 @@ We think there is still room for improvement and will detail a set of practices ## Git flow and its problems -[![Git Flow timeline by Vincent Driessen, used with permission](gitdashflow.png) +![Git Flow timeline by Vincent Driessen, used with permission](gitdashflow.png) Git flow was one of the first proposals to use git branches and it has gotten a lot of attention. It advocates a master branch and a separate develop branch as well as supporting branches for features, releases and hotfixes. @@ -54,7 +54,7 @@ And doing releases doesn't automatically mean also doing hotfixes. ![Master branch with feature branches merged in](github_flow.png) - In reaction to git flow a simpler alternative was detailed, [GitHub flow](https://guides.github.com/introduction/flow/index.html). +In reaction to git flow a simpler alternative was detailed, [GitHub flow](https://guides.github.com/introduction/flow/index.html). This flow has only feature branches and a master branch. This is very simple and clean, many organizations have adopted it with great success. Atlassian recommends [a similar strategy](http://blogs.atlassian.com/2014/01/simple-git-workflow-simple/) although they rebase feature branches. @@ -131,7 +131,7 @@ When you feel comfortable with it to be merged you assign it to the person that There is room for more feedback and after the assigned person feels comfortable with the result the branch is merged. If the assigned person does not feel comfortable they can close the merge request without merging. -In GitLab it is common to protect the long-lived branches (e.g. the master branch) so that normal developers [can't modify these protected branches](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/permissions/permissions.md). +In GitLab it is common to protect the long-lived branches (e.g. the master branch) so that normal developers [can't modify these protected branches](http://doc.gitlab.com/ce/permissions/permissions.html). So if you want to merge it into a protected branch you assign it to someone with master authorizations. ## Issues with GitLab flow @@ -216,7 +216,7 @@ This prevents creating a merge commit when merging master into your feature bran However, just like with squashing you should never rebase commits you have pushed to a remote server. This makes it impossible to rebase work in progress that you already shared with your team which is something we recommend. When using rebase to keep your feature branch updated you [need to resolve similar conflicts again and again](http://blogs.atlassian.com/2013/10/git-team-workflows-merge-or-rebase/). -You can reuse recorded resolutions (rerere) sometimes, but with without rebasing you only have to solve the conflicts one time and you’re set. +You can reuse recorded resolutions (rerere) sometimes, but without rebasing you only have to solve the conflicts one time and you’re set. There has to be a better way to avoid many merge commits. The way to prevent creating many merge commits is to not frequently merge master into the feature branch. From d92668a05bf35995b4b93069269084ee5db93484 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Sat, 25 Jul 2015 16:42:28 -0400 Subject: [PATCH 25/79] Only create :admin user in the one test where it's used --- spec/services/projects/create_service_spec.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb index 97b206c985..3e3d85db85 100644 --- a/spec/services/projects/create_service_spec.rb +++ b/spec/services/projects/create_service_spec.rb @@ -4,7 +4,6 @@ describe Projects::CreateService do describe :create_by_user do before do @user = create :user - @admin = create :user, admin: true @opts = { name: "GitLab", namespace: @user.namespace @@ -75,7 +74,9 @@ describe Projects::CreateService do end it 'should allow a restricted visibility level for admins' do - project = create_project(@admin, @opts) + admin = create(:admin) + project = create_project(admin, @opts) + expect(project.errors.any?).to be(false) expect(project.saved?).to be(true) end From 88aed4096274db4b2cf61c0afaa7c1df5c5f5b33 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Sat, 25 Jul 2015 16:43:18 -0400 Subject: [PATCH 26/79] Create project services on Project creation --- app/services/projects/create_service.rb | 2 ++ spec/services/projects/create_service_spec.rb | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb index 011f6f6145..b35aed005d 100644 --- a/app/services/projects/create_service.rb +++ b/app/services/projects/create_service.rb @@ -85,6 +85,8 @@ module Projects @project.create_wiki if @project.wiki_enabled? + @project.build_missing_services + event_service.create_project(@project, current_user) system_hook_service.execute_hooks_for(@project, :create) diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb index 3e3d85db85..66cdfd5d75 100644 --- a/spec/services/projects/create_service_spec.rb +++ b/spec/services/projects/create_service_spec.rb @@ -10,6 +10,13 @@ describe Projects::CreateService do } end + it 'creates services on Project creation' do + project = create_project(@user, @opts) + project.reload + + expect(project.services).not_to be_empty + end + context 'user namespace' do before do @project = create_project(@user, @opts) From 562242cb9dc11f0a5957a58eb9f91a484a909b40 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sun, 26 Jul 2015 02:17:34 -0700 Subject: [PATCH 27/79] Fix commit data retrieval when branch name has single quotes Closes #1724 --- CHANGELOG | 1 + app/controllers/projects/refs_controller.rb | 6 ++++++ app/views/projects/refs/logs_tree.js.haml | 8 +++++--- app/views/projects/tree/_tree.html.haml | 2 +- features/project/source/browse_files.feature | 7 +++++++ features/steps/project/source/browse_files.rb | 17 +++++++++++++++++ spec/support/test_env.rb | 3 ++- 7 files changed, 39 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 1ca4c7a848..024be16708 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 7.14.0 (unreleased) + - Fix commit data retrieval when branch name has single quotes (Stan Hu) - Fix Error 500 when browsing projects with no HEAD (Stan Hu) - Fix full screen mode for snippet comments (Daniel Gerhardt) - Fix 404 error in files view after deleting the last file in a repository (Stan Hu) diff --git a/app/controllers/projects/refs_controller.rb b/app/controllers/projects/refs_controller.rb index d83561cf32..6080c849c8 100644 --- a/app/controllers/projects/refs_controller.rb +++ b/app/controllers/projects/refs_controller.rb @@ -1,5 +1,6 @@ class Projects::RefsController < Projects::ApplicationController include ExtractsPath + include TreeHelper before_action :require_non_empty_project before_action :assign_ref_vars @@ -60,6 +61,11 @@ class Projects::RefsController < Projects::ApplicationController } end + if @logs.present? + @log_url = namespace_project_tree_url(@project.namespace, @project, tree_join(@ref, @path || '/')) + @more_log_url = logs_file_namespace_project_ref_path(@project.namespace, @project, @ref, @path || '', offset: (@offset + @limit)) + end + respond_to do |format| format.html { render_404 } format.js diff --git a/app/views/projects/refs/logs_tree.js.haml b/app/views/projects/refs/logs_tree.js.haml index 35c15cf3a9..db7f244d00 100644 --- a/app/views/projects/refs/logs_tree.js.haml +++ b/app/views/projects/refs/logs_tree.js.haml @@ -11,9 +11,11 @@ - if @logs.present? :plain var current_url = location.href.replace(/\/?$/, '/'); - var log_url = '#{namespace_project_tree_url(@project.namespace, @project, tree_join(@ref, @path || '/'))}'.replace(/\/?$/, '/'); + var log_url = "#{escape_javascript(@log_url)}".replace(/\/?$/, '/'); + if(current_url == log_url) { - // Load 10 more commit log for each file in tree + // Load more commit logs for each file in tree // if we still on the same page - ajaxGet('#{logs_file_namespace_project_ref_path(@project.namespace, @project, @ref, @path || '', offset: (@offset + @limit))}'); + var url = "#{escape_javascript(@more_log_url)}"; + ajaxGet(url); } diff --git a/app/views/projects/tree/_tree.html.haml b/app/views/projects/tree/_tree.html.haml index d304690d16..5048154cb2 100644 --- a/app/views/projects/tree/_tree.html.haml +++ b/app/views/projects/tree/_tree.html.haml @@ -49,5 +49,5 @@ :javascript // Load last commit log for each file in tree $('#tree-slider').waitForImages(function() { - ajaxGet('#{@logs_path}'); + ajaxGet("#{escape_javascript(@logs_path)}"); }); diff --git a/features/project/source/browse_files.feature b/features/project/source/browse_files.feature index af68cb96ed..d3a77466a3 100644 --- a/features/project/source/browse_files.feature +++ b/features/project/source/browse_files.feature @@ -158,3 +158,10 @@ Feature: Project Source Browse Files Given I visit project source page for "6d394385cf567f80a8fd85055db1ab4c5295806f" And I click on ".gitignore" file in repo Then I don't see the permalink link + + @javascript + Scenario: I browse code with single quotes in the ref + Given I switch ref to 'test' + And I see the ref 'test' has been selected + And I visit the 'test' tree + Then I see the commit data diff --git a/features/steps/project/source/browse_files.rb b/features/steps/project/source/browse_files.rb index 95879b9544..5cb085db20 100644 --- a/features/steps/project/source/browse_files.rb +++ b/features/steps/project/source/browse_files.rb @@ -193,6 +193,23 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps FileUtils.rm_f(File.join(@project.repository.path, 'hooks', 'pre-receive')) end + step "I switch ref to 'test'" do + select "'test'", from: 'ref' + end + + step "I see the ref 'test' has been selected" do + expect(page).to have_selector '.select2-chosen', text: "'test'" + end + + step "I visit the 'test' tree" do + visit namespace_project_tree_path(@project.namespace, @project, "'test'") + end + + step 'I see the commit data' do + expect(page).to have_css('.tree-commit-link', visible: true) + expect(page).not_to have_content('Loading commit data...') + end + private def set_new_content diff --git a/spec/support/test_env.rb b/spec/support/test_env.rb index dcf2a9e2ce..dab4535e2c 100644 --- a/spec/support/test_env.rb +++ b/spec/support/test_env.rb @@ -12,7 +12,8 @@ module TestEnv 'fix' => '12d65c8', 'improve/awesome' => '5937ac0', 'markdown' => '0ed8c6c', - 'master' => '5937ac0' + 'master' => '5937ac0', + "'test'" => 'e56497b', } # gitlab-test-fork is a fork of gitlab-fork, but we don't necessarily From dfe7807653304f2a42369141925733f3c6515488 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sun, 26 Jul 2015 09:52:49 -0700 Subject: [PATCH 28/79] Fix live notes refresh in relative URL deployments --- CHANGELOG | 1 + app/assets/javascripts/notes.js.coffee | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 1ca4c7a848..e198b48e86 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 7.14.0 (unreleased) + - Fix URL used for refreshing notes if relative_url is present (Bartłomiej Święcki) - Fix Error 500 when browsing projects with no HEAD (Stan Hu) - Fix full screen mode for snippet comments (Daniel Gerhardt) - Fix 404 error in files view after deleting the last file in a repository (Stan Hu) diff --git a/app/assets/javascripts/notes.js.coffee b/app/assets/javascripts/notes.js.coffee index bcff7bcc49..0021d17d85 100644 --- a/app/assets/javascripts/notes.js.coffee +++ b/app/assets/javascripts/notes.js.coffee @@ -10,7 +10,6 @@ class @Notes constructor: (notes_url, note_ids, last_fetched_at, view) -> @notes_url = notes_url - @notes_url = gon.relative_url_root + @notes_url if gon.relative_url_root? @note_ids = note_ids @last_fetched_at = last_fetched_at @view = view From 7679a7ea55851265e9d0015a51126bec489fbc6d Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Sun, 26 Jul 2015 16:55:43 -0400 Subject: [PATCH 29/79] Render Note field hints consistently for "new" and "edit" forms - The "Edit" form didn't have Markdown hints. - The "New" form had a paperclip icon for attachments, the "edit" form didn't. Closes #2010 Closes internal https://dev.gitlab.org/gitlab/gitlabhq/issues/2525 --- app/views/projects/notes/_edit_form.html.haml | 5 +---- app/views/projects/notes/_form.html.haml | 14 ++------------ app/views/projects/notes/_hints.html.haml | 9 +++++++++ 3 files changed, 12 insertions(+), 16 deletions(-) create mode 100644 app/views/projects/notes/_hints.html.haml diff --git a/app/views/projects/notes/_edit_form.html.haml b/app/views/projects/notes/_edit_form.html.haml index 7472b33bb5..8f7d2e84c7 100644 --- a/app/views/projects/notes/_edit_form.html.haml +++ b/app/views/projects/notes/_edit_form.html.haml @@ -3,10 +3,7 @@ = note_target_fields(note) = render layout: 'projects/md_preview', locals: { preview_class: 'note-text' } do = render 'projects/zen', f: f, attr: :note, classes: 'note_text js-note-text js-task-list-field' - - .comment-hints.clearfix - .pull-left #{link_to 'Markdown ', help_page_path('markdown', 'markdown'),{ target: '_blank', tabindex: -1 }} - .pull-right #{link_to 'Attach a file', '#', class: 'markdown-selector', tabindex: -1 } + = render 'projects/notes/hints' .note-form-actions .buttons diff --git a/app/views/projects/notes/_form.html.haml b/app/views/projects/notes/_form.html.haml index 64f98741d4..3be8f44b28 100644 --- a/app/views/projects/notes/_form.html.haml +++ b/app/views/projects/notes/_form.html.haml @@ -8,18 +8,8 @@ = f.hidden_field :noteable_type = render layout: 'projects/md_preview', locals: { preview_class: "note-text", referenced_users: true } do - = render 'projects/zen', f: f, attr: :note, - classes: 'note_text js-note-text' - - .comment-hints.clearfix - .pull-left - = link_to "Markdown ", help_page_path("markdown", "markdown"),{ target: '_blank', tabindex: -1 } - tip: - = random_markdown_tip - .pull-right - = link_to '#', class: 'markdown-selector', tabindex: -1 do - Attach a file - = icon('paperclip') + = render 'projects/zen', f: f, attr: :note, classes: 'note_text js-note-text' + = render 'projects/notes/hints' .error-alert .note-form-actions diff --git a/app/views/projects/notes/_hints.html.haml b/app/views/projects/notes/_hints.html.haml new file mode 100644 index 0000000000..6e7929bdab --- /dev/null +++ b/app/views/projects/notes/_hints.html.haml @@ -0,0 +1,9 @@ +.comment-hints.clearfix + .pull-left + = link_to 'Markdown', help_page_path('markdown', 'markdown'), target: '_blank', tabindex: -1 + tip: + = random_markdown_tip + .pull-right + = link_to '#', class: 'markdown-selector', tabindex: -1 do + = icon('paperclip') + Attach a file From 1cd28600652e23c8605b9344e269c34e83edccd1 Mon Sep 17 00:00:00 2001 From: Hiroyuki Sato Date: Mon, 27 Jul 2015 15:29:10 +0900 Subject: [PATCH 30/79] Fix the image file that contains non-ascii character is not displayed --- CHANGELOG | 1 + lib/gitlab/markdown/relative_link_filter.rb | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index e198b48e86..808f66b948 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 7.14.0 (unreleased) + - Fix the image file that contains non-ascii character is not displayed(Hiroyuki Sato) - Fix URL used for refreshing notes if relative_url is present (Bartłomiej Święcki) - Fix Error 500 when browsing projects with no HEAD (Stan Hu) - Fix full screen mode for snippet comments (Daniel Gerhardt) diff --git a/lib/gitlab/markdown/relative_link_filter.rb b/lib/gitlab/markdown/relative_link_filter.rb index 9de2b24a9d..3eaceba532 100644 --- a/lib/gitlab/markdown/relative_link_filter.rb +++ b/lib/gitlab/markdown/relative_link_filter.rb @@ -98,9 +98,10 @@ module Gitlab # # Returns a String def path_type(path) - if repository.tree(current_sha, path).entries.any? + unescaped_path = Addressable::URI.unescape(path) + if repository.tree(current_sha, unescaped_path).entries.any? 'tree' - elsif repository.blob_at(current_sha, path).try(:image?) + elsif repository.blob_at(current_sha, unescaped_path).try(:image?) 'raw' else 'blob' From 12a913a93c339a3dc325cbf53ae07eff902d937c Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Mon, 27 Jul 2015 17:32:56 -0400 Subject: [PATCH 31/79] Make `hr`s more visible in note bodies Closes #2107 --- app/assets/stylesheets/pages/notes.scss | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index 4da65b2874..85c828ec1a 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -37,7 +37,7 @@ ul.notes { font-size: 13px; a { - @extend .cgray; + @extend .cgray; &:hover { text-decoration: underline; @@ -105,6 +105,8 @@ ul.notes { } hr { + // Darken 'whitesmoke' a bit to make it more visible in note bodies + border-color: darken(#F5F5F5, 8%); margin: 10px 0; } } From 30b2a95b4d7d51f7c14c07c9f57fa84c1148725f Mon Sep 17 00:00:00 2001 From: Darby Date: Mon, 27 Jul 2015 17:41:31 -0400 Subject: [PATCH 32/79] Added a timestamp to the wikis page just below the title --- app/views/projects/wikis/show.html.haml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/views/projects/wikis/show.html.haml b/app/views/projects/wikis/show.html.haml index 83cd4c6667..5c4dd7f91a 100644 --- a/app/views/projects/wikis/show.html.haml +++ b/app/views/projects/wikis/show.html.haml @@ -3,6 +3,10 @@ %h3.page-title = @page.title = render 'main_links' + +.wiki-last-edit-by + Last edited by #{@page.commit.author.name} #{time_ago_with_tooltip(@page.commit.authored_date)} + - if @page.historical? .warning_message This is an old version of this page. @@ -16,6 +20,6 @@ = render_wiki_content(@page) %hr - .wiki-last-edit-by Last edited by #{@page.commit.author.name} #{time_ago_with_tooltip(@page.commit.authored_date)} + From d61433542e3bbcfac6b706a5e907240ca02c6de9 Mon Sep 17 00:00:00 2001 From: karen Carias Date: Mon, 27 Jul 2015 16:46:30 -0700 Subject: [PATCH 33/79] fixed details in document --- doc/gitlab-basics/add-file.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/gitlab-basics/add-file.md b/doc/gitlab-basics/add-file.md index ac0d98085a..e7c441e769 100644 --- a/doc/gitlab-basics/add-file.md +++ b/doc/gitlab-basics/add-file.md @@ -8,13 +8,13 @@ Select a project on the right side of your screen: ![Select a project](basicsimages/select_project.png) -[Create a branch](create-branch.md). +It's a good idea to [create a branch](create-branch.md), but it's not necessary. Go to the directory where you'd like to add the file and click on the "+" sign next to the name of the project and directory: ![Create a file](basicsimages/create_file.png) -Add a name to your file, use .md or .html at the end, depending on which markup language you'd like to use (you can't add spaces, so you can use hyphens or underscores): +Name your file (you can't add spaces, so you can use hyphens or underscores). Don't forget to include the markup language you'd like to use : ![File name](basicsimages/file_name.png) From 6b243dd138115470a3d49b90ee3d2a199776c790 Mon Sep 17 00:00:00 2001 From: karen Carias Date: Mon, 27 Jul 2015 21:53:55 -0700 Subject: [PATCH 34/79] fixed text --- doc/workflow/importing/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/workflow/importing/README.md b/doc/workflow/importing/README.md index c6cd4d34cc..cd98d1b985 100644 --- a/doc/workflow/importing/README.md +++ b/doc/workflow/importing/README.md @@ -8,4 +8,5 @@ ### Note * If you'd like to migrate from a self-hosted GitLab instance to GitLab.com, you can copy your repos by changing the remote and pushing to the new server; but issues and merge requests can't be imported. -* When you migrate repositories to GitLab, there is no restriction on maximum size. They are imported via HTTP, but if the repository is too large, it can timeout. +* Repositories are imported to GitLab via HTTP. +If the repository is too large, it can timeout. We have a soft limit of 10GB. From d3305df7aac4e632707492118a0ce91e67ed74ce Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Tue, 28 Jul 2015 14:33:19 +0200 Subject: [PATCH 35/79] Experimental support for gitlab-git-http-server https://gitlab.com/gitlab-org/gitlab-git-http-server This change introduces the GITLAB_GRACK_AUTH_ONLY environment variable. When set, Grack requests to GitLab will only respond with the user's GL_ID (if the request is OK) or an error. This allows gitlab-git-http-server to use the main GitLab application as an authentication and authorization backend. If we like how this works we should drop the GITLAB_GRACK_AUTH_ONLY variable at some point in the future. --- lib/gitlab/backend/grack_auth.rb | 7 ++++++- lib/gitlab/backend/shell_env.rb | 6 +++++- lib/support/nginx/gitlab | 25 +++++++++++++++++++++++++ lib/support/nginx/gitlab-ssl | 25 +++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 2 deletions(-) diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb index 03cef30c97..f7fc97651f 100644 --- a/lib/gitlab/backend/grack_auth.rb +++ b/lib/gitlab/backend/grack_auth.rb @@ -26,7 +26,12 @@ module Grack auth! if project && authorized_request? - @app.call(env) + if ENV['GITLAB_GRACK_AUTH_ONLY'] == '1' + # Tell gitlab-git-http-server the request is OK, and what the GL_ID is + [200, { "Content-Type" => "text/plain" }, [Gitlab::ShellEnv.gl_id(@user)]] + else + @app.call(env) + end elsif @user.nil? && !@gitlab_ci unauthorized else diff --git a/lib/gitlab/backend/shell_env.rb b/lib/gitlab/backend/shell_env.rb index 17ec029eed..009a3ec1a4 100644 --- a/lib/gitlab/backend/shell_env.rb +++ b/lib/gitlab/backend/shell_env.rb @@ -7,7 +7,7 @@ module Gitlab def set_env(user) # Set GL_ID env variable if user - ENV['GL_ID'] = "user-#{user.id}" + ENV['GL_ID'] = gl_id(user) end end @@ -15,5 +15,9 @@ module Gitlab # Reset GL_ID env variable ENV['GL_ID'] = nil end + + def gl_id(user) + "user-#{user.id}" + end end end diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab index edb987875d..efa0898900 100644 --- a/lib/support/nginx/gitlab +++ b/lib/support/nginx/gitlab @@ -38,6 +38,11 @@ upstream gitlab { server unix:/home/git/gitlab/tmp/sockets/gitlab.socket fail_timeout=0; } +## Experimental: gitlab-git-http-server +# upstream gitlab-git-http-server { +# server localhost:8181; +# } + ## Normal HTTP host server { ## Either remove "default_server" from the listen line below, @@ -109,6 +114,26 @@ server { proxy_pass http://gitlab; } + ## Experimental: send Git HTTP traffic to gitlab-git-http-server instead of Unicorn + # location ~ [-\/\w\.]+\.git\/ { + # ## If you use HTTPS make sure you disable gzip compression + # ## to be safe against BREACH attack. + # # gzip off; + + # ## https://github.com/gitlabhq/gitlabhq/issues/694 + # ## Some requests take more than 30 seconds. + # proxy_read_timeout 300; + # proxy_connect_timeout 300; + # proxy_redirect off; + + # proxy_set_header Host $http_host; + # proxy_set_header X-Real-IP $remote_addr; + # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + # proxy_set_header X-Forwarded-Proto $scheme; + + # proxy_pass http://gitlab-git-http-server; + # } + ## Enable gzip compression as per rails guide: ## http://guides.rubyonrails.org/asset_pipeline.html#gzip-compression ## WARNING: If you are using relative urls remove the block below diff --git a/lib/support/nginx/gitlab-ssl b/lib/support/nginx/gitlab-ssl index 766559b49f..314525518f 100644 --- a/lib/support/nginx/gitlab-ssl +++ b/lib/support/nginx/gitlab-ssl @@ -42,6 +42,11 @@ upstream gitlab { server unix:/home/git/gitlab/tmp/sockets/gitlab.socket fail_timeout=0; } +## Experimental: gitlab-git-http-server +# upstream gitlab-git-http-server { +# server localhost:8181; +# } + ## Redirects all HTTP traffic to the HTTPS host server { ## Either remove "default_server" from the listen line below, @@ -156,6 +161,26 @@ server { proxy_pass http://gitlab; } + ## Experimental: send Git HTTP traffic to gitlab-git-http-server instead of Unicorn + # location ~ [-\/\w\.]+\.git\/ { + # ## If you use HTTPS make sure you disable gzip compression + # ## to be safe against BREACH attack. + # gzip off; + + # ## https://github.com/gitlabhq/gitlabhq/issues/694 + # ## Some requests take more than 30 seconds. + # proxy_read_timeout 300; + # proxy_connect_timeout 300; + # proxy_redirect off; + + # proxy_set_header Host $http_host; + # proxy_set_header X-Real-IP $remote_addr; + # proxy_set_header X-Forwarded-Ssl on; + # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + # proxy_set_header X-Forwarded-Proto $scheme; + # proxy_pass http://gitlab-git-http-server; + # } + ## Enable gzip compression as per rails guide: ## http://guides.rubyonrails.org/asset_pipeline.html#gzip-compression ## WARNING: If you are using relative urls remove the block below From ae9e5eea3c6955d278182005808fbdfccd4d447b Mon Sep 17 00:00:00 2001 From: GitLab Date: Tue, 28 Jul 2015 15:17:06 +0200 Subject: [PATCH 36/79] Handle missing @user during Git HTTP requests --- lib/gitlab/backend/grack_auth.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb index f7fc97651f..5966d394b6 100644 --- a/lib/gitlab/backend/grack_auth.rb +++ b/lib/gitlab/backend/grack_auth.rb @@ -28,7 +28,7 @@ module Grack if project && authorized_request? if ENV['GITLAB_GRACK_AUTH_ONLY'] == '1' # Tell gitlab-git-http-server the request is OK, and what the GL_ID is - [200, { "Content-Type" => "text/plain" }, [Gitlab::ShellEnv.gl_id(@user)]] + render_grack_auth_ok else @app.call(env) end @@ -179,6 +179,15 @@ module Grack end end + def render_grack_auth_ok + if @user.present? + body = Gitlab::ShellEnv.gl_id(@user) + else + body = '' + end + [200, { "Content-Type" => "text/plain" }, [body]] + end + def render_not_found [404, { "Content-Type" => "text/plain" }, ["Not Found"]] end From 42ebd902de707c8ddc35b97983ec0eee16458e56 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 28 Jul 2015 15:33:16 +0200 Subject: [PATCH 37/79] Fix bug causing Bitbucket importer to crash when OAuth application had been removed. --- CHANGELOG | 1 + .../import/bitbucket_controller.rb | 1 + lib/gitlab/bitbucket_import/client.rb | 21 +++++++++++++------ 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index cf0fa36bd4..331f7d7a3a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -16,6 +16,7 @@ v 7.14.0 (unreleased) - Expire Rails cache entries after two weeks to prevent endless Redis growth - Add support for destroying project milestones (Stan Hu) - Add fetch command to the MR page + - Fix bug causing Bitbucket importer to crash when OAuth application had been removed. v 7.13.1 - Fix: Label modifications are not reflected in existing notes and in the issue list diff --git a/app/controllers/import/bitbucket_controller.rb b/app/controllers/import/bitbucket_controller.rb index ca78a4aaa8..af0b841f0b 100644 --- a/app/controllers/import/bitbucket_controller.rb +++ b/app/controllers/import/bitbucket_controller.rb @@ -3,6 +3,7 @@ class Import::BitbucketController < Import::BaseController before_action :bitbucket_auth, except: :callback rescue_from OAuth::Error, with: :bitbucket_unauthorized + rescue_from Gitlab::BitbucketImport::Client::Unauthorized, with: :bitbucket_unauthorized def callback request_token = session.delete(:oauth_request_token) diff --git a/lib/gitlab/bitbucket_import/client.rb b/lib/gitlab/bitbucket_import/client.rb index 5b1952b967..778b76f689 100644 --- a/lib/gitlab/bitbucket_import/client.rb +++ b/lib/gitlab/bitbucket_import/client.rb @@ -1,6 +1,8 @@ module Gitlab module BitbucketImport class Client + class Unauthorized < StandardError; end + attr_reader :consumer, :api def initialize(access_token = nil, access_token_secret = nil) @@ -46,23 +48,23 @@ module Gitlab end def user - JSON.parse(api.get("/api/1.0/user").body) + JSON.parse(get("/api/1.0/user").body) end def issues(project_identifier) - JSON.parse(api.get("/api/1.0/repositories/#{project_identifier}/issues").body) + JSON.parse(get("/api/1.0/repositories/#{project_identifier}/issues").body) end def issue_comments(project_identifier, issue_id) - JSON.parse(api.get("/api/1.0/repositories/#{project_identifier}/issues/#{issue_id}/comments").body) + JSON.parse(get("/api/1.0/repositories/#{project_identifier}/issues/#{issue_id}/comments").body) end def project(project_identifier) - JSON.parse(api.get("/api/1.0/repositories/#{project_identifier}").body) + JSON.parse(get("/api/1.0/repositories/#{project_identifier}").body) end def find_deploy_key(project_identifier, key) - JSON.parse(api.get("/api/1.0/repositories/#{project_identifier}/deploy-keys").body).find do |deploy_key| + JSON.parse(get("/api/1.0/repositories/#{project_identifier}/deploy-keys").body).find do |deploy_key| deploy_key["key"].chomp == key.chomp end end @@ -82,11 +84,18 @@ module Gitlab end def projects - JSON.parse(api.get("/api/1.0/user/repositories").body).select { |repo| repo["scm"] == "git" } + JSON.parse(get("/api/1.0/user/repositories").body).select { |repo| repo["scm"] == "git" } end private + def get(url) + response = api.get(url) + raise Unauthorized if (400..499).include?(response.code.to_i) + + response + end + def config Gitlab.config.omniauth.providers.find { |provider| provider.name == "bitbucket"} end From a784b996b3071cfe1807b1108316143dbc64492f Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 28 Jul 2015 15:49:44 +0200 Subject: [PATCH 38/79] Add project star and fork count, group avatar URL and user/group web URL attributes to API --- CHANGELOG | 1 + app/models/group.rb | 11 +++++++++++ app/models/user.rb | 4 ++++ lib/api/entities.rb | 4 +++- 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index cf0fa36bd4..eef3c3e7c0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -16,6 +16,7 @@ v 7.14.0 (unreleased) - Expire Rails cache entries after two weeks to prevent endless Redis growth - Add support for destroying project milestones (Stan Hu) - Add fetch command to the MR page + - Add project star and fork count, group avatar URL and user/group web URL attributes to API v 7.13.1 - Fix: Label modifications are not reflected in existing notes and in the issue list diff --git a/app/models/group.rb b/app/models/group.rb index 051c672cb3..adcbbec465 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -17,6 +17,7 @@ require 'carrierwave/orm/activerecord' require 'file_size_validator' class Group < Namespace + include Gitlab::ConfigHelper include Referable has_many :group_members, dependent: :destroy, as: :source, class_name: 'GroupMember' @@ -56,6 +57,16 @@ class Group < Namespace name end + def avatar_url(size = nil) + if avatar.present? + [gitlab_config.url, avatar.url].join + end + end + + def web_url + [gitlab_config.url, "groups", self.path].join('/') + end + def owners @owners ||= group_members.owners.map(&:user) end diff --git a/app/models/user.rb b/app/models/user.rb index 4a10520b20..00a37cd913 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -637,6 +637,10 @@ class User < ActiveRecord::Base end end + def web_url + [gitlab_config.url, "u", self.username].join('/') + end + def all_emails [self.email, *self.emails.map(&:email)] end diff --git a/lib/api/entities.rb b/lib/api/entities.rb index ecf1412dee..c1b0cece34 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -5,7 +5,7 @@ module API end class UserBasic < UserSafe - expose :id, :state, :avatar_url + expose :id, :state, :avatar_url, :web_url end class User < UserBasic @@ -59,6 +59,7 @@ module API expose :namespace expose :forked_from_project, using: Entities::ForkedFromProject, if: lambda{ | project, options | project.forked? } expose :avatar_url + expose :star_count, :forks_count end class ProjectMember < UserBasic @@ -69,6 +70,7 @@ module API class Group < Grape::Entity expose :id, :name, :path, :description + expose :avatar_url, :web_url end class GroupDetail < Group From 6912f21e5c9dd812286fce156534ebc094466e17 Mon Sep 17 00:00:00 2001 From: GitLab Date: Tue, 28 Jul 2015 15:55:53 +0200 Subject: [PATCH 39/79] Send GL_ID to gitlab-git-http-server as JSON --- lib/gitlab/backend/grack_auth.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb index 5966d394b6..e8cb0c77fb 100644 --- a/lib/gitlab/backend/grack_auth.rb +++ b/lib/gitlab/backend/grack_auth.rb @@ -181,11 +181,12 @@ module Grack def render_grack_auth_ok if @user.present? - body = Gitlab::ShellEnv.gl_id(@user) + gl_id = Gitlab::ShellEnv.gl_id(@user) else - body = '' + gl_id = '' end - [200, { "Content-Type" => "text/plain" }, [body]] + + [200, { "Content-Type" => "application/json" }, [JSON.dump({'GL_ID' => gl_id})]] end def render_not_found From f9bcb9632c1f7f5c5c72d50a90289baa2af762f5 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 28 Jul 2015 16:32:15 +0200 Subject: [PATCH 40/79] Add specific ability for managing group members --- app/controllers/groups/group_members_controller.rb | 7 +++++++ app/models/ability.rb | 5 +++-- app/views/dashboard/groups/index.html.haml | 7 ++++--- app/views/groups/group_members/_group_member.html.haml | 2 +- app/views/groups/group_members/index.html.haml | 2 +- 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb index 040255f08e..b9c428a964 100644 --- a/app/controllers/groups/group_members_controller.rb +++ b/app/controllers/groups/group_members_controller.rb @@ -21,6 +21,8 @@ class Groups::GroupMembersController < Groups::ApplicationController end def create + return render_403 unless can?(current_user, :admin_group_member, @group) + @group.add_users(params[:user_ids].split(','), params[:access_level], current_user) redirect_to group_group_members_path(@group), notice: 'Users were successfully added.' @@ -28,6 +30,9 @@ class Groups::GroupMembersController < Groups::ApplicationController def update @member = @group.group_members.find(params[:id]) + + return render_403 unless can?(current_user, :update_group_member, @member) + @member.update_attributes(member_params) end @@ -46,6 +51,8 @@ class Groups::GroupMembersController < Groups::ApplicationController end def resend_invite + return render_403 unless can?(current_user, :admin_group_member, @group) + redirect_path = group_group_members_path(@group) @group_member = @group.group_members.find(params[:id]) diff --git a/app/models/ability.rb b/app/models/ability.rb index 6a8f683bc8..f8e5afa9b0 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -233,7 +233,8 @@ class Ability if group.has_owner?(user) || user.admin? rules.push(*[ :admin_group, - :admin_namespace + :admin_namespace, + :admin_group_member ]) end @@ -295,7 +296,7 @@ class Ability rules = [] target_user = subject.user group = subject.group - can_manage = group_abilities(user, group).include?(:admin_group) + can_manage = group_abilities(user, group).include?(:admin_group_member) if can_manage && (user != target_user) rules << :update_group_member diff --git a/app/views/dashboard/groups/index.html.haml b/app/views/dashboard/groups/index.html.haml index 0a354373b9..b75c11795b 100644 --- a/app/views/dashboard/groups/index.html.haml +++ b/app/views/dashboard/groups/index.html.haml @@ -23,9 +23,10 @@ %i.fa.fa-cogs Settings - = link_to leave_group_group_members_path(group), data: { confirm: leave_group_message(group.name) }, method: :delete, class: "btn-sm btn btn-grouped", title: 'Leave this group' do - %i.fa.fa-sign-out - Leave + - if can?(current_user, :destroy_group_member, group_member) + = link_to leave_group_group_members_path(group), data: { confirm: leave_group_message(group.name) }, method: :delete, class: "btn-sm btn btn-grouped", title: 'Leave this group' do + %i.fa.fa-sign-out + Leave = image_tag group_icon(group), class: "avatar s40 avatar-tile hidden-xs" = link_to group, class: 'group-name' do diff --git a/app/views/groups/group_members/_group_member.html.haml b/app/views/groups/group_members/_group_member.html.haml index b460e0ff59..acc7f8b28c 100644 --- a/app/views/groups/group_members/_group_member.html.haml +++ b/app/views/groups/group_members/_group_member.html.haml @@ -24,7 +24,7 @@ = link_to member.created_by.name, user_path(member.created_by) = time_ago_with_tooltip(member.created_at) - - if show_controls && can?(current_user, :admin_group, @group) + - if show_controls && can?(current_user, :admin_group_member, member) = link_to resend_invite_group_group_member_path(@group, member), method: :post, class: "btn-xs btn", title: 'Resend invite' do Resend invite diff --git a/app/views/groups/group_members/index.html.haml b/app/views/groups/group_members/index.html.haml index a70d1ff069..dba395cc8f 100644 --- a/app/views/groups/group_members/index.html.haml +++ b/app/views/groups/group_members/index.html.haml @@ -17,7 +17,7 @@ = search_field_tag :search, params[:search], { placeholder: 'Find existing member by name', class: 'form-control search-text-input' } = button_tag 'Search', class: 'btn' - - if current_user && current_user.can?(:admin_group, @group) + - if current_user && current_user.can?(:admin_group_member, @group) .pull-right = button_tag class: 'btn btn-new js-toggle-button', type: 'button' do Add members From 45acfdd32ace09b8ff4c8905cbeefb3d8001ccc3 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 28 Jul 2015 16:36:48 +0200 Subject: [PATCH 41/79] Disable adding members from admin area when appropriate --- app/views/admin/groups/show.html.haml | 34 ++++++++++++++------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml index 187314872d..296497a4cd 100644 --- a/app/views/admin/groups/show.html.haml +++ b/app/views/admin/groups/show.html.haml @@ -51,21 +51,22 @@ = paginate @projects, param_name: 'projects_page', theme: 'gitlab' .col-md-6 - .panel.panel-default - .panel-heading - Add user(s) to the group: - .panel-body.form-holder - %p.light - Read more about project permissions - %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink" + - if can?(current_user, :admin_group_member, @group) + .panel.panel-default + .panel-heading + Add user(s) to the group: + .panel-body.form-holder + %p.light + Read more about project permissions + %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink" - = form_tag members_update_admin_group_path(@group), id: "new_project_member", class: "bulk_import", method: :put do - %div - = users_select_tag(:user_ids, multiple: true, email_user: true, scope: :all) - %div.prepend-top-10 - = select_tag :access_level, options_for_select(GroupMember.access_level_roles), class: "project-access-select select2" - %hr - = button_tag 'Add users to group', class: "btn btn-create" + = form_tag members_update_admin_group_path(@group), id: "new_project_member", class: "bulk_import", method: :put do + %div + = users_select_tag(:user_ids, multiple: true, email_user: true, scope: :all) + %div.prepend-top-10 + = select_tag :access_level, options_for_select(GroupMember.access_level_roles), class: "project-access-select select2" + %hr + = button_tag 'Add users to group', class: "btn btn-create" .panel.panel-default .panel-heading %h3.panel-title @@ -86,7 +87,8 @@ (invited) %span.pull-right.light = member.human_access - = link_to group_group_member_path(@group, member), data: { confirm: remove_user_from_group_message(@group, member) }, method: :delete, remote: true, class: "btn-xs btn btn-remove", title: 'Remove user from group' do - %i.fa.fa-minus.fa-inverse + - if can?(current_user, :destroy_group_member, member) + = link_to group_group_member_path(@group, member), data: { confirm: remove_user_from_group_message(@group, member) }, method: :delete, remote: true, class: "btn-xs btn btn-remove", title: 'Remove user from group' do + %i.fa.fa-minus.fa-inverse .panel-footer = paginate @members, param_name: 'members_page', theme: 'gitlab' From b230335090ee8fa22ab79453e24c1c3c468569df Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 28 Jul 2015 17:52:38 +0200 Subject: [PATCH 42/79] Show Leave button when you're the last owner, so that the error explains the reason --- app/views/dashboard/groups/index.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/dashboard/groups/index.html.haml b/app/views/dashboard/groups/index.html.haml index b75c11795b..6ef4d752ac 100644 --- a/app/views/dashboard/groups/index.html.haml +++ b/app/views/dashboard/groups/index.html.haml @@ -23,7 +23,7 @@ %i.fa.fa-cogs Settings - - if can?(current_user, :destroy_group_member, group_member) + - if can?(current_user, :admin_group_member, group) = link_to leave_group_group_members_path(group), data: { confirm: leave_group_message(group.name) }, method: :delete, class: "btn-sm btn btn-grouped", title: 'Leave this group' do %i.fa.fa-sign-out Leave From 16dcf356b5afe351a78ac976db30e4999600b13b Mon Sep 17 00:00:00 2001 From: GitLab Date: Tue, 28 Jul 2015 18:04:57 +0200 Subject: [PATCH 43/79] Fix style points To make Rubocop and Douwe happy --- lib/gitlab/backend/grack_auth.rb | 8 +------- lib/gitlab/backend/shell_env.rb | 7 ++++++- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb index e8cb0c77fb..12292f614e 100644 --- a/lib/gitlab/backend/grack_auth.rb +++ b/lib/gitlab/backend/grack_auth.rb @@ -180,13 +180,7 @@ module Grack end def render_grack_auth_ok - if @user.present? - gl_id = Gitlab::ShellEnv.gl_id(@user) - else - gl_id = '' - end - - [200, { "Content-Type" => "application/json" }, [JSON.dump({'GL_ID' => gl_id})]] + [200, { "Content-Type" => "application/json" }, [JSON.dump({ 'GL_ID' => Gitlab::ShellEnv.gl_id(@user) })]] end def render_not_found diff --git a/lib/gitlab/backend/shell_env.rb b/lib/gitlab/backend/shell_env.rb index 009a3ec1a4..9f5adee594 100644 --- a/lib/gitlab/backend/shell_env.rb +++ b/lib/gitlab/backend/shell_env.rb @@ -17,7 +17,12 @@ module Gitlab end def gl_id(user) - "user-#{user.id}" + if user.present? + "user-#{user.id}" + else + # This empty string is used in the render_grack_auth_ok method + "" + end end end end From c22b4061c2136c57a30b96a886688d49ecd88193 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Tue, 28 Jul 2015 08:07:25 -0700 Subject: [PATCH 44/79] Upgrade gitlab_git to version 7.2.6 to fix Error 500 when creating network graphs Closes #745 --- CHANGELOG | 1 + Gemfile | 2 +- Gemfile.lock | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index cf0fa36bd4..12ad9b7e79 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 7.14.0 (unreleased) + - Upgrade gitlab_git to version 7.2.6 to fix Error 500 when creating network graphs (Stan Hu) - Fix URL used for refreshing notes if relative_url is present (Bartłomiej Święcki) - Fix commit data retrieval when branch name has single quotes (Stan Hu) - Fix Error 500 when browsing projects with no HEAD (Stan Hu) diff --git a/Gemfile b/Gemfile index ba32feba3e..8552e731bb 100644 --- a/Gemfile +++ b/Gemfile @@ -38,7 +38,7 @@ gem "browser", '~> 0.8.0' # Extracting information from a git repository # Provide access to Gitlab::Git library -gem "gitlab_git", '~> 7.2.5' +gem "gitlab_git", '~> 7.2.6' # Ruby/Rack Git Smart-HTTP Server Handler # GitLab fork with a lot of changes (improved thread-safety, better memory usage etc) diff --git a/Gemfile.lock b/Gemfile.lock index 6e571072a4..bef67884c3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -271,7 +271,7 @@ GEM mime-types (~> 1.19) gitlab_emoji (0.1.0) gemojione (~> 2.0) - gitlab_git (7.2.5) + gitlab_git (7.2.6) activesupport (~> 4.0) charlock_holmes (~> 0.6) gitlab-linguist (~> 3.0) @@ -784,7 +784,7 @@ DEPENDENCIES gitlab-grack (~> 2.0.2) gitlab-linguist (~> 3.0.1) gitlab_emoji (~> 0.1) - gitlab_git (~> 7.2.5) + gitlab_git (~> 7.2.6) gitlab_meta (= 7.0) gitlab_omniauth-ldap (= 1.2.1) gollum-lib (~> 4.0.2) From 5bdcef7b0b6fd9cfdc3498a40d2b2b2a9ddc682c Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Tue, 28 Jul 2015 17:37:14 +0000 Subject: [PATCH 45/79] Change before(:all) -> let! to avoid leaking data across tests Closes https://github.com/gitlabhq/gitlabhq/issues/9495 --- spec/features/security/group_access_spec.rb | 30 ++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/spec/features/security/group_access_spec.rb b/spec/features/security/group_access_spec.rb index 0f36e47498..8ce1538860 100644 --- a/spec/features/security/group_access_spec.rb +++ b/spec/features/security/group_access_spec.rb @@ -36,7 +36,7 @@ describe 'Group access', feature: true do subject { group_path(group) } context 'with public projects' do - before(:all) { create_project(:public) } + let!(:project) { create_project(:public) } it { is_expected.to be_allowed_for group_member(:owner) } it { is_expected.to be_allowed_for group_member(:master) } @@ -48,7 +48,7 @@ describe 'Group access', feature: true do end context 'with mixed projects' do - before(:all) { create_project(:mixed) } + let!(:project) { create_project(:mixed) } it { is_expected.to be_allowed_for group_member(:owner) } it { is_expected.to be_allowed_for group_member(:master) } @@ -60,7 +60,7 @@ describe 'Group access', feature: true do end context 'with internal projects' do - before(:all) { create_project(:internal) } + let!(:project) { create_project(:internal) } it { is_expected.to be_allowed_for group_member(:owner) } it { is_expected.to be_allowed_for group_member(:master) } @@ -86,7 +86,7 @@ describe 'Group access', feature: true do subject { issues_group_path(group) } context 'with public projects' do - before(:all) { create_project(:public) } + let!(:project) { create_project(:public) } it { is_expected.to be_allowed_for group_member(:owner) } it { is_expected.to be_allowed_for group_member(:master) } @@ -98,7 +98,7 @@ describe 'Group access', feature: true do end context 'with mixed projects' do - before(:all) { create_project(:mixed) } + let!(:project) { create_project(:mixed) } it { is_expected.to be_allowed_for group_member(:owner) } it { is_expected.to be_allowed_for group_member(:master) } @@ -110,7 +110,7 @@ describe 'Group access', feature: true do end context 'with internal projects' do - before(:all) { create_project(:internal) } + let!(:project) { create_project(:internal) } it { is_expected.to be_allowed_for group_member(:owner) } it { is_expected.to be_allowed_for group_member(:master) } @@ -136,7 +136,7 @@ describe 'Group access', feature: true do subject { merge_requests_group_path(group) } context 'with public projects' do - before(:all) { create_project(:public) } + let!(:project) { create_project(:public) } it { is_expected.to be_allowed_for group_member(:owner) } it { is_expected.to be_allowed_for group_member(:master) } @@ -148,7 +148,7 @@ describe 'Group access', feature: true do end context 'with mixed projects' do - before(:all) { create_project(:mixed) } + let!(:project) { create_project(:mixed) } it { is_expected.to be_allowed_for group_member(:owner) } it { is_expected.to be_allowed_for group_member(:master) } @@ -160,7 +160,7 @@ describe 'Group access', feature: true do end context 'with internal projects' do - before(:all) { create_project(:internal) } + let!(:project) { create_project(:internal) } it { is_expected.to be_allowed_for group_member(:owner) } it { is_expected.to be_allowed_for group_member(:master) } @@ -186,7 +186,7 @@ describe 'Group access', feature: true do subject { group_group_members_path(group) } context 'with public projects' do - before(:all) { create_project(:public) } + let!(:project) { create_project(:public) } it { is_expected.to be_allowed_for group_member(:owner) } it { is_expected.to be_allowed_for group_member(:master) } @@ -198,7 +198,7 @@ describe 'Group access', feature: true do end context 'with mixed projects' do - before(:all) { create_project(:mixed) } + let!(:project) { create_project(:mixed) } it { is_expected.to be_allowed_for group_member(:owner) } it { is_expected.to be_allowed_for group_member(:master) } @@ -210,7 +210,7 @@ describe 'Group access', feature: true do end context 'with internal projects' do - before(:all) { create_project(:internal) } + let!(:project) { create_project(:internal) } it { is_expected.to be_allowed_for group_member(:owner) } it { is_expected.to be_allowed_for group_member(:master) } @@ -236,7 +236,7 @@ describe 'Group access', feature: true do subject { edit_group_path(group) } context 'with public projects' do - before(:all) { create_project(:public) } + let!(:project) { create_project(:public) } it { is_expected.to be_allowed_for group_member(:owner) } it { is_expected.to be_denied_for group_member(:master) } @@ -248,7 +248,7 @@ describe 'Group access', feature: true do end context 'with mixed projects' do - before(:all) { create_project(:mixed) } + let!(:project) { create_project(:mixed) } it { is_expected.to be_allowed_for group_member(:owner) } it { is_expected.to be_denied_for group_member(:master) } @@ -260,7 +260,7 @@ describe 'Group access', feature: true do end context 'with internal projects' do - before(:all) { create_project(:internal) } + let!(:project) { create_project(:internal) } it { is_expected.to be_allowed_for group_member(:owner) } it { is_expected.to be_denied_for group_member(:master) } From f8bfd065aa010955e9435347cb92b92006f0d5bf Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Tue, 28 Jul 2015 14:31:02 -0700 Subject: [PATCH 46/79] Fix extraneous version --- CHANGELOG | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 12ad9b7e79..b2169b5de1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -30,7 +30,6 @@ v 7.13.1 v 7.13.0 - Remove repository graph log to fix slow cache updates after push event (Stan Hu) -v 7.13.0 (unreleased) - Return comments in created order in merge request API (Stan Hu) - Only enable HSTS header for HTTPS and port 443 (Stan Hu) - Fix user autocomplete for unauthenticated users accessing public projects (Stan Hu) From b07ecbb5e37530e7754dc267da4ded1d7d2d736d Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Sun, 19 Jul 2015 19:41:54 -0400 Subject: [PATCH 47/79] Simplify AutolinkFilter specs --- spec/features/markdown_spec.rb | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/spec/features/markdown_spec.rb b/spec/features/markdown_spec.rb index b8199aa5e6..b8a846c701 100644 --- a/spec/features/markdown_spec.rb +++ b/spec/features/markdown_spec.rb @@ -195,45 +195,41 @@ describe 'GitLab Markdown', feature: true do end describe 'AutolinkFilter' do - let(:list) { get_section('autolinkfilter').next_element } + def body + get_section('autolinkfilter').next_element + end - def item(index) - list.at_css("li:nth-child(#{index})") + # Override Capybara's `have_link` matcher to simplify our use case + def have_link(link) + super(link, href: link) end it 'autolinks http://' do - expect(item(1).children.first.name).to eq 'a' - expect(item(1).children.first['href']).to eq 'http://about.gitlab.com/' + expect(body).to have_link('http://about.gitlab.com/') end it 'autolinks https://' do - expect(item(2).children.first.name).to eq 'a' - expect(item(2).children.first['href']).to eq 'https://google.com/' + expect(body).to have_link('https://google.com/') end it 'autolinks ftp://' do - expect(item(3).children.first.name).to eq 'a' - expect(item(3).children.first['href']).to eq 'ftp://ftp.us.debian.org/debian/' + expect(body).to have_link('ftp://ftp.us.debian.org/debian/') end it 'autolinks smb://' do - expect(item(4).children.first.name).to eq 'a' - expect(item(4).children.first['href']).to eq 'smb://foo/bar/baz' + expect(body).to have_link('smb://foo/bar/baz') end it 'autolinks irc://' do - expect(item(5).children.first.name).to eq 'a' - expect(item(5).children.first['href']).to eq 'irc://irc.freenode.net/git' + expect(body).to have_link('irc://irc.freenode.net/git') end it 'autolinks short, invalid URLs' do - expect(item(6).children.first.name).to eq 'a' - expect(item(6).children.first['href']).to eq 'http://localhost:3000' + expect(body).to have_link('http://localhost:3000') end %w(code a kbd).each do |elem| it "ignores links inside '#{elem}' element" do - body = get_section('autolinkfilter') expect(body).not_to have_selector("#{elem} a") end end From 06478ef3ecba80625e5cff70cb3697f442e24cba Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Mon, 20 Jul 2015 22:22:17 -0400 Subject: [PATCH 48/79] Minor Markdown feature spec reorganization --- spec/features/markdown_spec.rb | 93 +++++++++++++++++----------------- 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/spec/features/markdown_spec.rb b/spec/features/markdown_spec.rb index b8a846c701..f1be4e49c8 100644 --- a/spec/features/markdown_spec.rb +++ b/spec/features/markdown_spec.rb @@ -33,39 +33,31 @@ require 'erb' # See the MarkdownFeature class for setup details. describe 'GitLab Markdown', feature: true do - include ActionView::Helpers::TagHelper - include ActionView::Helpers::UrlHelper include Capybara::Node::Matchers include GitlabMarkdownHelper - # `markdown` calls these two methods - def current_user - @feat.user - end - - def user_color_scheme_class - :white - end - # Let's only parse this thing once before(:all) do @feat = MarkdownFeature.new - # `markdown` expects a `@project` variable + # `gfm_with_options` depends on a `@project` variable @project = @feat.project - @md = markdown(@feat.raw_markdown) - @doc = Nokogiri::HTML::DocumentFragment.parse(@md) + @html = markdown(@feat.raw_markdown) end after(:all) do @feat.teardown end + def doc + @doc ||= Nokogiri::HTML::DocumentFragment.parse(@html) + end + # Given a header ID, goes to that element's parent (the header itself), then # its next sibling element (the body). def get_section(id) - @doc.at_css("##{id}").parent.next_element + doc.at_css("##{id}").parent.next_element end # Sometimes it can be useful to see the parsed output of the Markdown document @@ -74,11 +66,11 @@ describe 'GitLab Markdown', feature: true do # # it 'writes to a file' do # File.open(Rails.root.join('tmp/capybara/markdown_spec.html'), 'w') do |file| - # file.puts @md + # file.puts @html # end # end - describe 'Markdown' do + describe 'Redcarpet extensions' do describe 'No Intra Emphasis' do it 'does not parse emphasis inside of words' do body = get_section('no-intra-emphasis') @@ -95,21 +87,21 @@ describe 'GitLab Markdown', feature: true do end it 'allows Markdown in tables' do - expect(@doc.at_css('td:contains("Baz")').children.to_html). + expect(doc.at_css('td:contains("Baz")').children.to_html). to eq 'Baz' end end describe 'Fenced Code Blocks' do it 'parses fenced code blocks' do - expect(@doc).to have_selector('pre.code.highlight.white.c') - expect(@doc).to have_selector('pre.code.highlight.white.python') + expect(doc).to have_selector('pre.code.highlight.white.c') + expect(doc).to have_selector('pre.code.highlight.white.python') end end describe 'Strikethrough' do it 'parses strikethroughs' do - expect(@doc).to have_selector(%{del:contains("and this text doesn't")}) + expect(doc).to have_selector(%{del:contains("and this text doesn't")}) end end @@ -125,28 +117,28 @@ describe 'GitLab Markdown', feature: true do describe 'HTML::Pipeline' do describe 'SanitizationFilter' do it 'uses a permissive whitelist' do - expect(@doc).to have_selector('b:contains("b tag")') - expect(@doc).to have_selector('em:contains("em tag")') - expect(@doc).to have_selector('code:contains("code tag")') - expect(@doc).to have_selector('kbd:contains("s")') - expect(@doc).to have_selector('strike:contains(Emoji)') - expect(@doc).to have_selector('img[src*="smile.png"]') - expect(@doc).to have_selector('br') - expect(@doc).to have_selector('hr') + expect(doc).to have_selector('b:contains("b tag")') + expect(doc).to have_selector('em:contains("em tag")') + expect(doc).to have_selector('code:contains("code tag")') + expect(doc).to have_selector('kbd:contains("s")') + expect(doc).to have_selector('strike:contains(Emoji)') + expect(doc).to have_selector('img[src*="smile.png"]') + expect(doc).to have_selector('br') + expect(doc).to have_selector('hr') end it 'permits span elements' do - expect(@doc).to have_selector('span:contains("span tag")') + expect(doc).to have_selector('span:contains("span tag")') end it 'permits table alignment' do - expect(@doc.at_css('th:contains("Header")')['style']).to eq 'text-align: center' - expect(@doc.at_css('th:contains("Row")')['style']).to eq 'text-align: right' - expect(@doc.at_css('th:contains("Example")')['style']).to eq 'text-align: left' + expect(doc.at_css('th:contains("Header")')['style']).to eq 'text-align: center' + expect(doc.at_css('th:contains("Row")')['style']).to eq 'text-align: right' + expect(doc.at_css('th:contains("Example")')['style']).to eq 'text-align: left' - expect(@doc.at_css('td:contains("Foo")')['style']).to eq 'text-align: center' - expect(@doc.at_css('td:contains("Bar")')['style']).to eq 'text-align: right' - expect(@doc.at_css('td:contains("Baz")')['style']).to eq 'text-align: left' + expect(doc.at_css('td:contains("Foo")')['style']).to eq 'text-align: center' + expect(doc.at_css('td:contains("Bar")')['style']).to eq 'text-align: right' + expect(doc.at_css('td:contains("Baz")')['style']).to eq 'text-align: left' end it 'removes `rel` attribute from links' do @@ -155,12 +147,12 @@ describe 'GitLab Markdown', feature: true do end it "removes `href` from `a` elements if it's fishy" do - expect(@doc).not_to have_selector('a[href*="javascript"]') + expect(doc).not_to have_selector('a[href*="javascript"]') end end describe 'Escaping' do - let(:table) { @doc.css('table').last.at_css('tbody') } + let(:table) { doc.css('table').last.at_css('tbody') } it 'escapes non-tag angle brackets' do expect(table.at_xpath('.//tr[1]/td[3]').inner_html).to eq '1 < 3 & 5' @@ -169,28 +161,28 @@ describe 'GitLab Markdown', feature: true do describe 'Edge Cases' do it 'allows markup inside link elements' do - expect(@doc.at_css('a[href="#link-emphasis"]').to_html). + expect(doc.at_css('a[href="#link-emphasis"]').to_html). to eq %{text} - expect(@doc.at_css('a[href="#link-strong"]').to_html). + expect(doc.at_css('a[href="#link-strong"]').to_html). to eq %{text} - expect(@doc.at_css('a[href="#link-code"]').to_html). + expect(doc.at_css('a[href="#link-code"]').to_html). to eq %{text} end end describe 'EmojiFilter' do it 'parses Emoji' do - expect(@doc).to have_selector('img.emoji', count: 10) + expect(doc).to have_selector('img.emoji', count: 10) end end describe 'TableOfContentsFilter' do it 'creates anchors inside header elements' do - expect(@doc).to have_selector('h1 a#gitlab-markdown') - expect(@doc).to have_selector('h2 a#markdown') - expect(@doc).to have_selector('h3 a#autolinkfilter') + expect(doc).to have_selector('h1 a#gitlab-markdown') + expect(doc).to have_selector('h2 a#markdown') + expect(doc).to have_selector('h3 a#autolinkfilter') end end @@ -249,7 +241,7 @@ describe 'GitLab Markdown', feature: true do describe 'ReferenceFilter' do it 'handles references in headers' do - header = @doc.at_css('#reference-filters-eg-1').parent + header = doc.at_css('#reference-filters-eg-1').parent expect(header.css('a').size).to eq 2 end @@ -304,6 +296,15 @@ describe 'GitLab Markdown', feature: true do end end end + + # `markdown` calls these two methods + def current_user + @feat.user + end + + def user_color_scheme_class + :white + end end # This is a helper class used by the GitLab Markdown feature spec From 3cafa74387d707dac37d0e81bf2bb194e94957e4 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Mon, 20 Jul 2015 22:31:05 -0400 Subject: [PATCH 49/79] Use aggregate_failures where appropriate --- spec/features/markdown_spec.rb | 85 +++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 33 deletions(-) diff --git a/spec/features/markdown_spec.rb b/spec/features/markdown_spec.rb index f1be4e49c8..dadb1c3589 100644 --- a/spec/features/markdown_spec.rb +++ b/spec/features/markdown_spec.rb @@ -81,9 +81,12 @@ describe 'GitLab Markdown', feature: true do describe 'Tables' do it 'parses table Markdown' do body = get_section('tables') - expect(body).to have_selector('th:contains("Header")') - expect(body).to have_selector('th:contains("Row")') - expect(body).to have_selector('th:contains("Example")') + + aggregate_failures do + expect(body).to have_selector('th:contains("Header")') + expect(body).to have_selector('th:contains("Row")') + expect(body).to have_selector('th:contains("Example")') + end end it 'allows Markdown in tables' do @@ -94,8 +97,10 @@ describe 'GitLab Markdown', feature: true do describe 'Fenced Code Blocks' do it 'parses fenced code blocks' do - expect(doc).to have_selector('pre.code.highlight.white.c') - expect(doc).to have_selector('pre.code.highlight.white.python') + aggregate_failures do + expect(doc).to have_selector('pre.code.highlight.white.c') + expect(doc).to have_selector('pre.code.highlight.white.python') + end end end @@ -108,8 +113,11 @@ describe 'GitLab Markdown', feature: true do describe 'Superscript' do it 'parses superscript' do body = get_section('superscript') - expect(body.to_html).to match('1st') - expect(body.to_html).to match('2nd') + + aggregate_failures do + expect(body.to_html).to match('1st') + expect(body.to_html).to match('2nd') + end end end end @@ -117,14 +125,16 @@ describe 'GitLab Markdown', feature: true do describe 'HTML::Pipeline' do describe 'SanitizationFilter' do it 'uses a permissive whitelist' do - expect(doc).to have_selector('b:contains("b tag")') - expect(doc).to have_selector('em:contains("em tag")') - expect(doc).to have_selector('code:contains("code tag")') - expect(doc).to have_selector('kbd:contains("s")') - expect(doc).to have_selector('strike:contains(Emoji)') - expect(doc).to have_selector('img[src*="smile.png"]') - expect(doc).to have_selector('br') - expect(doc).to have_selector('hr') + aggregate_failures do + expect(doc).to have_selector('b:contains("b tag")') + expect(doc).to have_selector('em:contains("em tag")') + expect(doc).to have_selector('code:contains("code tag")') + expect(doc).to have_selector('kbd:contains("s")') + expect(doc).to have_selector('strike:contains(Emoji)') + expect(doc).to have_selector('img[src*="smile.png"]') + expect(doc).to have_selector('br') + expect(doc).to have_selector('hr') + end end it 'permits span elements' do @@ -132,13 +142,15 @@ describe 'GitLab Markdown', feature: true do end it 'permits table alignment' do - expect(doc.at_css('th:contains("Header")')['style']).to eq 'text-align: center' - expect(doc.at_css('th:contains("Row")')['style']).to eq 'text-align: right' - expect(doc.at_css('th:contains("Example")')['style']).to eq 'text-align: left' + aggregate_failures do + expect(doc.at_css('th:contains("Header")')['style']).to eq 'text-align: center' + expect(doc.at_css('th:contains("Row")')['style']).to eq 'text-align: right' + expect(doc.at_css('th:contains("Example")')['style']).to eq 'text-align: left' - expect(doc.at_css('td:contains("Foo")')['style']).to eq 'text-align: center' - expect(doc.at_css('td:contains("Bar")')['style']).to eq 'text-align: right' - expect(doc.at_css('td:contains("Baz")')['style']).to eq 'text-align: left' + expect(doc.at_css('td:contains("Foo")')['style']).to eq 'text-align: center' + expect(doc.at_css('td:contains("Bar")')['style']).to eq 'text-align: right' + expect(doc.at_css('td:contains("Baz")')['style']).to eq 'text-align: left' + end end it 'removes `rel` attribute from links' do @@ -161,14 +173,16 @@ describe 'GitLab Markdown', feature: true do describe 'Edge Cases' do it 'allows markup inside link elements' do - expect(doc.at_css('a[href="#link-emphasis"]').to_html). - to eq %{text} + aggregate_failures do + expect(doc.at_css('a[href="#link-emphasis"]').to_html). + to eq %{text} - expect(doc.at_css('a[href="#link-strong"]').to_html). - to eq %{text} + expect(doc.at_css('a[href="#link-strong"]').to_html). + to eq %{text} - expect(doc.at_css('a[href="#link-code"]').to_html). - to eq %{text} + expect(doc.at_css('a[href="#link-code"]').to_html). + to eq %{text} + end end end @@ -180,9 +194,11 @@ describe 'GitLab Markdown', feature: true do describe 'TableOfContentsFilter' do it 'creates anchors inside header elements' do - expect(doc).to have_selector('h1 a#gitlab-markdown') - expect(doc).to have_selector('h2 a#markdown') - expect(doc).to have_selector('h3 a#autolinkfilter') + aggregate_failures do + expect(doc).to have_selector('h1 a#gitlab-markdown') + expect(doc).to have_selector('h2 a#markdown') + expect(doc).to have_selector('h3 a#autolinkfilter') + end end end @@ -290,9 +306,12 @@ describe 'GitLab Markdown', feature: true do describe 'Task Lists' do it 'generates task lists' do body = get_section('task-lists') - expect(body).to have_selector('ul.task-list', count: 2) - expect(body).to have_selector('li.task-list-item', count: 7) - expect(body).to have_selector('input[checked]', count: 3) + + aggregate_failures do + expect(body).to have_selector('ul.task-list', count: 2) + expect(body).to have_selector('li.task-list-item', count: 7) + expect(body).to have_selector('input[checked]', count: 3) + end end end end From 97cedc5d1b023af56c035cccc5914d11bf6299de Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Mon, 20 Jul 2015 23:57:26 -0400 Subject: [PATCH 50/79] Break up SanitizationFilter feature specs --- spec/features/markdown_spec.rb | 53 ++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/spec/features/markdown_spec.rb b/spec/features/markdown_spec.rb index dadb1c3589..5adf19980d 100644 --- a/spec/features/markdown_spec.rb +++ b/spec/features/markdown_spec.rb @@ -124,29 +124,52 @@ describe 'GitLab Markdown', feature: true do describe 'HTML::Pipeline' do describe 'SanitizationFilter' do - it 'uses a permissive whitelist' do - aggregate_failures do - expect(doc).to have_selector('b:contains("b tag")') - expect(doc).to have_selector('em:contains("em tag")') - expect(doc).to have_selector('code:contains("code tag")') - expect(doc).to have_selector('kbd:contains("s")') - expect(doc).to have_selector('strike:contains(Emoji)') - expect(doc).to have_selector('img[src*="smile.png"]') - expect(doc).to have_selector('br') - expect(doc).to have_selector('hr') - end + it 'permits b elements' do + expect(doc).to have_selector('b:contains("b tag")') + end + + it 'permits em elements' do + expect(doc).to have_selector('em:contains("em tag")') + end + + it 'permits code elements' do + expect(doc).to have_selector('code:contains("code tag")') + end + + it 'permits kbd elements' do + expect(doc).to have_selector('kbd:contains("s")') + end + + it 'permits strike elements' do + expect(doc).to have_selector('strike:contains(Emoji)') + end + + it 'permits img elements' do + expect(doc).to have_selector('img[src*="smile.png"]') + end + + it 'permits br elements' do + expect(doc).to have_selector('br') + end + + it 'permits hr elements' do + expect(doc).to have_selector('hr') end it 'permits span elements' do expect(doc).to have_selector('span:contains("span tag")') end - it 'permits table alignment' do + it 'permits style attribute in th elements' do aggregate_failures do expect(doc.at_css('th:contains("Header")')['style']).to eq 'text-align: center' expect(doc.at_css('th:contains("Row")')['style']).to eq 'text-align: right' expect(doc.at_css('th:contains("Example")')['style']).to eq 'text-align: left' + end + end + it 'permits style attribute in td elements' do + aggregate_failures do expect(doc.at_css('td:contains("Foo")')['style']).to eq 'text-align: center' expect(doc.at_css('td:contains("Bar")')['style']).to eq 'text-align: right' expect(doc.at_css('td:contains("Baz")')['style']).to eq 'text-align: left' @@ -154,8 +177,7 @@ describe 'GitLab Markdown', feature: true do end it 'removes `rel` attribute from links' do - body = get_section('sanitizationfilter') - expect(body).not_to have_selector('a[rel="bookmark"]') + expect(doc).not_to have_selector('a[rel="bookmark"]') end it "removes `href` from `a` elements if it's fishy" do @@ -164,9 +186,8 @@ describe 'GitLab Markdown', feature: true do end describe 'Escaping' do - let(:table) { doc.css('table').last.at_css('tbody') } - it 'escapes non-tag angle brackets' do + table = doc.css('table').last.at_css('tbody') expect(table.at_xpath('.//tr[1]/td[3]').inner_html).to eq '1 < 3 & 5' end end From b07df8b1b05117352bc77fd4be0227dc588255fe Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Tue, 21 Jul 2015 00:21:51 -0400 Subject: [PATCH 51/79] Make links inside ignored elements unique This is to prevent false matches since the Autolink section uses about.gitlab.com as well. --- spec/fixtures/markdown.md.erb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/fixtures/markdown.md.erb b/spec/fixtures/markdown.md.erb index 02ab46c905..75f6528ccd 100644 --- a/spec/fixtures/markdown.md.erb +++ b/spec/fixtures/markdown.md.erb @@ -123,9 +123,9 @@ These are all plain text that should get turned into links: But it shouldn't autolink text inside certain tags: -- http://about.gitlab.com/ -- http://about.gitlab.com/ -- http://about.gitlab.com/ +- http://code.gitlab.com/ +- http://a.gitlab.com/ +- http://kbd.gitlab.com/ ### ExternalLinkFilter From 590fca0f06c4a21dbac90480bc6622f4da97dc86 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Tue, 21 Jul 2015 00:23:27 -0400 Subject: [PATCH 52/79] Move MarkdownFeature to its own support file This file's about to get much bigger and this removes some of the extra noise. --- spec/features/markdown_spec.rb | 115 ------------------------------- spec/support/markdown_feature.rb | 114 ++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 115 deletions(-) create mode 100644 spec/support/markdown_feature.rb diff --git a/spec/features/markdown_spec.rb b/spec/features/markdown_spec.rb index 5adf19980d..46814fdfb8 100644 --- a/spec/features/markdown_spec.rb +++ b/spec/features/markdown_spec.rb @@ -346,118 +346,3 @@ describe 'GitLab Markdown', feature: true do :white end end - -# This is a helper class used by the GitLab Markdown feature spec -# -# Because the feature spec only cares about the output of the Markdown, and the -# test setup and teardown and parsing is fairly expensive, we only want to do it -# once. Unfortunately RSpec will not let you access `let`s in a `before(:all)` -# block, so we fake it by encapsulating all the shared setup in this class. -# -# The class renders `spec/fixtures/markdown.md.erb` using ERB, allowing for -# reference to the factory-created objects. -class MarkdownFeature - include FactoryGirl::Syntax::Methods - - def initialize - DatabaseCleaner.start - end - - def teardown - DatabaseCleaner.clean - end - - def user - @user ||= create(:user) - end - - def group - unless @group - @group = create(:group) - @group.add_user(user, Gitlab::Access::DEVELOPER) - end - - @group - end - - # Direct references ---------------------------------------------------------- - - def project - @project ||= create(:project) - end - - def issue - @issue ||= create(:issue, project: project) - end - - def merge_request - @merge_request ||= create(:merge_request, :simple, source_project: project) - end - - def snippet - @snippet ||= create(:project_snippet, project: project) - end - - def commit - @commit ||= project.commit - end - - def commit_range - unless @commit_range - commit2 = project.commit('HEAD~3') - @commit_range = CommitRange.new("#{commit.id}...#{commit2.id}", project) - end - - @commit_range - end - - def simple_label - @simple_label ||= create(:label, name: 'gfm', project: project) - end - - def label - @label ||= create(:label, name: 'awaiting feedback', project: project) - end - - # Cross-references ----------------------------------------------------------- - - def xproject - unless @xproject - namespace = create(:namespace, name: 'cross-reference') - @xproject = create(:project, namespace: namespace) - @xproject.team << [user, :developer] - end - - @xproject - end - - def xissue - @xissue ||= create(:issue, project: xproject) - end - - def xmerge_request - @xmerge_request ||= create(:merge_request, :simple, source_project: xproject) - end - - def xsnippet - @xsnippet ||= create(:project_snippet, project: xproject) - end - - def xcommit - @xcommit ||= xproject.commit - end - - def xcommit_range - unless @xcommit_range - xcommit2 = xproject.commit('HEAD~2') - @xcommit_range = CommitRange.new("#{xcommit.id}...#{xcommit2.id}", xproject) - end - - @xcommit_range - end - - def raw_markdown - fixture = Rails.root.join('spec/fixtures/markdown.md.erb') - ERB.new(File.read(fixture)).result(binding) - end -end diff --git a/spec/support/markdown_feature.rb b/spec/support/markdown_feature.rb new file mode 100644 index 0000000000..5e18ffa414 --- /dev/null +++ b/spec/support/markdown_feature.rb @@ -0,0 +1,114 @@ +# This is a helper class used by the GitLab Markdown feature spec +# +# Because the feature spec only cares about the output of the Markdown, and the +# test setup and teardown and parsing is fairly expensive, we only want to do it +# once. Unfortunately RSpec will not let you access `let`s in a `before(:all)` +# block, so we fake it by encapsulating all the shared setup in this class. +# +# The class renders `spec/fixtures/markdown.md.erb` using ERB, allowing for +# reference to the factory-created objects. +class MarkdownFeature + include FactoryGirl::Syntax::Methods + + def initialize + DatabaseCleaner.start + end + + def teardown + DatabaseCleaner.clean + end + + def user + @user ||= create(:user) + end + + def group + unless @group + @group = create(:group) + @group.add_user(user, Gitlab::Access::DEVELOPER) + end + + @group + end + + # Direct references ---------------------------------------------------------- + + def project + @project ||= create(:project) + end + + def issue + @issue ||= create(:issue, project: project) + end + + def merge_request + @merge_request ||= create(:merge_request, :simple, source_project: project) + end + + def snippet + @snippet ||= create(:project_snippet, project: project) + end + + def commit + @commit ||= project.commit + end + + def commit_range + unless @commit_range + commit2 = project.commit('HEAD~3') + @commit_range = CommitRange.new("#{commit.id}...#{commit2.id}", project) + end + + @commit_range + end + + def simple_label + @simple_label ||= create(:label, name: 'gfm', project: project) + end + + def label + @label ||= create(:label, name: 'awaiting feedback', project: project) + end + + # Cross-references ----------------------------------------------------------- + + def xproject + unless @xproject + namespace = create(:namespace, name: 'cross-reference') + @xproject = create(:project, namespace: namespace) + @xproject.team << [user, :developer] + end + + @xproject + end + + def xissue + @xissue ||= create(:issue, project: xproject) + end + + def xmerge_request + @xmerge_request ||= create(:merge_request, :simple, source_project: xproject) + end + + def xsnippet + @xsnippet ||= create(:project_snippet, project: xproject) + end + + def xcommit + @xcommit ||= xproject.commit + end + + def xcommit_range + unless @xcommit_range + xcommit2 = xproject.commit('HEAD~2') + @xcommit_range = CommitRange.new("#{xcommit.id}...#{xcommit2.id}", xproject) + end + + @xcommit_range + end + + def raw_markdown + fixture = Rails.root.join('spec/fixtures/markdown.md.erb') + ERB.new(File.read(fixture)).result(binding) + end +end From 0673ca36812ac3f709032938b77e5ab6e1d63885 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Wed, 22 Jul 2015 21:22:16 -0400 Subject: [PATCH 53/79] Add RelativeLinkFilter section to Markdown fixture --- spec/fixtures/markdown.md.erb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/spec/fixtures/markdown.md.erb b/spec/fixtures/markdown.md.erb index 75f6528ccd..41d12afa9c 100644 --- a/spec/fixtures/markdown.md.erb +++ b/spec/fixtures/markdown.md.erb @@ -100,6 +100,13 @@ Markdown should be usable inside a link. Let's try! - [**text**](#link-strong) - [`text`](#link-code) +### RelativeLinkFilter + +Linking to a file relative to this project's repository should work. + +[Relative Link](doc/README.md) +![Relative Image](app/assets/images/touch-icon-ipad.png) + ### EmojiFilter Because life would be :zzz: without Emoji, right? :rocket: From 05f9a6a9c44c094d281d3dc8d80eb30c4e7dff27 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Wed, 22 Jul 2015 21:22:57 -0400 Subject: [PATCH 54/79] Update Markdown feature to allow for multiple pipelines --- spec/features/markdown_spec.rb | 238 ++++++--------------- spec/support/matchers/markdown_matchers.rb | 156 ++++++++++++++ 2 files changed, 220 insertions(+), 174 deletions(-) create mode 100644 spec/support/matchers/markdown_matchers.rb diff --git a/spec/features/markdown_spec.rb b/spec/features/markdown_spec.rb index 46814fdfb8..ddef2317e1 100644 --- a/spec/features/markdown_spec.rb +++ b/spec/features/markdown_spec.rb @@ -17,16 +17,8 @@ require 'erb' # -> Post-process HTML # -> `gfm_with_options` helper # -> HTML::Pipeline -# -> Sanitize -# -> RelativeLink -# -> Emoji -# -> Table of Contents -# -> Autolinks -# -> Rinku (http, https, ftp) -# -> Other schemes -# -> ExternalLink -# -> References -# -> TaskList +# -> SanitizationFilter +# -> Other filters, depending on pipeline # -> `html_safe` # -> Template # @@ -35,6 +27,7 @@ require 'erb' describe 'GitLab Markdown', feature: true do include Capybara::Node::Matchers include GitlabMarkdownHelper + include MarkdownMatchers # Let's only parse this thing once before(:all) do @@ -42,50 +35,37 @@ describe 'GitLab Markdown', feature: true do # `gfm_with_options` depends on a `@project` variable @project = @feat.project - - @html = markdown(@feat.raw_markdown) end after(:all) do @feat.teardown end - def doc - @doc ||= Nokogiri::HTML::DocumentFragment.parse(@html) - end - - # Given a header ID, goes to that element's parent (the header itself), then - # its next sibling element (the body). - def get_section(id) - doc.at_css("##{id}").parent.next_element + def doc(html = @html) + Nokogiri::HTML::DocumentFragment.parse(html) end # Sometimes it can be useful to see the parsed output of the Markdown document - # for debugging. Uncomment this block to write the output to - # tmp/capybara/markdown_spec.html. - # - # it 'writes to a file' do - # File.open(Rails.root.join('tmp/capybara/markdown_spec.html'), 'w') do |file| - # file.puts @html - # end - # end - - describe 'Redcarpet extensions' do - describe 'No Intra Emphasis' do - it 'does not parse emphasis inside of words' do - body = get_section('no-intra-emphasis') - expect(body.to_html).not_to match('foobarbaz') - end + # for debugging. Call this method to write the output to + # `tmp/capybara/.html`. + def write_markdown(filename = 'markdown_spec') + File.open(Rails.root.join("tmp/capybara/#{filename}.html"), 'w') do |file| + file.puts @html end + end + + # Shared behavior that all pipelines should exhibit + shared_examples 'all pipelines' do + describe 'Redcarpet extensions' do + it 'does not parse emphasis inside of words' do + expect(doc.to_html).not_to match('foobarbaz') + end - describe 'Tables' do it 'parses table Markdown' do - body = get_section('tables') - aggregate_failures do - expect(body).to have_selector('th:contains("Header")') - expect(body).to have_selector('th:contains("Row")') - expect(body).to have_selector('th:contains("Example")') + expect(doc).to have_selector('th:contains("Header")') + expect(doc).to have_selector('th:contains("Row")') + expect(doc).to have_selector('th:contains("Example")') end end @@ -93,36 +73,23 @@ describe 'GitLab Markdown', feature: true do expect(doc.at_css('td:contains("Baz")').children.to_html). to eq 'Baz' end - end - describe 'Fenced Code Blocks' do it 'parses fenced code blocks' do aggregate_failures do expect(doc).to have_selector('pre.code.highlight.white.c') expect(doc).to have_selector('pre.code.highlight.white.python') end end - end - describe 'Strikethrough' do it 'parses strikethroughs' do expect(doc).to have_selector(%{del:contains("and this text doesn't")}) end - end - describe 'Superscript' do it 'parses superscript' do - body = get_section('superscript') - - aggregate_failures do - expect(body.to_html).to match('1st') - expect(body.to_html).to match('2nd') - end + expect(doc).to have_selector('sup', count: 2) end end - end - describe 'HTML::Pipeline' do describe 'SanitizationFilter' do it 'permits b elements' do expect(doc).to have_selector('b:contains("b tag")') @@ -207,133 +174,56 @@ describe 'GitLab Markdown', feature: true do end end - describe 'EmojiFilter' do - it 'parses Emoji' do - expect(doc).to have_selector('img.emoji', count: 10) - end - end - - describe 'TableOfContentsFilter' do - it 'creates anchors inside header elements' do - aggregate_failures do - expect(doc).to have_selector('h1 a#gitlab-markdown') - expect(doc).to have_selector('h2 a#markdown') - expect(doc).to have_selector('h3 a#autolinkfilter') - end - end - end - - describe 'AutolinkFilter' do - def body - get_section('autolinkfilter').next_element - end - - # Override Capybara's `have_link` matcher to simplify our use case - def have_link(link) - super(link, href: link) - end - - it 'autolinks http://' do - expect(body).to have_link('http://about.gitlab.com/') - end - - it 'autolinks https://' do - expect(body).to have_link('https://google.com/') - end - - it 'autolinks ftp://' do - expect(body).to have_link('ftp://ftp.us.debian.org/debian/') - end - - it 'autolinks smb://' do - expect(body).to have_link('smb://foo/bar/baz') - end - - it 'autolinks irc://' do - expect(body).to have_link('irc://irc.freenode.net/git') - end - - it 'autolinks short, invalid URLs' do - expect(body).to have_link('http://localhost:3000') - end - - %w(code a kbd).each do |elem| - it "ignores links inside '#{elem}' element" do - expect(body).not_to have_selector("#{elem} a") - end - end - end - describe 'ExternalLinkFilter' do - let(:links) { get_section('externallinkfilter').next_element } - it 'adds nofollow to external link' do - expect(links.css('a').first.to_html).to match 'nofollow' + link = doc.at_css('a:contains("Google")') + expect(link.attr('rel')).to match 'nofollow' end it 'ignores internal link' do - expect(links.css('a').last.to_html).not_to match 'nofollow' + link = doc.at_css('a:contains("GitLab Root")') + expect(link.attr('rel')).not_to match 'nofollow' + end + end + end + + context 'default pipeline' do + before(:all) do + @html = markdown(@feat.raw_markdown) + end + + it_behaves_like 'all pipelines' + + it 'includes RelativeLinkFilter' do + expect(doc).to parse_relative_links + end + + it 'includes EmojiFilter' do + expect(doc).to parse_emoji + end + + it 'includes TableOfContentsFilter' do + expect(doc).to create_header_links + end + + it 'includes AutolinkFilter' do + expect(doc).to create_autolinks + end + + it 'includes all reference filters' do + aggregate_failures do + expect(doc).to reference_users + expect(doc).to reference_issues + expect(doc).to reference_merge_requests + expect(doc).to reference_snippets + expect(doc).to reference_commit_ranges + expect(doc).to reference_commits + expect(doc).to reference_labels end end - describe 'ReferenceFilter' do - it 'handles references in headers' do - header = doc.at_css('#reference-filters-eg-1').parent - - expect(header.css('a').size).to eq 2 - end - - it "handles references in Markdown" do - body = get_section('reference-filters-eg-1') - expect(body).to have_selector('em a.gfm-merge_request', count: 1) - end - - it 'parses user references' do - body = get_section('userreferencefilter') - expect(body).to have_selector('a.gfm.gfm-project_member', count: 3) - end - - it 'parses issue references' do - body = get_section('issuereferencefilter') - expect(body).to have_selector('a.gfm.gfm-issue', count: 2) - end - - it 'parses merge request references' do - body = get_section('mergerequestreferencefilter') - expect(body).to have_selector('a.gfm.gfm-merge_request', count: 2) - end - - it 'parses snippet references' do - body = get_section('snippetreferencefilter') - expect(body).to have_selector('a.gfm.gfm-snippet', count: 2) - end - - it 'parses commit range references' do - body = get_section('commitrangereferencefilter') - expect(body).to have_selector('a.gfm.gfm-commit_range', count: 2) - end - - it 'parses commit references' do - body = get_section('commitreferencefilter') - expect(body).to have_selector('a.gfm.gfm-commit', count: 2) - end - - it 'parses label references' do - body = get_section('labelreferencefilter') - expect(body).to have_selector('a.gfm.gfm-label', count: 3) - end - end - - describe 'Task Lists' do - it 'generates task lists' do - body = get_section('task-lists') - - aggregate_failures do - expect(body).to have_selector('ul.task-list', count: 2) - expect(body).to have_selector('li.task-list-item', count: 7) - expect(body).to have_selector('input[checked]', count: 3) - end - end + it 'includes TaskListFilter' do + expect(doc).to parse_task_lists end end diff --git a/spec/support/matchers/markdown_matchers.rb b/spec/support/matchers/markdown_matchers.rb new file mode 100644 index 0000000000..9df226c3af --- /dev/null +++ b/spec/support/matchers/markdown_matchers.rb @@ -0,0 +1,156 @@ +# MarkdownMatchers +# +# Custom matchers for our custom HTML::Pipeline filters. These are used to test +# that specific filters are or are not used by our defined pipelines. +# +# Must be included manually. +module MarkdownMatchers + extend RSpec::Matchers::DSL + include Capybara::Node::Matchers + + # RelativeLinkFilter + matcher :parse_relative_links do + set_default_markdown_messages + + match do |actual| + link = actual.at_css('a:contains("Relative Link")') + image = actual.at_css('img[alt="Relative Image"]') + + expect(link['href']).to end_with('master/doc/README.md') + expect(image['src']).to end_with('master/app/assets/images/touch-icon-ipad.png') + end + end + + # EmojiFilter + matcher :parse_emoji do + set_default_markdown_messages + + match do |actual| + expect(actual).to have_selector('img.emoji', count: 10) + end + end + + # TableOfContentsFilter + matcher :create_header_links do + set_default_markdown_messages + + match do |actual| + expect(actual).to have_selector('h1 a#gitlab-markdown') + expect(actual).to have_selector('h2 a#markdown') + expect(actual).to have_selector('h3 a#autolinkfilter') + end + end + + # AutolinkFilter + matcher :create_autolinks do + def have_autolink(link) + have_link(link, href: link) + end + + set_default_markdown_messages + + match do |actual| + expect(actual).to have_autolink('http://about.gitlab.com/') + expect(actual).to have_autolink('https://google.com/') + expect(actual).to have_autolink('ftp://ftp.us.debian.org/debian/') + expect(actual).to have_autolink('smb://foo/bar/baz') + expect(actual).to have_autolink('irc://irc.freenode.net/git') + expect(actual).to have_autolink('http://localhost:3000') + + %w(code a kbd).each do |elem| + expect(body).not_to have_selector("#{elem} a") + end + end + end + + # UserReferenceFilter + matcher :reference_users do + set_default_markdown_messages + + match do |actual| + expect(actual).to have_selector('a.gfm.gfm-project_member', count: 3) + end + end + + # IssueReferenceFilter + matcher :reference_issues do + set_default_markdown_messages + + match do |actual| + expect(actual).to have_selector('a.gfm.gfm-issue', count: 3) + end + end + + # MergeRequestReferenceFilter + matcher :reference_merge_requests do + set_default_markdown_messages + + match do |actual| + expect(actual).to have_selector('a.gfm.gfm-merge_request', count: 3) + expect(actual).to have_selector('em a.gfm-merge_request') + end + end + + # SnippetReferenceFilter + matcher :reference_snippets do + set_default_markdown_messages + + match do |actual| + expect(actual).to have_selector('a.gfm.gfm-snippet', count: 2) + end + end + + # CommitRangeReferenceFilter + matcher :reference_commit_ranges do + set_default_markdown_messages + + match do |actual| + expect(actual).to have_selector('a.gfm.gfm-commit_range', count: 2) + end + end + + # CommitReferenceFilter + matcher :reference_commits do + set_default_markdown_messages + + match do |actual| + expect(actual).to have_selector('a.gfm.gfm-commit', count: 2) + end + end + + # LabelReferenceFilter + matcher :reference_labels do + set_default_markdown_messages + + match do |actual| + expect(actual).to have_selector('a.gfm.gfm-label', count: 3) + end + end + + # TaskListFilter + matcher :parse_task_lists do + set_default_markdown_messages + + match do |actual| + expect(actual).to have_selector('ul.task-list', count: 2) + expect(actual).to have_selector('li.task-list-item', count: 7) + expect(actual).to have_selector('input[checked]', count: 3) + end + end +end + +# Monkeypatch the matcher DSL so that we can reduce some noisy duplication for +# setting the failure messages for these matchers +module RSpec::Matchers::DSL::Macros + def set_default_markdown_messages + failure_message do + # expected to parse emoji, but didn't + "expected to #{description}, but didn't" + end + + failure_message_when_negated do + # expected not to parse task lists, but did + "expected not to #{description}, but did" + end + end +end From 8c957b54f5a70d07a0c70f15c84cdf9fc7eb0f23 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Tue, 28 Jul 2015 23:27:08 -0400 Subject: [PATCH 55/79] Fix setup/teardown for Markdown feature spec Prior, CI seemed to be freezing after running these specs. --- spec/features/markdown_spec.rb | 25 +++++++++---------------- spec/support/markdown_feature.rb | 8 -------- 2 files changed, 9 insertions(+), 24 deletions(-) diff --git a/spec/features/markdown_spec.rb b/spec/features/markdown_spec.rb index ddef2317e1..859a62f740 100644 --- a/spec/features/markdown_spec.rb +++ b/spec/features/markdown_spec.rb @@ -29,22 +29,6 @@ describe 'GitLab Markdown', feature: true do include GitlabMarkdownHelper include MarkdownMatchers - # Let's only parse this thing once - before(:all) do - @feat = MarkdownFeature.new - - # `gfm_with_options` depends on a `@project` variable - @project = @feat.project - end - - after(:all) do - @feat.teardown - end - - def doc(html = @html) - Nokogiri::HTML::DocumentFragment.parse(html) - end - # Sometimes it can be useful to see the parsed output of the Markdown document # for debugging. Call this method to write the output to # `tmp/capybara/.html`. @@ -54,6 +38,10 @@ describe 'GitLab Markdown', feature: true do end end + def doc(html = @html) + Nokogiri::HTML::DocumentFragment.parse(html) + end + # Shared behavior that all pipelines should exhibit shared_examples 'all pipelines' do describe 'Redcarpet extensions' do @@ -189,6 +177,11 @@ describe 'GitLab Markdown', feature: true do context 'default pipeline' do before(:all) do + @feat = MarkdownFeature.new + + # `gfm_with_options` depends on a `@project` variable + @project = @feat.project + @html = markdown(@feat.raw_markdown) end diff --git a/spec/support/markdown_feature.rb b/spec/support/markdown_feature.rb index 5e18ffa414..2a868aed73 100644 --- a/spec/support/markdown_feature.rb +++ b/spec/support/markdown_feature.rb @@ -10,14 +10,6 @@ class MarkdownFeature include FactoryGirl::Syntax::Methods - def initialize - DatabaseCleaner.start - end - - def teardown - DatabaseCleaner.clean - end - def user @user ||= create(:user) end From f736721c5bb8f1f6031d36cc726cbd11cc499a72 Mon Sep 17 00:00:00 2001 From: Stefan Tatschner Date: Sun, 28 Jun 2015 20:45:40 +0200 Subject: [PATCH 56/79] Replace Rugments with Rouge I have mainly created the rugments fork for the purpose of improving gitlab's highlighting. Nowadays IMO it works way better than the old highlight.js solution. But the development is stuck on my side because of a couple of personal reasons: * I have finished my studies; last months I was writing my master thesis. So there was a huge time problem. I am sorry for that. * I had to move to Munich due to getting a (paid) job. Searching a flat here is horrible... :) * Last but not least, maintaining the same code base in two seperate projects is a mess. I have decided to switch back to rouge due to several reasons: * In the beginning I was quite motivated, but since I start working on my new job next week, the best solution IMO is switching back to upstream rouge. * Rouge is continously improving: https://github.com/jneen/rouge/blob/master/CHANGELOG.md http://rouge.jneen.net/ * There should be absolutely no regressions with this change. Most likely this pull request will almost fix some minor bugs. * One less gem in gitlab is a good thing. since Gitlab is quite a huge bundle of gems. Reducing complexity should be a major milestone. Thanks a lot to @stanhu and @jneen for the review! --- Gemfile | 1 - Gemfile.lock | 2 -- app/helpers/blob_helper.rb | 8 ++++---- app/helpers/emails_helper.rb | 4 ++-- lib/redcarpet/render/gitlab_html.rb | 8 ++++---- 5 files changed, 10 insertions(+), 13 deletions(-) diff --git a/Gemfile b/Gemfile index 8552e731bb..1c49a60379 100644 --- a/Gemfile +++ b/Gemfile @@ -272,4 +272,3 @@ end gem "newrelic_rpm" gem 'octokit', '3.7.0' -gem "rugments", "~> 1.0.0.beta8" diff --git a/Gemfile.lock b/Gemfile.lock index bef67884c3..f5c547f024 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -579,7 +579,6 @@ GEM rubyntlm (0.5.0) rubypants (0.2.0) rugged (0.22.2) - rugments (1.0.0.beta8) safe_yaml (1.0.4) sanitize (2.1.0) nokogiri (>= 1.4.4) @@ -836,7 +835,6 @@ DEPENDENCIES rqrcode-rails3 rspec-rails (~> 3.3.0) rubocop (= 0.28.0) - rugments (~> 1.0.0.beta8) sanitize (~> 2.0) sass-rails (~> 4.0.5) sdoc diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index 50df380170..f626381805 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -1,6 +1,6 @@ module BlobHelper def highlight(blob_name, blob_content, nowrap: false, continue: false) - @formatter ||= Rugments::Formatters::HTML.new( + @formatter ||= Rouge::Formatters::HTMLGitlab.new( nowrap: nowrap, cssclass: 'code highlight', lineanchors: true, @@ -8,11 +8,11 @@ module BlobHelper ) begin - @lexer ||= Rugments::Lexer.guess(filename: blob_name, source: blob_content).new + @lexer ||= Rouge::Lexer.guess(filename: blob_name, source: blob_content) result = @formatter.format(@lexer.lex(blob_content, continue: continue)).html_safe rescue - lexer = Rugments::Lexers::PlainText - result = @formatter.format(lexer.lex(blob_content)).html_safe + @lexer = Rouge::Lexers::PlainText + result = @formatter.format(@lexer.lex(blob_content)).html_safe end result diff --git a/app/helpers/emails_helper.rb b/app/helpers/emails_helper.rb index 128de18bc4..45788ba95a 100644 --- a/app/helpers/emails_helper.rb +++ b/app/helpers/emails_helper.rb @@ -31,8 +31,8 @@ module EmailsHelper end def color_email_diff(diffcontent) - formatter = Rugments::Formatters::HTML.new(cssclass: "highlight", inline_theme: :github) - lexer = Rugments::Lexers::Diff.new + formatter = Rouge::Formatters::HTML.new(css_class: 'highlight', inline_theme: 'github') + lexer = Rouge::Lexers::Diff raw formatter.format(lexer.lex(diffcontent)) end diff --git a/lib/redcarpet/render/gitlab_html.rb b/lib/redcarpet/render/gitlab_html.rb index 2f7aff03c2..04440e4f68 100644 --- a/lib/redcarpet/render/gitlab_html.rb +++ b/lib/redcarpet/render/gitlab_html.rb @@ -22,10 +22,10 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML ERB::Util.html_escape_once(text) end - # Stolen from Rugments::Plugins::Redcarpet as this module is not required - # from Rugments's gem root. + # Stolen from Rouge::Plugins::Redcarpet as this module is not required + # from Rouge's gem root. def block_code(code, language) - lexer = Rugments::Lexer.find_fancy(language, code) || Rugments::Lexers::PlainText + lexer = Rouge::Lexer.find_fancy(language, code) || Rouge::Lexers::PlainText # XXX HACK: Redcarpet strips hard tabs out of code blocks, # so we assume you're not using leading spaces that aren't tabs, @@ -34,7 +34,7 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML code.gsub!(/^ /, "\t") end - formatter = Rugments::Formatters::HTML.new( + formatter = Rouge::Formatters::HTMLGitlab.new( cssclass: "code highlight #{@color_scheme} #{lexer.tag}" ) formatter.format(lexer.lex(code)) From 00ff84d3c02e551cb7c4be3f71e1836e9f5abce2 Mon Sep 17 00:00:00 2001 From: Stefan Tatschner Date: Sun, 28 Jun 2015 20:42:41 +0200 Subject: [PATCH 57/79] Add HTMLGitlab formatter This custom formatter for rouge is needed to generate HTML output specifically for gitlab. Since its usecase is mostly suitable for gitlab it had been rejected upstream: https://github.com/jneen/rouge/pull/268 Thanks a lot to @stanhu, @jneen and @tsigo for review! --- app/helpers/blob_helper.rb | 2 +- lib/rouge/formatters/html_gitlab.rb | 168 ++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 lib/rouge/formatters/html_gitlab.rb diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index f626381805..77d99140c4 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -8,7 +8,7 @@ module BlobHelper ) begin - @lexer ||= Rouge::Lexer.guess(filename: blob_name, source: blob_content) + @lexer ||= Rouge::Lexer.guess(filename: blob_name, source: blob_content).new result = @formatter.format(@lexer.lex(blob_content, continue: continue)).html_safe rescue @lexer = Rouge::Lexers::PlainText diff --git a/lib/rouge/formatters/html_gitlab.rb b/lib/rouge/formatters/html_gitlab.rb new file mode 100644 index 0000000000..485af6832d --- /dev/null +++ b/lib/rouge/formatters/html_gitlab.rb @@ -0,0 +1,168 @@ +require 'cgi' + +module Rouge + module Formatters + class HTMLGitlab < Rouge::Formatter + tag 'html_gitlab' + + # Creates a new Rouge::Formatter::HTMLGitlab instance. + # + # [+nowrap+] If set to True, don't wrap the output at all, not + # even inside a

 tag (default: false).
+      # [+cssclass+]        CSS class for the wrapping 
tag + # (default: 'highlight'). + # [+linenos+] If set to 'table', output line numbers as a table + # with two cells, one containing the line numbers, + # the other the whole code. This is copy paste friendly, + # but may cause alignment problems with some browsers + # or fonts. If set to 'inline', the line numbers will + # be integrated in the
 tag that contains
+      #                     the code (default: nil).
+      # [+linenostart+]     The line number for the first line (default: 1).
+      # [+lineanchors+]     If set to true the formatter will wrap each output
+      #                     line in an anchor tag with a name of L-linenumber.
+      #                     This allows easy linking to certain lines
+      #                     (default: false).
+      # [+lineanchorsid+]   If lineanchors is true the name of the anchors can
+      #                     be changed with lineanchorsid to e.g. foo-linenumber
+      #                     (default: 'L').
+      # [+anchorlinenos+]   If set to true, will wrap line numbers in 
+      #                     tags. Used in combination with linenos and lineanchors
+      #                     (default: false).
+      # [+inline_theme+]    Inline CSS styles for the 
 tag (default: false).
+      def initialize(
+          nowrap: false,
+          cssclass: 'highlight',
+          linenos: nil,
+          linenostart: 1,
+          lineanchors: false,
+          lineanchorsid: 'L',
+          anchorlinenos: false,
+          inline_theme: nil
+        )
+        @nowrap = nowrap
+        @cssclass = cssclass
+        @linenos = linenos
+        @linenostart = linenostart
+        @lineanchors = lineanchors
+        @lineanchorsid = lineanchorsid
+        @anchorlinenos = anchorlinenos
+        @inline_theme = Theme.find(@inline_theme).new if @inline_theme.is_a?(String)
+      end
+
+      def render(tokens)
+        case @linenos
+        when 'table'
+          render_tableized(tokens)
+        when 'inline'
+          render_untableized(tokens)
+        else
+          render_untableized(tokens)
+        end
+      end
+
+      alias_method :format, :render
+
+      private
+
+      def render_untableized(tokens)
+        data = process_tokens(tokens)
+
+        html = ''
+        html << "
" unless @nowrap
+        html << wrap_lines(data[:code])
+        html << "
\n" unless @nowrap + html + end + + def render_tableized(tokens) + data = process_tokens(tokens) + + html = '' + html << "
" unless @nowrap + html << '' + html << "' + html << "' + html << '
"
+        html << wrap_linenos(data[:numbers])
+        html << '
"
+        html << wrap_lines(data[:code])
+        html << '
' + html << '
' unless @nowrap + html + end + + def process_tokens(tokens) + num_lines = 0 + last_val = '' + rendered = '' + + tokens.each do |tok, val| + last_val = val + num_lines += val.scan(/\n/).size + rendered << span(tok, val) + end + + numbers = (@linenostart..num_lines + @linenostart - 1).to_a + + { numbers: numbers, code: rendered } + end + + def wrap_linenos(numbers) + if @anchorlinenos + numbers.map! do |number| + "
#{number}" + end + end + numbers.join("\n") + end + + def wrap_lines(rendered) + if @lineanchors + lines = rendered.split("\n") + lines = lines.each_with_index.map do |line, index| + number = index + @linenostart + + if @linenos == 'inline' + "" \ + "#{number}" \ + "#{line}" \ + '' + else + "#{line}" \ + '' + end + end + lines.join("\n") + else + if @linenos == 'inline' + lines = rendered.split("\n") + lines = lines.each_with_index.map do |line, index| + number = index + @linenostart + "#{number}#{line}" + end + lines.join("\n") + else + rendered + end + end + end + + def span(tok, val) + # http://stackoverflow.com/a/1600584/2587286 + val = CGI.escapeHTML(val) + + if tok.shortname.empty? + val + else + if @inline_theme + rules = @inline_theme.style_for(tok).rendered_rules + "#{val}" + else + "#{val}" + end + end + end + end + end +end From f2d4672b3803d52c7a0e58a80cd6a7e83f808ef6 Mon Sep 17 00:00:00 2001 From: Stefan Tatschner Date: Tue, 14 Jul 2015 19:10:16 +0200 Subject: [PATCH 58/79] Manually update rouge to 1.9.1 Since gollum-lib blocks rouge from updating, let's bump the version manually. The fix has already been accepted upstream: https://github.com/gollum/gollum-lib/commit/9c042ea0914a7714abbda9d89e234c8a79fba893 --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index f5c547f024..44365017ed 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -288,7 +288,7 @@ GEM github-markup (~> 1.3.1) gollum-grit_adapter (~> 0.1, >= 0.1.1) nokogiri (~> 1.6.4) - rouge (~> 1.7.4) + rouge (~> 1.9) sanitize (~> 2.1.0) stringex (~> 2.5.1) gon (5.0.1) @@ -536,7 +536,7 @@ GEM netrc (~> 0.7) rinku (1.7.3) rotp (1.6.1) - rouge (1.7.7) + rouge (1.9.1) rqrcode (0.4.2) rqrcode-rails3 (0.1.7) rqrcode (>= 0.4.2) From e72a9685f3298536568e885afb1d5dabd9b315c5 Mon Sep 17 00:00:00 2001 From: Daryl Chan Date: Sat, 25 Jul 2015 17:51:22 +0800 Subject: [PATCH 59/79] Added tags to disable autocapitalize and autocorrect on login field - Updated CHANGELOG --- CHANGELOG | 1 + app/views/devise/sessions/_new_base.html.haml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index b0811db1f7..ec61759cd0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -18,6 +18,7 @@ v 7.14.0 (unreleased) - Add support for destroying project milestones (Stan Hu) - Add fetch command to the MR page - Fix bug causing Bitbucket importer to crash when OAuth application had been removed. + - Disabled autocapitalize and autocorrect on login field (Daryl Chan) v 7.13.1 - Fix: Label modifications are not reflected in existing notes and in the issue list diff --git a/app/views/devise/sessions/_new_base.html.haml b/app/views/devise/sessions/_new_base.html.haml index 54a3972677..9f5520603c 100644 --- a/app/views/devise/sessions/_new_base.html.haml +++ b/app/views/devise/sessions/_new_base.html.haml @@ -1,5 +1,5 @@ = form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| - = f.text_field :login, class: "form-control top", placeholder: "Username or Email", autofocus: "autofocus" + = f.text_field :login, class: "form-control top", placeholder: "Username or Email", autofocus: "autofocus", autocapitalize: "off", autocorrect: "off" = f.password_field :password, class: "form-control bottom", placeholder: "Password" - if devise_mapping.rememberable? .remember-me.checkbox From c5aae3077335ab0eaafb73f51548d4c85413a1d1 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Wed, 29 Jul 2015 11:18:55 +0200 Subject: [PATCH 60/79] Set internal backup directory modes on create This sidesteps problems with running 'chmod' on some CIFS mounts. --- lib/backup/database.rb | 2 +- lib/backup/manager.rb | 2 -- lib/backup/repository.rb | 2 +- lib/backup/uploads.rb | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/backup/database.rb b/lib/backup/database.rb index c5a5396cbb..8450019980 100644 --- a/lib/backup/database.rb +++ b/lib/backup/database.rb @@ -7,7 +7,7 @@ module Backup def initialize @config = YAML.load_file(File.join(Rails.root,'config','database.yml'))[Rails.env] @db_dir = File.join(Gitlab.config.backup.path, 'db') - FileUtils.mkdir_p(@db_dir) unless Dir.exists?(@db_dir) + FileUtils.mkdir_p(@db_dir, mode: 0700)unless Dir.exists?(@db_dir) end def dump diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb index 6fa2079d1a..9ae4b34643 100644 --- a/lib/backup/manager.rb +++ b/lib/backup/manager.rb @@ -16,8 +16,6 @@ module Backup file << s.to_yaml.gsub(/^---\n/,'') end - FileUtils.chmod(0700, folders_to_backup) - # create archive $progress.print "Creating backup archive: #{tar_file} ... " orig_umask = File.umask(0077) diff --git a/lib/backup/repository.rb b/lib/backup/repository.rb index dfb2da9f84..36d43d6298 100644 --- a/lib/backup/repository.rb +++ b/lib/backup/repository.rb @@ -130,7 +130,7 @@ module Backup def prepare FileUtils.rm_rf(backup_repos_path) - FileUtils.mkdir_p(backup_repos_path) + FileUtils.mkdir_p(backup_repos_path, mode: 0700) end def silent diff --git a/lib/backup/uploads.rb b/lib/backup/uploads.rb index bf43610acf..ed445f7908 100644 --- a/lib/backup/uploads.rb +++ b/lib/backup/uploads.rb @@ -10,7 +10,7 @@ module Backup # Copy uploads from public/uploads to backup/uploads def dump - FileUtils.mkdir_p(backup_uploads_dir) + FileUtils.mkdir_p(backup_uploads_dir, mode: 0700) FileUtils.cp_r(app_uploads_dir, backup_dir) end From 545f389910f738e021e2fbc9b5a1e0bcca45b580 Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Wed, 29 Jul 2015 12:10:10 +0300 Subject: [PATCH 61/79] update changelog --- CHANGELOG | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b0811db1f7..7ca450d423 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,8 +4,6 @@ v 7.14.0 (unreleased) - Upgrade gitlab_git to version 7.2.6 to fix Error 500 when creating network graphs (Stan Hu) - Fix URL used for refreshing notes if relative_url is present (Bartłomiej Święcki) - Fix commit data retrieval when branch name has single quotes (Stan Hu) - - Fix Error 500 when browsing projects with no HEAD (Stan Hu) - - Add rake task 'gitlab:update_commit_count' (Daniel Gerhardt) - Fix full screen mode for snippet comments (Daniel Gerhardt) - Fix 404 error in files view after deleting the last file in a repository (Stan Hu) - Fix the "Reload with full diff" URL button (Stan Hu) @@ -18,6 +16,17 @@ v 7.14.0 (unreleased) - Add support for destroying project milestones (Stan Hu) - Add fetch command to the MR page - Fix bug causing Bitbucket importer to crash when OAuth application had been removed. + - Add fetch command to the MR page. + +v 7.13.2 + - Fix randomly failed spec + - Create project services on Project creation + - Add admin_merge_request ability to Developer level and up + - Fix Error 500 when browsing projects with no HEAD (Stan Hu) + - Fix labels / assignee / milestone for the merge requests when issues are disabled + - Show the first tab automatically on MergeRequests#new + - Add rake task 'gitlab:update_commit_count' (Daniel Gerhardt) + - Fix Gmail Actions v 7.13.1 - Fix: Label modifications are not reflected in existing notes and in the issue list @@ -28,6 +37,7 @@ v 7.13.1 - Fix: ActionView::Template::Error - Fix: "Create Merge Request" isn't always shown in event for newly pushed branch - Fix bug causing "Remove source-branch" option not to work for merge requests from the same project. + - Render Note field hints consistently for "new" and "edit" forms v 7.13.0 - Remove repository graph log to fix slow cache updates after push event (Stan Hu) From 05cca9342b3cff4e9f2785a062822cd3af9fcdd4 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 29 Jul 2015 12:03:53 +0200 Subject: [PATCH 62/79] Use URL helpers --- app/models/group.rb | 4 ++-- app/models/project.rb | 2 +- app/models/user.rb | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/models/group.rb b/app/models/group.rb index adcbbec465..885d3b1e5a 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -17,7 +17,7 @@ require 'carrierwave/orm/activerecord' require 'file_size_validator' class Group < Namespace - include Gitlab::ConfigHelper + include Rails.application.routes.url_helpers include Referable has_many :group_members, dependent: :destroy, as: :source, class_name: 'GroupMember' @@ -64,7 +64,7 @@ class Group < Namespace end def web_url - [gitlab_config.url, "groups", self.path].join('/') + group_url(self) end def owners diff --git a/app/models/project.rb b/app/models/project.rb index ff372ea9aa..0608133b2c 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -316,7 +316,7 @@ class Project < ActiveRecord::Base end def web_url - [gitlab_config.url, path_with_namespace].join('/') + namespace_project_url(self.namespace, self) end def web_url_without_protocol diff --git a/app/models/user.rb b/app/models/user.rb index 00a37cd913..6dd2271abe 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -67,6 +67,7 @@ class User < ActiveRecord::Base include Gitlab::ConfigHelper include Gitlab::CurrentSettings + include Rails.application.routes.url_helpers include Referable include Sortable include TokenAuthenticatable @@ -638,7 +639,7 @@ class User < ActiveRecord::Base end def web_url - [gitlab_config.url, "u", self.username].join('/') + user_url(self) end def all_emails From d953f6927cfa605d0bc336b09a25bde2a483b3ba Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 29 Jul 2015 12:15:21 +0200 Subject: [PATCH 63/79] Restore Leave button on dashboard groups page --- app/views/dashboard/groups/index.html.haml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/views/dashboard/groups/index.html.haml b/app/views/dashboard/groups/index.html.haml index 6ef4d752ac..0a354373b9 100644 --- a/app/views/dashboard/groups/index.html.haml +++ b/app/views/dashboard/groups/index.html.haml @@ -23,10 +23,9 @@ %i.fa.fa-cogs Settings - - if can?(current_user, :admin_group_member, group) - = link_to leave_group_group_members_path(group), data: { confirm: leave_group_message(group.name) }, method: :delete, class: "btn-sm btn btn-grouped", title: 'Leave this group' do - %i.fa.fa-sign-out - Leave + = link_to leave_group_group_members_path(group), data: { confirm: leave_group_message(group.name) }, method: :delete, class: "btn-sm btn btn-grouped", title: 'Leave this group' do + %i.fa.fa-sign-out + Leave = image_tag group_icon(group), class: "avatar s40 avatar-tile hidden-xs" = link_to group, class: 'group-name' do From 72c552c2d4ea985a9ab1470ba2e44fc7e52673d9 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 29 Jul 2015 13:23:28 +0200 Subject: [PATCH 64/79] Fix specs --- app/models/project.rb | 2 +- spec/models/project_spec.rb | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/app/models/project.rb b/app/models/project.rb index 0608133b2c..2d02996255 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -571,7 +571,7 @@ class Project < ActiveRecord::Base end def http_url_to_repo - [gitlab_config.url, '/', path_with_namespace, '.git'].join('') + "#{web_url}.git" end # Check if current branch name is marked as protected in the system diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 63091e913f..1ffd92b9bd 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -111,14 +111,20 @@ describe Project do expect(project.url_to_repo).to eq(Gitlab.config.gitlab_shell.ssh_path_prefix + 'somewhere.git') end - it 'returns the full web URL for this repo' do - project = Project.new(path: 'somewhere') - expect(project.web_url).to eq("#{Gitlab.config.gitlab.url}/somewhere") + describe "#web_url" do + let(:project) { create(:empty_project, path: "somewhere") } + + it 'returns the full web URL for this repo' do + expect(project.web_url).to eq("#{Gitlab.config.gitlab.url}/#{project.namespace.path}/somewhere") + end end - it 'returns the web URL without the protocol for this repo' do - project = Project.new(path: 'somewhere') - expect(project.web_url_without_protocol).to eq("#{Gitlab.config.gitlab.url.split('://')[1]}/somewhere") + describe "#web_url_without_protocol" do + let(:project) { create(:empty_project, path: "somewhere") } + + it 'returns the web URL without the protocol for this repo' do + expect(project.web_url_without_protocol).to eq("#{Gitlab.config.gitlab.url.split('://')[1]}/#{project.namespace.path}/somewhere") + end end describe 'last_activity methods' do From 3e9b612306e026e7a91bd1bc5e52cc6f0c9c48de Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Thu, 23 Jul 2015 23:52:21 -0700 Subject: [PATCH 65/79] Check that project was actually created rather than just validated in import:repos task Add gitlab-shell to error message to give user a clue that something may be wrong there. Ran into this in #2082. User was told that repositories were created when they were not due to hooks symlink being wrong. --- CHANGELOG | 1 + app/models/project.rb | 4 ++-- lib/tasks/gitlab/import.rake | 4 ++-- spec/services/projects/fork_service_spec.rb | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 01c59299ec..1aa3f13f16 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,7 @@ v 7.14.0 (unreleased) - Upgrade gitlab_git to version 7.2.6 to fix Error 500 when creating network graphs (Stan Hu) - Fix URL used for refreshing notes if relative_url is present (Bartłomiej Święcki) - Fix commit data retrieval when branch name has single quotes (Stan Hu) + - Check that project was actually created rather than just validated in import:repos task (Stan Hu) - Fix full screen mode for snippet comments (Daniel Gerhardt) - Fix 404 error in files view after deleting the last file in a repository (Stan Hu) - Fix the "Reload with full diff" URL button (Stan Hu) diff --git a/app/models/project.rb b/app/models/project.rb index ff372ea9aa..1800c3a7e0 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -705,14 +705,14 @@ class Project < ActiveRecord::Base ensure_satellite_exists true else - errors.add(:base, 'Failed to fork repository') + errors.add(:base, 'Failed to fork repository via gitlab-shell') false end else if gitlab_shell.add_repository(path_with_namespace) true else - errors.add(:base, 'Failed to create repository') + errors.add(:base, 'Failed to create repository via gitlab-shell') false end end diff --git a/lib/tasks/gitlab/import.rake b/lib/tasks/gitlab/import.rake index 5f83e5e8e7..c1ee271ae2 100644 --- a/lib/tasks/gitlab/import.rake +++ b/lib/tasks/gitlab/import.rake @@ -62,11 +62,11 @@ namespace :gitlab do project = Projects::CreateService.new(user, project_params).execute - if project.valid? + if project.persisted? puts " * Created #{project.name} (#{repo_path})".green else puts " * Failed trying to create #{project.name} (#{repo_path})".red - puts " Validation Errors: #{project.errors.messages}".red + puts " Errors: #{project.errors.messages}".red end end end diff --git a/spec/services/projects/fork_service_spec.rb b/spec/services/projects/fork_service_spec.rb index 439a492cea..c04e842c67 100644 --- a/spec/services/projects/fork_service_spec.rb +++ b/spec/services/projects/fork_service_spec.rb @@ -29,7 +29,7 @@ describe Projects::ForkService do it "fails due to transaction failure" do @to_project = fork_project(@from_project, @to_user, false) expect(@to_project.errors).not_to be_empty - expect(@to_project.errors[:base]).to include("Failed to fork repository") + expect(@to_project.errors[:base]).to include("Failed to fork repository via gitlab-shell") end end From 34c2867ca29e60af763bb420a308090994e68e73 Mon Sep 17 00:00:00 2001 From: Darby Date: Wed, 29 Jul 2015 12:59:50 -0700 Subject: [PATCH 66/79] Switched the otder of the SSH key form --- app/views/profiles/keys/_form.html.haml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/views/profiles/keys/_form.html.haml b/app/views/profiles/keys/_form.html.haml index f905417f0e..b76a5b636a 100644 --- a/app/views/profiles/keys/_form.html.haml +++ b/app/views/profiles/keys/_form.html.haml @@ -6,14 +6,13 @@ - @key.errors.full_messages.each do |msg| %li= msg - .form-group - = f.label :title, class: 'control-label' - .col-sm-10= f.text_field :title, class: "form-control" .form-group = f.label :key, class: 'control-label' .col-sm-10 = f.text_area :key, class: "form-control", rows: 8 - + .form-group + = f.label :title, class: 'control-label' + .col-sm-10= f.text_field :title, class: "form-control" .form-actions = f.submit 'Add key', class: "btn btn-create" From 0fac66f84d85eb072f2d96a54820ac805799c5f3 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Thu, 30 Jul 2015 01:06:16 +0300 Subject: [PATCH 67/79] Mention group and project name in flash messages upon create, update and delete. --- CHANGELOG | 1 + app/controllers/groups_controller.rb | 6 +++--- app/controllers/projects_controller.rb | 8 ++++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 01c59299ec..0cebe2519e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -17,6 +17,7 @@ v 7.14.0 (unreleased) - Add fetch command to the MR page - Fix bug causing Bitbucket importer to crash when OAuth application had been removed. - Add fetch command to the MR page. + - Mention group and project name in creation, update and deletion notices (Achilleas Pipinellis) v 7.13.2 - Fix randomly failed spec diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 901c1cdddc..784cb0f8f7 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -24,7 +24,7 @@ class GroupsController < Groups::ApplicationController if @group.save @group.add_owner(current_user) - redirect_to @group, notice: 'Group was successfully created.' + redirect_to @group, notice: "Group '#{@group.name}' was successfully created." else render action: "new" end @@ -75,7 +75,7 @@ class GroupsController < Groups::ApplicationController def update if @group.update_attributes(group_params) - redirect_to edit_group_path(@group), notice: 'Group was successfully updated.' + redirect_to edit_group_path(@group), notice: "Group '#{@group.name}' was successfully updated." else render action: "edit" end @@ -84,7 +84,7 @@ class GroupsController < Groups::ApplicationController def destroy DestroyGroupService.new(@group, current_user).execute - redirect_to root_path, notice: 'Group was removed.' + redirect_to root_path, notice: "Group '#{@group.name} was deleted." end protected diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 586359f308..dafc11d070 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -24,7 +24,7 @@ class ProjectsController < ApplicationController if @project.saved? redirect_to( project_path(@project), - notice: 'Project was successfully created.' + notice: "Project '#{@project.name}' was successfully created." ) else render 'new' @@ -36,11 +36,11 @@ class ProjectsController < ApplicationController respond_to do |format| if status - flash[:notice] = 'Project was successfully updated.' + flash[:notice] = "Project '#{@project.name}' was successfully updated." format.html do redirect_to( edit_project_path(@project), - notice: 'Project was successfully updated.' + notice: "Project '#{@project.name}' was successfully updated." ) end format.js @@ -100,7 +100,7 @@ class ProjectsController < ApplicationController return access_denied! unless can?(current_user, :remove_project, @project) ::Projects::DestroyService.new(@project, current_user, {}).execute - flash[:alert] = 'Project deleted.' + flash[:alert] = "Project '#{@project.name}' was deleted." if request.referer.include?('/admin') redirect_to admin_namespaces_projects_path From 725a891dda4beae9a365058f58bb44aebf1fc9cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Doursenaud?= Date: Wed, 29 Jul 2015 23:27:04 +0000 Subject: [PATCH 68/79] Updated Twitter OmniAuth documentation --- doc/integration/twitter.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/doc/integration/twitter.md b/doc/integration/twitter.md index fe9091ad9a..1350c8f693 100644 --- a/doc/integration/twitter.md +++ b/doc/integration/twitter.md @@ -2,9 +2,7 @@ To enable the Twitter OmniAuth provider you must register your application with Twitter. Twitter will generate a client ID and secret key for you to use. -1. Sign in to [Twitter Developers](https://dev.twitter.com/) area. - -1. Hover over the avatar in the top right corner and select "My applications." +1. Sign in to [Twitter Application Management](https://apps.twitter.com/). 1. Select "Create new app" @@ -14,18 +12,18 @@ To enable the Twitter OmniAuth provider you must register your application with - Description: Create a description. - Website: The URL to your GitLab installation. 'https://gitlab.example.com' - Callback URL: 'https://gitlab.example.com/users/auth/twitter/callback' - - Agree to the "Rules of the Road." + - Agree to the "Developer Agreement". ![Twitter App Details](twitter_app_details.png) 1. Select "Create your Twitter application." 1. Select the "Settings" tab. -1. Underneath the Callback URL check the box next to "Allow this application to be used to Sign in the Twitter." +1. Underneath the Callback URL check the box next to "Allow this application to be used to Sign in with Twitter." 1. Select "Update settings" at the bottom to save changes. -1. Select the "API Keys" tab. +1. Select the "Keys and Access Tokens" tab. 1. You should now see an API key and API secret (see screenshot). Keep this page open as you continue configuration. @@ -78,4 +76,4 @@ To enable the Twitter OmniAuth provider you must register your application with 1. Restart GitLab for the changes to take effect. -On the sign in page there should now be a Twitter icon below the regular sign in form. Click the icon to begin the authentication process. Twitter will ask the user to sign in and authorize the GitLab application. If everything goes well the user will be returned to GitLab and will be signed in. +On the sign in page there should now be a Twitter icon below the regular sign in form. Click the icon to begin the authentication process. Twitter will ask the user to sign in and authorize the GitLab application. If everything goes well the user will be returned to GitLab and will be signed in. \ No newline at end of file From 369275d63074e5d526c0d1cf404b4a3742bb1e6a Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Tue, 28 Jul 2015 18:15:23 -0700 Subject: [PATCH 69/79] Fix network graph when branch name has single quotes Closes https://github.com/gitlabhq/gitlabhq/issues/9500 --- CHANGELOG | 1 + app/controllers/projects/network_controller.rb | 4 ++++ app/views/projects/network/show.html.haml | 6 +++--- features/project/network_graph.feature | 5 +++++ features/steps/project/network_graph.rb | 14 ++++++++++++-- 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 01c59299ec..9c36822caf 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 7.14.0 (unreleased) + - Fix network graph when branch name has single quotes (Stan Hu) - Upgrade gitlab_git to version 7.2.6 to fix Error 500 when creating network graphs (Stan Hu) - Fix URL used for refreshing notes if relative_url is present (Bartłomiej Święcki) - Fix commit data retrieval when branch name has single quotes (Stan Hu) diff --git a/app/controllers/projects/network_controller.rb b/app/controllers/projects/network_controller.rb index 06aef91cad..b181c47bae 100644 --- a/app/controllers/projects/network_controller.rb +++ b/app/controllers/projects/network_controller.rb @@ -7,6 +7,10 @@ class Projects::NetworkController < Projects::ApplicationController before_action :authorize_download_code! def show + + @url = namespace_project_network_path(@project.namespace, @project, @ref, @options.merge(format: :json)) + @commit_url = namespace_project_commit_path(@project.namespace, @project, 'ae45ca32').gsub("ae45ca32", "%s") + respond_to do |format| format.html diff --git a/app/views/projects/network/show.html.haml b/app/views/projects/network/show.html.haml index a88cf16751..52b5b8b877 100644 --- a/app/views/projects/network/show.html.haml +++ b/app/views/projects/network/show.html.haml @@ -17,9 +17,9 @@ :javascript network_graph = new Network({ - url: '#{namespace_project_network_path(@project.namespace, @project, @ref, @options.merge(format: :json))}', - commit_url: '#{namespace_project_commit_path(@project.namespace, @project, 'ae45ca32').gsub("ae45ca32", "%s")}', - ref: '#{@ref}', + url: "#{escape_javascript(@url)}", + commit_url: "#{escape_javascript(@commit_url)}", + ref: "#{escape_javascript(@ref)}", commit_id: '#{@commit.id}' }) new ShortcutsNetwork(network_graph.branch_graph) diff --git a/features/project/network_graph.feature b/features/project/network_graph.feature index 8beb6043af..6cc89a15a7 100644 --- a/features/project/network_graph.feature +++ b/features/project/network_graph.feature @@ -10,6 +10,11 @@ Feature: Project Network Graph And page should select "master" in select box And page should have "master" on graph + @javascript + Scenario: I should see project network with 'test' branch + When I visit project network page on branch 'test' + Then page should have 'test' on graph + @javascript Scenario: I should switch "branch" and "tag" When I switch ref to "feature" diff --git a/features/steps/project/network_graph.rb b/features/steps/project/network_graph.rb index 992cf2734f..7a83d32a24 100644 --- a/features/steps/project/network_graph.rb +++ b/features/steps/project/network_graph.rb @@ -11,8 +11,12 @@ class Spinach::Features::ProjectNetworkGraph < Spinach::FeatureSteps # Stub Graph max_size to speed up test (10 commits vs. 650) Network::Graph.stub(max_count: 10) - project = Project.find_by(name: "Shop") - visit namespace_project_network_path(project.namespace, project, "master") + @project = Project.find_by(name: "Shop") + visit namespace_project_network_path(@project.namespace, @project, "master") + end + + step "I visit project network page on branch 'test'" do + visit namespace_project_network_path(@project.namespace, @project, "'test'") end step 'page should select "master" in select box' do @@ -29,6 +33,12 @@ class Spinach::Features::ProjectNetworkGraph < Spinach::FeatureSteps end end + step "page should have 'test' on graph" do + page.within '.network-graph' do + expect(page).to have_content "'test'" + end + end + When 'I switch ref to "feature"' do select 'feature', from: 'ref' sleep 2 From baa157926d432f404a41c31ad6514ff8d5366269 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Thu, 30 Jul 2015 10:17:34 +0200 Subject: [PATCH 70/79] Stricter mkdir's in 'rake gitlab:backup:create' --- lib/backup/database.rb | 7 +++++-- lib/backup/repository.rb | 5 ++++- lib/backup/uploads.rb | 6 +++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/backup/database.rb b/lib/backup/database.rb index 8450019980..bbb230a10f 100644 --- a/lib/backup/database.rb +++ b/lib/backup/database.rb @@ -7,7 +7,11 @@ module Backup def initialize @config = YAML.load_file(File.join(Rails.root,'config','database.yml'))[Rails.env] @db_dir = File.join(Gitlab.config.backup.path, 'db') - FileUtils.mkdir_p(@db_dir, mode: 0700)unless Dir.exists?(@db_dir) + FileUtils.rm_rf(@db_dir) + # Ensure the parent dir of @db_dir exists + FileUtils.mkdir_p(Gitlab.config.backup.path) + # Fail if somebody raced to create @db_dir before us + FileUtils.mkdir(@db_dir, mode: 0700) end def dump @@ -25,7 +29,6 @@ module Backup abort 'Backup failed' unless success $progress.print 'Compressing database ... ' - FileUtils.rm_f db_file_name_gz success = system('gzip', db_file_name) report_success(success) abort 'Backup failed: compress error' unless success diff --git a/lib/backup/repository.rb b/lib/backup/repository.rb index 36d43d6298..4d70f7883d 100644 --- a/lib/backup/repository.rb +++ b/lib/backup/repository.rb @@ -130,7 +130,10 @@ module Backup def prepare FileUtils.rm_rf(backup_repos_path) - FileUtils.mkdir_p(backup_repos_path, mode: 0700) + # Ensure the parent dir of backup_repos_path exists + FileUtils.mkdir_p(Gitlab.config.backup.path) + # Fail if somebody raced to create backup_repos_path before us + FileUtils.mkdir(backup_repos_path, mode: 0700) end def silent diff --git a/lib/backup/uploads.rb b/lib/backup/uploads.rb index ed445f7908..1f9626644e 100644 --- a/lib/backup/uploads.rb +++ b/lib/backup/uploads.rb @@ -10,7 +10,11 @@ module Backup # Copy uploads from public/uploads to backup/uploads def dump - FileUtils.mkdir_p(backup_uploads_dir, mode: 0700) + FileUtils.rm_rf(backup_uploads_dir) + # Ensure the parent dir of backup_uploads_dir exists + FileUtils.mkdir_p(Gitlab.config.backup.path) + # Fail if somebody raced to create backup_uploads_dir before us + FileUtils.mkdir(backup_uploads_dir, mode: 0700) FileUtils.cp_r(app_uploads_dir, backup_dir) end From b8066e2cd0c8ae8384b68c81ea3a6c071cd44c51 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Thu, 30 Jul 2015 11:56:15 +0200 Subject: [PATCH 71/79] No more web url --- app/models/group.rb | 5 ----- app/models/project.rb | 3 +-- app/models/user.rb | 5 ----- lib/api/entities.rb | 12 ++++++++++-- 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/app/models/group.rb b/app/models/group.rb index 885d3b1e5a..cfb8faa149 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -17,7 +17,6 @@ require 'carrierwave/orm/activerecord' require 'file_size_validator' class Group < Namespace - include Rails.application.routes.url_helpers include Referable has_many :group_members, dependent: :destroy, as: :source, class_name: 'GroupMember' @@ -63,10 +62,6 @@ class Group < Namespace end end - def web_url - group_url(self) - end - def owners @owners ||= group_members.owners.map(&:user) end diff --git a/app/models/project.rb b/app/models/project.rb index 2d02996255..99be170731 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -36,7 +36,6 @@ class Project < ActiveRecord::Base include Gitlab::ConfigHelper include Gitlab::ShellAdapter include Gitlab::VisibilityLevel - include Rails.application.routes.url_helpers include Referable include Sortable @@ -316,7 +315,7 @@ class Project < ActiveRecord::Base end def web_url - namespace_project_url(self.namespace, self) + Rails.application.routes.url_helpers.namespace_project_url(self.namespace, self) end def web_url_without_protocol diff --git a/app/models/user.rb b/app/models/user.rb index 6dd2271abe..4a10520b20 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -67,7 +67,6 @@ class User < ActiveRecord::Base include Gitlab::ConfigHelper include Gitlab::CurrentSettings - include Rails.application.routes.url_helpers include Referable include Sortable include TokenAuthenticatable @@ -638,10 +637,6 @@ class User < ActiveRecord::Base end end - def web_url - user_url(self) - end - def all_emails [self.email, *self.emails.map(&:email)] end diff --git a/lib/api/entities.rb b/lib/api/entities.rb index c1b0cece34..dcfd7a8e1a 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -5,7 +5,11 @@ module API end class UserBasic < UserSafe - expose :id, :state, :avatar_url, :web_url + expose :id, :state, :avatar_url + + expose :web_url do |user, options| + Rails.application.routes.url_helpers.user_url(user) + end end class User < UserBasic @@ -70,7 +74,11 @@ module API class Group < Grape::Entity expose :id, :name, :path, :description - expose :avatar_url, :web_url + expose :avatar_url + + expose :web_url do |group, options| + Rails.application.routes.url_helpers.group_url(group) + end end class GroupDetail < Group From 2a60b8006b1374aec998370f9cfe5b574255712f Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Thu, 30 Jul 2015 12:35:09 +0200 Subject: [PATCH 72/79] Fix Project --- app/models/project.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/project.rb b/app/models/project.rb index 99be170731..cc2b936ba2 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -432,7 +432,7 @@ class Project < ActiveRecord::Base if avatar.present? [gitlab_config.url, avatar.url].join elsif avatar_in_git - [gitlab_config.url, namespace_project_avatar_path(namespace, self)].join + Rails.application.routes.url_helpers.namespace_project_avatar_url(namespace, self) end end From feb2865fba15524c7dd1ae03274c63ae02edd152 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Thu, 30 Jul 2015 14:11:26 +0300 Subject: [PATCH 73/79] Raise alert when group is deleted. This change was made to match the project deletion. --- app/controllers/groups_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 784cb0f8f7..279c6ef0f4 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -84,7 +84,7 @@ class GroupsController < Groups::ApplicationController def destroy DestroyGroupService.new(@group, current_user).execute - redirect_to root_path, notice: "Group '#{@group.name} was deleted." + redirect_to root_path, alert: "Group '#{@group.name} was deleted." end protected From ee1710284883d4cf61fc89d5197beef63646a220 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Wed, 29 Jul 2015 09:03:15 -0700 Subject: [PATCH 74/79] Check that hooks directory exists before attempting to call realpath Closes #2121 --- lib/tasks/gitlab/check.rake | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index aed84226a2..badb47c677 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -485,7 +485,8 @@ namespace :gitlab do if project.empty_repo? puts "repository is empty".magenta - elsif File.realpath(project_hook_directory) == File.realpath(gitlab_shell_hooks_path) + elsif File.directory?(project_hook_directory) && File.directory?(gitlab_shell_hooks_path) && + (File.realpath(project_hook_directory) == File.realpath(gitlab_shell_hooks_path)) puts 'ok'.green else puts "wrong or missing hooks".red @@ -754,7 +755,7 @@ namespace :gitlab do print "Ruby version >= #{required_version} ? ... " if current_version.valid? && required_version <= current_version - puts "yes (#{current_version})".green + puts "yes (#{current_version})".green else puts "no".red try_fixing_it( @@ -772,7 +773,7 @@ namespace :gitlab do print "Git version >= #{required_version} ? ... " if current_version.valid? && required_version <= current_version - puts "yes (#{current_version})".green + puts "yes (#{current_version})".green else puts "no".red try_fixing_it( @@ -806,4 +807,3 @@ namespace :gitlab do end end end - From bd72b5bd32c64606a498066cadf9f765be059b9d Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Thu, 30 Jul 2015 13:40:30 -0700 Subject: [PATCH 75/79] Fix version for CHANGELOG entry --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index c03e5053d1..a3b1b82e0e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,7 @@ v 7.14.0 (unreleased) - Add fetch command to the MR page - Fix bug causing Bitbucket importer to crash when OAuth application had been removed. - Add fetch command to the MR page. + - Disabled autocapitalize and autocorrect on login field (Daryl Chan) v 7.13.2 - Fix randomly failed spec @@ -29,7 +30,6 @@ v 7.13.2 - Show the first tab automatically on MergeRequests#new - Add rake task 'gitlab:update_commit_count' (Daniel Gerhardt) - Fix Gmail Actions - - Disabled autocapitalize and autocorrect on login field (Daryl Chan) v 7.13.1 - Fix: Label modifications are not reflected in existing notes and in the issue list From 4e22dcb6a34f43e5b3b2700ec72b32354315adc0 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Thu, 30 Jul 2015 17:25:07 -0400 Subject: [PATCH 76/79] Add spec to RelativeLinkFilter for Unicode filenames --- lib/gitlab/markdown/relative_link_filter.rb | 13 +++++++++++-- .../gitlab/markdown/relative_link_filter_spec.rb | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/lib/gitlab/markdown/relative_link_filter.rb b/lib/gitlab/markdown/relative_link_filter.rb index 3eaceba532..30f50b8299 100644 --- a/lib/gitlab/markdown/relative_link_filter.rb +++ b/lib/gitlab/markdown/relative_link_filter.rb @@ -99,15 +99,24 @@ module Gitlab # Returns a String def path_type(path) unescaped_path = Addressable::URI.unescape(path) - if repository.tree(current_sha, unescaped_path).entries.any? + + if tree?(unescaped_path) 'tree' - elsif repository.blob_at(current_sha, unescaped_path).try(:image?) + elsif image?(unescaped_path) 'raw' else 'blob' end end + def tree?(path) + repository.tree(current_sha, path).entries.any? + end + + def image?(path) + repository.blob_at(current_sha, path).try(:image?) + end + def current_sha context[:commit].try(:id) || ref ? repository.commit(ref).try(:sha) : repository.head_commit.sha diff --git a/spec/lib/gitlab/markdown/relative_link_filter_spec.rb b/spec/lib/gitlab/markdown/relative_link_filter_spec.rb index 5ee5310825..7f4d67e403 100644 --- a/spec/lib/gitlab/markdown/relative_link_filter_spec.rb +++ b/spec/lib/gitlab/markdown/relative_link_filter_spec.rb @@ -1,3 +1,5 @@ +# encoding: UTF-8 + require 'spec_helper' module Gitlab::Markdown @@ -101,6 +103,20 @@ module Gitlab::Markdown expect(doc.at_css('a')['href']).to eq 'http://example.com' end + it 'supports Unicode filenames' do + path = 'files/images/한글.png' + escaped = Addressable::URI.escape(path) + + # Stub these methods so the file doesn't actually need to be in the repo + allow_any_instance_of(described_class).to receive(:file_exists?). + and_return(true) + allow_any_instance_of(described_class). + to receive(:image?).with(path).and_return(true) + + doc = filter(image(escaped)) + expect(doc.at_css('img')['src']).to match '/raw/' + end + context 'when requested path is a file in the repo' do let(:requested_path) { 'doc/api/README.md' } include_examples :relative_to_requested From 7ca7770e984d802f9f35579d6b5c08ad63a3052a Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Thu, 30 Jul 2015 17:27:25 -0400 Subject: [PATCH 77/79] Fix CHANGELOG entry --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 86927eae79..c1f7da82f5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,7 +3,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 7.14.0 (unreleased) - Fix network graph when branch name has single quotes (Stan Hu) - Upgrade gitlab_git to version 7.2.6 to fix Error 500 when creating network graphs (Stan Hu) - - Fix the image file that contains non-ascii character is not displayed(Hiroyuki Sato) + - Add support for Unicode filenames in relative links (Hiroyuki Sato) - Fix URL used for refreshing notes if relative_url is present (Bartłomiej Święcki) - Fix commit data retrieval when branch name has single quotes (Stan Hu) - Check that project was actually created rather than just validated in import:repos task (Stan Hu) From 0abe98f0497b667ef85ad4e078ea5c10b5b26ede Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Thu, 30 Jul 2015 22:31:53 -0700 Subject: [PATCH 78/79] Fix multi-line syntax highlighting HTML span elements only apply to a single line, and in the case of multi-line comments, the highlighting was dropped as a result. Ensure that each line has the proper styling to fix this. Closes #1577 --- CHANGELOG | 1 + lib/rouge/formatters/html_gitlab.rb | 12 ++++++++++-- spec/helpers/blob_helper_spec.rb | 18 ++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index bfff6a5677..27cf89b593 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 7.14.0 (unreleased) + - Fix multi-line syntax highlighting (Stan Hu) - Fix network graph when branch name has single quotes (Stan Hu) - Upgrade gitlab_git to version 7.2.6 to fix Error 500 when creating network graphs (Stan Hu) - Add support for Unicode filenames in relative links (Hiroyuki Sato) diff --git a/lib/rouge/formatters/html_gitlab.rb b/lib/rouge/formatters/html_gitlab.rb index 485af6832d..092a920a0c 100644 --- a/lib/rouge/formatters/html_gitlab.rb +++ b/lib/rouge/formatters/html_gitlab.rb @@ -148,6 +148,12 @@ module Rouge end end + def wrap_values(val, element) + lines = val.split("\n") + lines = lines.map{ |x| "#{x}" } + lines.join("\n") + end + def span(tok, val) # http://stackoverflow.com/a/1600584/2587286 val = CGI.escapeHTML(val) @@ -155,11 +161,13 @@ module Rouge if tok.shortname.empty? val else + # In the case of multi-line values (e.g. comments), we need to apply + # styling to each line since span elements are inline. if @inline_theme rules = @inline_theme.style_for(tok).rendered_rules - "#{val}" + wrap_values(val, "style=\"#{rules.to_a.join(';')}\"") else - "#{val}" + wrap_values(val, "class=\"#{tok.shortname}\"") end end end diff --git a/spec/helpers/blob_helper_spec.rb b/spec/helpers/blob_helper_spec.rb index e49e4e6d5d..76009c3609 100644 --- a/spec/helpers/blob_helper_spec.rb +++ b/spec/helpers/blob_helper_spec.rb @@ -6,6 +6,14 @@ describe BlobHelper do let(:no_context_content) { ":type \"assem\"))" } let(:blob_content) { "(make-pathname :defaults name\n#{no_context_content}" } let(:split_content) { blob_content.split("\n") } + let(:multiline_content) do + %q( + def test(input): + """This is line 1 of a multi-line comment. + This is line 2. + """ + ) + end it 'should return plaintext for unknown lexer context' do result = highlight(blob_name, no_context_content, nowrap: true, continue: false) @@ -29,5 +37,15 @@ describe BlobHelper do result = split_content.map{ |content| highlight(blob_name, content, nowrap: true, continue: true) } expect(result).to eq(expected) end + + it 'should highlight multi-line comments' do + result = highlight(blob_name, multiline_content, nowrap: true, continue: false) + html = Nokogiri::HTML(result) + lines = html.search('.s') + expect(lines.count).to eq(3) + expect(lines[0].text).to eq('"""This is line 1 of a multi-line comment.') + expect(lines[1].text).to eq(' This is line 2.') + expect(lines[2].text).to eq(' """') + end end end From 0736f348a6953e6417d3857b78ea5c7eb5954e51 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 31 Jul 2015 14:15:49 +0200 Subject: [PATCH 79/79] Use before_actions --- app/controllers/groups/application_controller.rb | 6 ++++++ app/controllers/groups/group_members_controller.rb | 5 +---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/controllers/groups/application_controller.rb b/app/controllers/groups/application_controller.rb index 4df9d1b753..6878d4bc07 100644 --- a/app/controllers/groups/application_controller.rb +++ b/app/controllers/groups/application_controller.rb @@ -18,4 +18,10 @@ class Groups::ApplicationController < ApplicationController return render_404 end end + + def authorize_admin_group_member! + unless can?(current_user, :admin_group_member, group) + return render_403 + end + end end diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb index b9c428a964..91518c44a9 100644 --- a/app/controllers/groups/group_members_controller.rb +++ b/app/controllers/groups/group_members_controller.rb @@ -5,6 +5,7 @@ class Groups::GroupMembersController < Groups::ApplicationController # Authorize before_action :authorize_read_group! before_action :authorize_admin_group!, except: [:index, :leave] + before_action :authorize_admin_group_member!, only: [:create, :resend_invite] def index @project = @group.projects.find(params[:project_id]) if params[:project_id] @@ -21,8 +22,6 @@ class Groups::GroupMembersController < Groups::ApplicationController end def create - return render_403 unless can?(current_user, :admin_group_member, @group) - @group.add_users(params[:user_ids].split(','), params[:access_level], current_user) redirect_to group_group_members_path(@group), notice: 'Users were successfully added.' @@ -51,8 +50,6 @@ class Groups::GroupMembersController < Groups::ApplicationController end def resend_invite - return render_403 unless can?(current_user, :admin_group_member, @group) - redirect_path = group_group_members_path(@group) @group_member = @group.group_members.find(params[:id])