From 3f57022f1e40d874abec35c003b30febcb07bddf Mon Sep 17 00:00:00 2001 From: Sytse Sijbrandij Date: Sat, 10 Jan 2015 21:48:35 -0800 Subject: [PATCH 01/75] Add note about semantic versioning not being absolute. --- MAINTENANCE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTENANCE.md b/MAINTENANCE.md index 19200fef38..d3d3667069 100644 --- a/MAINTENANCE.md +++ b/MAINTENANCE.md @@ -2,7 +2,7 @@ GitLab is a fast moving and evolving project. We currently don't have the resources to support many releases concurrently. We support exactly one stable release at any given time. -GitLab follows the [Semantic Versioning](http://semver.org/) for its releases: `(Major).(Minor).(Patch)`. +GitLab follows the [Semantic Versioning](http://semver.org/) for its releases: `(Major).(Minor).(Patch)` in a [pragmatic way](https://gist.github.com/jashkenas/cbd2b088e20279ae2c8e). - **Major version**: Whenever there is something significant or any backwards incompatible changes are introduced to the public API. - **Minor version**: When new, backwards compatible functionality is introduced to the public API or a minor feature is introduced, or when a set of smaller features is rolled out. From 59ebcfe0e041e68fc666c3d6c8de23bb45e6fb41 Mon Sep 17 00:00:00 2001 From: Ewan Edwards Date: Wed, 11 Feb 2015 14:50:31 -0800 Subject: [PATCH 02/75] Add an example of creating a line break by adding two spaces at the end of a line. --- doc/markdown/markdown.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/markdown/markdown.md b/doc/markdown/markdown.md index abef79b075..cc6b5d7339 100644 --- a/doc/markdown/markdown.md +++ b/doc/markdown/markdown.md @@ -485,6 +485,10 @@ This line is separated from the one above by two newlines, so it will be a *sepa This line is also a separate paragraph, but... This line is only separated by a single newline, so it's a separate line in the *same paragraph*. + +This line is also a separate paragraph, and... +This line is on its own line, because the previous line ends with two +spaces. ``` Here's a line for us to start with. @@ -494,6 +498,10 @@ This line is separated from the one above by two newlines, so it will be a *sepa This line is also begins a separate paragraph, but... This line is only separated by a single newline, so it's a separate line in the *same paragraph*. +This line is also a separate paragraph, and... +This line is on its own line, because the previous line ends with two +spaces. + ## Tables Tables aren't part of the core Markdown spec, but they are part of GFM and Markdown Here supports them. From 6ddd45948f35dd6a3e04fbaf95d9f6935b4cbbc1 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Wed, 4 Mar 2015 22:31:28 +0000 Subject: [PATCH 03/75] Make Irker service use the supported events check --- app/models/project_services/irker_service.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/models/project_services/irker_service.rb b/app/models/project_services/irker_service.rb index a0203a5bb1..14ea5360aa 100644 --- a/app/models/project_services/irker_service.rb +++ b/app/models/project_services/irker_service.rb @@ -63,9 +63,15 @@ class IrkerService < Service 'irker' end - def execute(push_data) + def supported_events + %w(push) + end + + def execute(data) + return unless supported_events.include?(data[:object_kind]) + IrkerWorker.perform_async(project_id, channels, - colorize_messages, push_data, @settings) + colorize_messages, data, @settings) end def fields From cacac147de2b317d02788c5da1cdc6010f00a340 Mon Sep 17 00:00:00 2001 From: Vinnie Okada Date: Sun, 1 Mar 2015 08:06:46 -0700 Subject: [PATCH 04/75] Move restricted visibility settings to the UI Add checkboxes to the application settings page for restricted visibility levels, and remove those settings from gitlab.yml. --- CHANGELOG | 1 + app/assets/stylesheets/generic/forms.scss | 5 +++ .../admin/application_settings_controller.rb | 10 +++++- app/helpers/application_settings_helper.rb | 16 +++++++++ app/helpers/visibility_level_helper.rb | 5 +-- app/models/application_setting.rb | 36 +++++++++++++------ app/models/project.rb | 6 ++-- app/services/base_service.rb | 4 --- app/services/update_snippet_service.rb | 22 ++++++++++++ .../application_settings/_form.html.haml | 8 +++++ config/gitlab.yml.example | 4 --- ...sibility_levels_to_application_settings.rb | 5 +++ db/schema.rb | 7 ++-- lib/gitlab/current_settings.rb | 4 +-- lib/gitlab/visibility_level.rb | 20 ++++++----- spec/models/application_setting_spec.rb | 24 +++++++------ 16 files changed, 128 insertions(+), 49 deletions(-) create mode 100644 app/services/update_snippet_service.rb create mode 100644 db/migrate/20150301014758_add_restricted_visibility_levels_to_application_settings.rb diff --git a/CHANGELOG b/CHANGELOG index 08e66c7dc6..b26e83d726 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -11,6 +11,7 @@ v 7.9.0 (unreleased) - Improve error messages for file edit failures - Improve UI for commits, issues and merge request lists - Fix commit comments on first line of diff not rendering in Merge Request Discussion view. + - Move restricted visibility settings from gitlab.yml into the web UI. - Improve trigger merge request hook when source project branch has been updated (Kirill Zaitsev) - Save web edit in new branch - Fix ordering of imported but unchanged projects (Marco Wessel) diff --git a/app/assets/stylesheets/generic/forms.scss b/app/assets/stylesheets/generic/forms.scss index c8982cdc00..79231638a2 100644 --- a/app/assets/stylesheets/generic/forms.scss +++ b/app/assets/stylesheets/generic/forms.scss @@ -97,3 +97,8 @@ label { .wiki-content { margin-top: 35px; } + +.btn-group .btn.active { + text-shadow: 0 0 0.2em #D9534F, 0 0 0.2em #D9534F, 0 0 0.2em #D9534F; + background-color: #5487bf; +} diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index 2b0c500e97..8f7d5e8006 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -20,6 +20,13 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController end def application_setting_params + restricted_levels = params[:application_setting][:restricted_visibility_levels] + unless restricted_levels.nil? + restricted_levels.map! do |level| + level.to_i + end + end + params.require(:application_setting).permit( :default_projects_limit, :default_branch_protection, @@ -28,7 +35,8 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController :gravatar_enabled, :twitter_sharing_enabled, :sign_in_text, - :home_page_url + :home_page_url, + restricted_visibility_levels: [] ) end end diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb index 1ee086da99..2b0d8860f9 100644 --- a/app/helpers/application_settings_helper.rb +++ b/app/helpers/application_settings_helper.rb @@ -18,4 +18,20 @@ module ApplicationSettingsHelper def extra_sign_in_text current_application_settings.sign_in_text end + + # Return a group of checkboxes that use Bootstrap's button plugin for a + # toggle button effect. + def restricted_level_checkboxes(help_block_id) + Gitlab::VisibilityLevel.options.map do |name, level| + checked = restricted_visibility_levels(true).include?(level) + css_class = 'btn btn-primary' + css_class += ' active' if checked + checkbox_name = 'application_setting[restricted_visibility_levels][]' + + label_tag(checkbox_name, class: css_class) do + check_box_tag(checkbox_name, level, checked, autocomplete: 'off', + 'aria-describedby' => help_block_id) + name + end + end + end end diff --git a/app/helpers/visibility_level_helper.rb b/app/helpers/visibility_level_helper.rb index deb9c8b4d4..7c090dc594 100644 --- a/app/helpers/visibility_level_helper.rb +++ b/app/helpers/visibility_level_helper.rb @@ -60,7 +60,8 @@ module VisibilityLevelHelper Project.visibility_levels.key(level) end - def restricted_visibility_levels - current_user.is_admin? ? [] : gitlab_config.restricted_visibility_levels + def restricted_visibility_levels(show_all = false) + return [] if current_user.is_admin? && !show_all + current_application_settings.restricted_visibility_levels end end diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 588668b3d1..6abdf0c755 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -2,25 +2,38 @@ # # Table name: application_settings # -# id :integer not null, primary key -# default_projects_limit :integer -# signup_enabled :boolean -# signin_enabled :boolean -# gravatar_enabled :boolean -# sign_in_text :text -# created_at :datetime -# updated_at :datetime -# home_page_url :string(255) -# default_branch_protection :integer default(2) -# twitter_sharing_enabled :boolean default(TRUE) +# id :integer not null, primary key +# default_projects_limit :integer +# default_branch_protection :integer +# signup_enabled :boolean +# signin_enabled :boolean +# gravatar_enabled :boolean +# twitter_sharing_enabled :boolean +# sign_in_text :text +# created_at :datetime +# updated_at :datetime +# home_page_url :string(255) +# default_branch_protection :integer default(2) +# twitter_sharing_enabled :boolean default(TRUE) +# restricted_visibility_levels :text # class ApplicationSetting < ActiveRecord::Base + serialize :restricted_visibility_levels + validates :home_page_url, allow_blank: true, format: { with: URI::regexp(%w(http https)), message: "should be a valid url" }, if: :home_page_url_column_exist + validates_each :restricted_visibility_levels do |record, attr, value| + value.each do |level| + unless Gitlab::VisibilityLevel.options.has_value?(level) + record.errors.add(attr, "'#{level}' is not a valid visibility level") + end + end + end + def self.current ApplicationSetting.last end @@ -34,6 +47,7 @@ class ApplicationSetting < ActiveRecord::Base twitter_sharing_enabled: Settings.gitlab['twitter_sharing_enabled'], gravatar_enabled: Settings.gravatar['enabled'], sign_in_text: Settings.extra['sign_in_text'], + restricted_visibility_levels: Settings.gitlab['restricted_visibility_levels'] ) end diff --git a/app/models/project.rb b/app/models/project.rb index c45338bf4e..16b68453f5 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -34,6 +34,8 @@ require 'file_size_validator' class Project < ActiveRecord::Base include Sortable + include Gitlab::CurrentSettings + extend Gitlab::CurrentSettings include Gitlab::ShellAdapter include Gitlab::VisibilityLevel include Gitlab::ConfigHelper @@ -132,8 +134,8 @@ class Project < ActiveRecord::Base validates :issues_enabled, :merge_requests_enabled, :wiki_enabled, inclusion: { in: [true, false] } validates :visibility_level, - exclusion: { in: gitlab_config.restricted_visibility_levels }, - if: -> { gitlab_config.restricted_visibility_levels.any? } + exclusion: { in: current_application_settings.restricted_visibility_levels }, + if: -> { current_application_settings.restricted_visibility_levels.any? } validates :issues_tracker_id, length: { maximum: 255 }, allow_blank: true validates :namespace, presence: true validates_uniqueness_of :name, scope: :namespace_id diff --git a/app/services/base_service.rb b/app/services/base_service.rb index 52ab29f149..8b07d7a436 100644 --- a/app/services/base_service.rb +++ b/app/services/base_service.rb @@ -31,10 +31,6 @@ class BaseService SystemHooksService.new end - def current_application_settings - ApplicationSetting.current - end - private def error(message, http_status = nil) diff --git a/app/services/update_snippet_service.rb b/app/services/update_snippet_service.rb new file mode 100644 index 0000000000..b7a719f252 --- /dev/null +++ b/app/services/update_snippet_service.rb @@ -0,0 +1,22 @@ +class UpdateSnippetService < BaseService + attr_accessor :snippet + + def initialize(project = nil, user, snippet, params = {}) + super(project, user, params) + @snippet = snippet + end + + def execute + # check that user is allowed to set specified visibility_level + new_visibility = params[:visibility_level] + if new_visibility && new_visibility != snippet.visibility_level + unless can?(current_user, :change_visibility_level, snippet) && + Gitlab::VisibilityLevel.allowed_for?(current_user, new_visibility) + deny_visibility_level(snippet, new_visibility_level) + return snippet + end + end + + snippet.update_attributes(params) + end +end diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml index ac64d26f9a..da147605a8 100644 --- a/app/views/admin/application_settings/_form.html.haml +++ b/app/views/admin/application_settings/_form.html.haml @@ -34,6 +34,14 @@ = f.label :default_branch_protection, class: 'control-label col-sm-2' .col-sm-10 = f.select :default_branch_protection, options_for_select(Gitlab::Access.protection_options, @application_setting.default_branch_protection), {}, class: 'form-control' + .form-group + = f.label :restricted_visibility_levels, class: 'control-label col-sm-2' + .col-sm-10 + - data_attrs = { toggle: 'buttons' } + .btn-group{ data: data_attrs } + - restricted_level_checkboxes('restricted-visibility-help').each do |level| + = level + %span.help-block#restricted-visibility-help Selected levels cannot be used by non-admin users for projects or snippets .form-group = f.label :home_page_url, class: 'control-label col-sm-2' .col-sm-10 diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 6dff07cf9d..dcd26c2317 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -56,10 +56,6 @@ production: &base ## COLOR = 5 # default_theme: 2 # default: 2 - # Restrict setting visibility levels for non-admin users. - # The default is to allow all levels. - # restricted_visibility_levels: [ "public" ] - ## Automatic issue closing # If a commit message matches this regular expression, all issues referenced from the matched text will be closed. # This happens when the commit is pushed or merged into the default branch of a project. diff --git a/db/migrate/20150301014758_add_restricted_visibility_levels_to_application_settings.rb b/db/migrate/20150301014758_add_restricted_visibility_levels_to_application_settings.rb new file mode 100644 index 0000000000..494c3033bf --- /dev/null +++ b/db/migrate/20150301014758_add_restricted_visibility_levels_to_application_settings.rb @@ -0,0 +1,5 @@ +class AddRestrictedVisibilityLevelsToApplicationSettings < ActiveRecord::Migration + def change + add_column :application_settings, :restricted_visibility_levels, :text + end +end diff --git a/db/schema.rb b/db/schema.rb index a686bb4b3c..e539afdda4 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20150225065047) do +ActiveRecord::Schema.define(version: 20150301014758) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -25,8 +25,9 @@ ActiveRecord::Schema.define(version: 20150225065047) do t.datetime "created_at" t.datetime "updated_at" t.string "home_page_url" - t.integer "default_branch_protection", default: 2 - t.boolean "twitter_sharing_enabled", default: true + t.integer "default_branch_protection", default: 2 + t.boolean "twitter_sharing_enabled", default: true + t.text "restricted_visibility_levels" end create_table "broadcast_messages", force: true do |t| diff --git a/lib/gitlab/current_settings.rb b/lib/gitlab/current_settings.rb index 1a25eebe7d..0ebebfa09c 100644 --- a/lib/gitlab/current_settings.rb +++ b/lib/gitlab/current_settings.rb @@ -5,8 +5,7 @@ module Gitlab RequestStore.store[key] ||= begin if ActiveRecord::Base.connected? && ActiveRecord::Base.connection.table_exists?('application_settings') - RequestStore.store[:current_application_settings] = - (ApplicationSetting.current || ApplicationSetting.create_from_defaults) + ApplicationSetting.current || ApplicationSetting.create_from_defaults else fake_application_settings end @@ -21,6 +20,7 @@ module Gitlab signin_enabled: Settings.gitlab['signin_enabled'], gravatar_enabled: Settings.gravatar['enabled'], sign_in_text: Settings.extra['sign_in_text'], + restricted_visibility_levels: Settings.gitlab['restricted_visibility_levels'] ) end end diff --git a/lib/gitlab/visibility_level.rb b/lib/gitlab/visibility_level.rb index d0b6cde3c7..1851e76067 100644 --- a/lib/gitlab/visibility_level.rb +++ b/lib/gitlab/visibility_level.rb @@ -5,6 +5,8 @@ # module Gitlab module VisibilityLevel + extend CurrentSettings + PRIVATE = 0 unless const_defined?(:PRIVATE) INTERNAL = 10 unless const_defined?(:INTERNAL) PUBLIC = 20 unless const_defined?(:PUBLIC) @@ -23,21 +25,21 @@ module Gitlab end def allowed_for?(user, level) - user.is_admin? || allowed_level?(level) + user.is_admin? || allowed_level?(level.to_i) end - # Level can be a string `"public"` or a value `20`, first check if valid, - # then check if the corresponding string appears in the config + # Return true if the specified level is allowed for the current user. + # Level should be a numeric value, e.g. `20`. def allowed_level?(level) - if options.has_key?(level.to_s) - non_restricted_level?(level) - elsif options.has_value?(level.to_i) - non_restricted_level?(options.key(level.to_i).downcase) - end + valid_level?(level) && non_restricted_level?(level) end def non_restricted_level?(level) - ! Gitlab.config.gitlab.restricted_visibility_levels.include?(level) + ! current_application_settings.restricted_visibility_levels.include?(level) + end + + def valid_level?(level) + options.has_value?(level) end end diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb index d1027f64d1..b4f0b2c201 100644 --- a/spec/models/application_setting_spec.rb +++ b/spec/models/application_setting_spec.rb @@ -2,17 +2,19 @@ # # Table name: application_settings # -# id :integer not null, primary key -# default_projects_limit :integer -# signup_enabled :boolean -# signin_enabled :boolean -# gravatar_enabled :boolean -# sign_in_text :text -# created_at :datetime -# updated_at :datetime -# home_page_url :string(255) -# default_branch_protection :integer default(2) -# twitter_sharing_enabled :boolean default(TRUE) +# id :integer not null, primary key +# default_projects_limit :integer +# default_branch_protection :integer +# signup_enabled :boolean +# signin_enabled :boolean +# gravatar_enabled :boolean +# sign_in_text :text +# created_at :datetime +# updated_at :datetime +# home_page_url :string(255) +# default_branch_protection :integer default(2) +# twitter_sharing_enabled :boolean default(TRUE) +# restricted_visibility_levels :text # require 'spec_helper' From 285c5341855f8af6cbea5e964e3104a4698fa450 Mon Sep 17 00:00:00 2001 From: Vinnie Okada Date: Sat, 7 Mar 2015 11:23:43 -0700 Subject: [PATCH 05/75] Allow admins to override restricted visibility Allow admins to use restricted visibility levels when creating or updating projects. --- CHANGELOG | 1 + app/models/project.rb | 5 ---- app/services/projects/base_service.rb | 18 +++++++++++++ app/services/projects/create_service.rb | 11 +++++--- app/services/projects/update_service.rb | 11 +++++--- doc/public_access/public_access.md | 2 +- lib/api/helpers.rb | 2 +- lib/api/projects.rb | 6 ++--- spec/requests/api/projects_spec.rb | 26 ++++++++++++++++++ spec/services/projects/create_service_spec.rb | 27 +++++++++++++++++++ spec/services/projects/update_service_spec.rb | 6 ++--- 11 files changed, 95 insertions(+), 20 deletions(-) create mode 100644 app/services/projects/base_service.rb diff --git a/CHANGELOG b/CHANGELOG index b26e83d726..5e9f69f3e9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -11,6 +11,7 @@ v 7.9.0 (unreleased) - Improve error messages for file edit failures - Improve UI for commits, issues and merge request lists - Fix commit comments on first line of diff not rendering in Merge Request Discussion view. + - Allow admins to override restricted project visibility settings. - Move restricted visibility settings from gitlab.yml into the web UI. - Improve trigger merge request hook when source project branch has been updated (Kirill Zaitsev) - Save web edit in new branch diff --git a/app/models/project.rb b/app/models/project.rb index 16b68453f5..dae2b6425c 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -34,8 +34,6 @@ require 'file_size_validator' class Project < ActiveRecord::Base include Sortable - include Gitlab::CurrentSettings - extend Gitlab::CurrentSettings include Gitlab::ShellAdapter include Gitlab::VisibilityLevel include Gitlab::ConfigHelper @@ -133,9 +131,6 @@ class Project < ActiveRecord::Base message: Gitlab::Regex.path_regex_message } validates :issues_enabled, :merge_requests_enabled, :wiki_enabled, inclusion: { in: [true, false] } - validates :visibility_level, - exclusion: { in: current_application_settings.restricted_visibility_levels }, - if: -> { current_application_settings.restricted_visibility_levels.any? } validates :issues_tracker_id, length: { maximum: 255 }, allow_blank: true validates :namespace, presence: true validates_uniqueness_of :name, scope: :namespace_id diff --git a/app/services/projects/base_service.rb b/app/services/projects/base_service.rb new file mode 100644 index 0000000000..2a683e0d40 --- /dev/null +++ b/app/services/projects/base_service.rb @@ -0,0 +1,18 @@ +module Projects + class BaseService < ::BaseService + # Add an error to the project for restricted visibility levels + def deny_visibility_level(project, denied_visibility_level = nil) + denied_visibility_level ||= project.visibility_level + + level_name = 'Unknown' + Gitlab::VisibilityLevel.options.each do |name, level| + level_name = name if level == denied_visibility_level + end + + project.errors.add( + :visibility_level, + "#{level_name} visibility has been restricted by your GitLab administrator" + ) + end + end +end diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb index 4fe790b98f..5f166a9a30 100644 --- a/app/services/projects/create_service.rb +++ b/app/services/projects/create_service.rb @@ -1,5 +1,5 @@ module Projects - class CreateService < BaseService + class CreateService < Projects::BaseService def initialize(user, params) @current_user, @params = user, params.dup end @@ -7,9 +7,12 @@ module Projects def execute @project = Project.new(params) - # Reset visibility level if is not allowed to set it - unless Gitlab::VisibilityLevel.allowed_for?(current_user, params[:visibility_level]) - @project.visibility_level = default_features.visibility_level + # Make sure that the user is allowed to use the specified visibility + # level + unless Gitlab::VisibilityLevel.allowed_for?(current_user, + params[:visibility_level]) + deny_visibility_level(@project) + return @project end # Set project name from path diff --git a/app/services/projects/update_service.rb b/app/services/projects/update_service.rb index 36877a6167..823afadc18 100644 --- a/app/services/projects/update_service.rb +++ b/app/services/projects/update_service.rb @@ -1,9 +1,14 @@ module Projects - class UpdateService < BaseService + class UpdateService < Projects::BaseService def execute # check that user is allowed to set specified visibility_level - unless can?(current_user, :change_visibility_level, project) && Gitlab::VisibilityLevel.allowed_for?(current_user, params[:visibility_level]) - params[:visibility_level] = project.visibility_level + new_visibility = params[:visibility_level] + if new_visibility && new_visibility.to_i != project.visibility_level + unless can?(current_user, :change_visibility_level, project) && + Gitlab::VisibilityLevel.allowed_for?(current_user, new_visibility) + deny_visibility_level(project, new_visibility) + return project + end end new_branch = params[:default_branch] diff --git a/doc/public_access/public_access.md b/doc/public_access/public_access.md index 4712c38702..7c5a6c0463 100644 --- a/doc/public_access/public_access.md +++ b/doc/public_access/public_access.md @@ -41,4 +41,4 @@ When visiting the public page of an user, you will only see listed projects whic ## Restricting the use of public or internal projects -In [gitlab.yml](https://gitlab.com/gitlab-org/gitlab-ce/blob/dbd88d453b8e6c78a423fa7e692004b1db6ea069/config/gitlab.yml.example#L64) you can disable public projects or public and internal projects for the entire GitLab installation to prevent people making code public by accident. +In [gitlab.yml](https://gitlab.com/gitlab-org/gitlab-ce/blob/dbd88d453b8e6c78a423fa7e692004b1db6ea069/config/gitlab.yml.example#L64) you can disable public projects or public and internal projects for the entire GitLab installation to prevent people making code public by accident. The restricted visibility settings do not apply to admin users. diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 228a719fbd..f46dc8b456 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -204,7 +204,7 @@ module API end def render_validation_error!(model) - unless model.valid? + if model.errors.any? render_api_error!(model.errors.messages || '400 Bad Request', 400) end end diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 0677e85bea..83f65eec6c 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -233,10 +233,10 @@ module API ::Projects::UpdateService.new(user_project, current_user, attrs).execute - if user_project.valid? - present user_project, with: Entities::Project - else + if user_project.errors.any? render_validation_error!(user_project) + else + present user_project, with: Entities::Project end end diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 0b3a47e327..98b31a6e0a 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -3,6 +3,7 @@ require 'spec_helper' describe API::API, api: true do include ApiHelpers + include Gitlab::CurrentSettings let(:user) { create(:user) } let(:user2) { create(:user) } let(:user3) { create(:user) } @@ -202,6 +203,31 @@ describe API::API, api: true do expect(json_response['public']).to be_falsey expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PRIVATE) end + + context 'when a visibility level is restricted' do + before do + @project = attributes_for(:project, { public: true }) + allow_any_instance_of(ApplicationSetting).to( + receive(:restricted_visibility_levels).and_return([20]) + ) + end + + it 'should not allow a non-admin to use a restricted visibility level' do + post api('/projects', user), @project + expect(response.status).to eq(400) + expect(json_response['message']['visibility_level'].first).to( + match('restricted by your GitLab administrator') + ) + end + + it 'should allow an admin to override restricted visibility settings' do + post api('/projects', admin), @project + expect(json_response['public']).to be_truthy + expect(json_response['visibility_level']).to( + eq(Gitlab::VisibilityLevel::PUBLIC) + ) + end + end end describe 'POST /projects/user/:id' do diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb index 8bb4834620..337dae592d 100644 --- a/spec/services/projects/create_service_spec.rb +++ b/spec/services/projects/create_service_spec.rb @@ -55,6 +55,33 @@ describe Projects::CreateService do it { expect(File.exists?(@path)).to be_falsey } end end + + context 'restricted visibility level' do + before do + allow_any_instance_of(ApplicationSetting).to( + receive(:restricted_visibility_levels).and_return([20]) + ) + + @opts.merge!( + visibility_level: Gitlab::VisibilityLevel.options['Public'] + ) + end + + it 'should not allow a restricted visibility level for non-admins' do + project = create_project(@user, @opts) + expect(project).to respond_to(:errors) + expect(project.errors.messages).to have_key(:visibility_level) + expect(project.errors.messages[:visibility_level].first).to( + match('restricted by your GitLab administrator') + ) + end + + it 'should allow a restricted visibility level for admins' do + project = create_project(@admin, @opts) + expect(project.errors.any?).to be(false) + expect(project.saved?).to be(true) + end + end end def create_project(user, opts) diff --git a/spec/services/projects/update_service_spec.rb b/spec/services/projects/update_service_spec.rb index 10dbc548e8..ea5b881310 100644 --- a/spec/services/projects/update_service_spec.rb +++ b/spec/services/projects/update_service_spec.rb @@ -47,9 +47,9 @@ describe Projects::UpdateService do context 'respect configured visibility restrictions setting' do before(:each) do - @restrictions = double("restrictions") - allow(@restrictions).to receive(:restricted_visibility_levels) { [ "public" ] } - Settings.stub_chain(:gitlab).and_return(@restrictions) + allow_any_instance_of(ApplicationSetting).to( + receive(:restricted_visibility_levels).and_return([20]) + ) end context 'should be private when updated to private' do From 928fc94c3d900069902b097d6464acee712a886c Mon Sep 17 00:00:00 2001 From: Vinnie Okada Date: Sat, 7 Mar 2015 12:47:06 -0700 Subject: [PATCH 06/75] Enforce restricted visibilities for snippets Add new service classes to create and update project and personal snippets. These classes are responsible for enforcing restricted visibility settings for non-admin users. --- .../projects/snippets_controller.rb | 24 ++++++++----------- app/controllers/snippets_controller.rb | 18 +++++--------- app/helpers/gitlab_routing_helper.rb | 3 ++- app/services/base_service.rb | 15 ++++++++++++ app/services/create_snippet_service.rb | 20 ++++++++++++++++ app/services/projects/base_service.rb | 18 -------------- app/services/projects/create_service.rb | 2 +- app/services/projects/update_service.rb | 2 +- app/services/update_snippet_service.rb | 6 ++--- lib/api/project_snippets.rb | 22 ++++++++++------- lib/gitlab/url_builder.rb | 6 ++--- spec/requests/api/projects_spec.rb | 3 ++- 12 files changed, 76 insertions(+), 63 deletions(-) create mode 100644 app/services/create_snippet_service.rb delete mode 100644 app/services/projects/base_service.rb diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb index 6c250e4ffe..ed26840037 100644 --- a/app/controllers/projects/snippets_controller.rb +++ b/app/controllers/projects/snippets_controller.rb @@ -28,26 +28,22 @@ class Projects::SnippetsController < Projects::ApplicationController end def create - @snippet = @project.snippets.build(snippet_params) - @snippet.author = current_user - - if @snippet.save - redirect_to namespace_project_snippet_path(@project.namespace, @project, - @snippet) - else - respond_with(@snippet) - end + @snippet = CreateSnippetService.new(@project, current_user, + snippet_params).execute + respond_with(@snippet, + location: namespace_project_snippet_path(@project.namespace, + @project, @snippet)) end def edit end def update - if @snippet.update_attributes(snippet_params) - redirect_to namespace_project_snippet_path(@project.namespace, @project, @snippet) - else - respond_with(@snippet) - end + UpdateSnippetService.new(project, current_user, @snippet, + snippet_params).execute + respond_with(@snippet, + location: namespace_project_snippet_path(@project.namespace, + @project, @snippet)) end def show diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index 6ac048e4b8..dc0a555472 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -42,25 +42,19 @@ class SnippetsController < ApplicationController end def create - @snippet = PersonalSnippet.new(snippet_params) - @snippet.author = current_user + @snippet = CreateSnippetService.new(nil, current_user, + snippet_params).execute - if @snippet.save - redirect_to snippet_path(@snippet) - else - respond_with @snippet - end + respond_with @snippet.becomes(Snippet) end def edit end def update - if @snippet.update_attributes(snippet_params) - redirect_to snippet_path(@snippet) - else - respond_with @snippet - end + UpdateSnippetService.new(nil, current_user, @snippet, + snippet_params).execute + respond_with @snippet.becomes(Snippet) end def show diff --git a/app/helpers/gitlab_routing_helper.rb b/app/helpers/gitlab_routing_helper.rb index 8518a47a3a..b005cb8e41 100644 --- a/app/helpers/gitlab_routing_helper.rb +++ b/app/helpers/gitlab_routing_helper.rb @@ -45,7 +45,8 @@ module GitlabRoutingHelper namespace_project_merge_request_url(entity.project.namespace, entity.project, entity, *args) end - def snippet_url(entity, *args) + def project_snippet_url(entity, *args) namespace_project_snippet_url(entity.project.namespace, entity.project, entity, *args) + end end diff --git a/app/services/base_service.rb b/app/services/base_service.rb index 8b07d7a436..6d9ed34591 100644 --- a/app/services/base_service.rb +++ b/app/services/base_service.rb @@ -31,6 +31,21 @@ class BaseService SystemHooksService.new end + # Add an error to the specified model for restricted visibility levels + def deny_visibility_level(model, denied_visibility_level = nil) + denied_visibility_level ||= model.visibility_level + + level_name = 'Unknown' + Gitlab::VisibilityLevel.options.each do |name, level| + level_name = name if level == denied_visibility_level + end + + model.errors.add( + :visibility_level, + "#{level_name} visibility has been restricted by your GitLab administrator" + ) + end + private def error(message, http_status = nil) diff --git a/app/services/create_snippet_service.rb b/app/services/create_snippet_service.rb new file mode 100644 index 0000000000..101a3df5ee --- /dev/null +++ b/app/services/create_snippet_service.rb @@ -0,0 +1,20 @@ +class CreateSnippetService < BaseService + def execute + if project.nil? + snippet = PersonalSnippet.new(params) + else + snippet = project.snippets.build(params) + end + + unless Gitlab::VisibilityLevel.allowed_for?(current_user, + params[:visibility_level]) + deny_visibility_level(snippet) + return snippet + end + + snippet.author = current_user + + snippet.save + snippet + end +end diff --git a/app/services/projects/base_service.rb b/app/services/projects/base_service.rb deleted file mode 100644 index 2a683e0d40..0000000000 --- a/app/services/projects/base_service.rb +++ /dev/null @@ -1,18 +0,0 @@ -module Projects - class BaseService < ::BaseService - # Add an error to the project for restricted visibility levels - def deny_visibility_level(project, denied_visibility_level = nil) - denied_visibility_level ||= project.visibility_level - - level_name = 'Unknown' - Gitlab::VisibilityLevel.options.each do |name, level| - level_name = name if level == denied_visibility_level - end - - project.errors.add( - :visibility_level, - "#{level_name} visibility has been restricted by your GitLab administrator" - ) - end - end -end diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb index 5f166a9a30..7ffd0b3882 100644 --- a/app/services/projects/create_service.rb +++ b/app/services/projects/create_service.rb @@ -1,5 +1,5 @@ module Projects - class CreateService < Projects::BaseService + class CreateService < BaseService def initialize(user, params) @current_user, @params = user, params.dup end diff --git a/app/services/projects/update_service.rb b/app/services/projects/update_service.rb index 823afadc18..69bdd045dd 100644 --- a/app/services/projects/update_service.rb +++ b/app/services/projects/update_service.rb @@ -1,5 +1,5 @@ module Projects - class UpdateService < Projects::BaseService + class UpdateService < BaseService def execute # check that user is allowed to set specified visibility_level new_visibility = params[:visibility_level] diff --git a/app/services/update_snippet_service.rb b/app/services/update_snippet_service.rb index b7a719f252..9d181c2d2a 100644 --- a/app/services/update_snippet_service.rb +++ b/app/services/update_snippet_service.rb @@ -1,7 +1,7 @@ class UpdateSnippetService < BaseService attr_accessor :snippet - def initialize(project = nil, user, snippet, params = {}) + def initialize(project, user, snippet, params) super(project, user, params) @snippet = snippet end @@ -9,10 +9,10 @@ class UpdateSnippetService < BaseService def execute # check that user is allowed to set specified visibility_level new_visibility = params[:visibility_level] - if new_visibility && new_visibility != snippet.visibility_level + if new_visibility && new_visibility.to_i != snippet.visibility_level unless can?(current_user, :change_visibility_level, snippet) && Gitlab::VisibilityLevel.allowed_for?(current_user, new_visibility) - deny_visibility_level(snippet, new_visibility_level) + deny_visibility_level(snippet, new_visibility) return snippet end end diff --git a/lib/api/project_snippets.rb b/lib/api/project_snippets.rb index 0c2d282f78..25f34a3dab 100644 --- a/lib/api/project_snippets.rb +++ b/lib/api/project_snippets.rb @@ -42,18 +42,19 @@ module API # title (required) - The title of a snippet # file_name (required) - The name of a snippet file # code (required) - The content of a snippet + # visibility_level (required) - The snippet's visibility # Example Request: # POST /projects/:id/snippets post ":id/snippets" do authorize! :write_project_snippet, user_project - required_attributes! [:title, :file_name, :code] + required_attributes! [:title, :file_name, :code, :visibility_level] - attrs = attributes_for_keys [:title, :file_name] + attrs = attributes_for_keys [:title, :file_name, :visibility_level] attrs[:content] = params[:code] if params[:code].present? - @snippet = user_project.snippets.new attrs - @snippet.author = current_user + @snippet = CreateSnippetservice.new(user_project, current_user, + attrs).execute - if @snippet.save + if @snippet.saved? present @snippet, with: Entities::ProjectSnippet else render_validation_error!(@snippet) @@ -68,19 +69,22 @@ module API # title (optional) - The title of a snippet # file_name (optional) - The name of a snippet file # code (optional) - The content of a snippet + # visibility_level (optional) - The snippet's visibility # Example Request: # PUT /projects/:id/snippets/:snippet_id put ":id/snippets/:snippet_id" do @snippet = user_project.snippets.find(params[:snippet_id]) authorize! :modify_project_snippet, @snippet - attrs = attributes_for_keys [:title, :file_name] + attrs = attributes_for_keys [:title, :file_name, :visibility_level] attrs[:content] = params[:code] if params[:code].present? - if @snippet.update_attributes attrs - present @snippet, with: Entities::ProjectSnippet - else + UpdateSnippetService.new(user_project, current_user, @snippet, + attrs).execute + if @snippet.errors.any? render_validation_error!(@snippet) + else + present @snippet, with: Entities::ProjectSnippet end end diff --git a/lib/gitlab/url_builder.rb b/lib/gitlab/url_builder.rb index 6830d15875..11b0d44f34 100644 --- a/lib/gitlab/url_builder.rb +++ b/lib/gitlab/url_builder.rb @@ -51,9 +51,9 @@ module Gitlab anchor: "note_#{note.id}") elsif note.for_project_snippet? snippet = Snippet.find(note.noteable_id) - snippet_url(snippet, - host: Gitlab.config.gitlab['url'], - anchor: "note_#{note.id}") + project_snippet_url(snippet, + host: Gitlab.config.gitlab['url'], + anchor: "note_#{note.id}") end end end diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 98b31a6e0a..f28dfea3cc 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -425,7 +425,8 @@ describe API::API, api: true do describe 'POST /projects/:id/snippets' do it 'should create a new project snippet' do post api("/projects/#{project.id}/snippets", user), - title: 'api test', file_name: 'sample.rb', code: 'test' + title: 'api test', file_name: 'sample.rb', code: 'test', + visibility_level: '0' expect(response.status).to eq(201) expect(json_response['title']).to eq('api test') end From 9623b71a3975bb442b85aa57146b788f96de6320 Mon Sep 17 00:00:00 2001 From: Vinnie Okada Date: Tue, 10 Mar 2015 18:21:09 -0600 Subject: [PATCH 07/75] More restricted visibility changes Bug fixes and new tests for the restricted visibility changes. --- app/helpers/application_settings_helper.rb | 3 ++- lib/api/project_snippets.rb | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb index 2b0d8860f9..241d6075c9 100644 --- a/app/helpers/application_settings_helper.rb +++ b/app/helpers/application_settings_helper.rb @@ -29,7 +29,8 @@ module ApplicationSettingsHelper checkbox_name = 'application_setting[restricted_visibility_levels][]' label_tag(checkbox_name, class: css_class) do - check_box_tag(checkbox_name, level, checked, autocomplete: 'off', + check_box_tag(checkbox_name, level, checked, + autocomplete: 'off', 'aria-describedby' => help_block_id) + name end end diff --git a/lib/api/project_snippets.rb b/lib/api/project_snippets.rb index 25f34a3dab..54f2555903 100644 --- a/lib/api/project_snippets.rb +++ b/lib/api/project_snippets.rb @@ -51,13 +51,13 @@ module API attrs = attributes_for_keys [:title, :file_name, :visibility_level] attrs[:content] = params[:code] if params[:code].present? - @snippet = CreateSnippetservice.new(user_project, current_user, + @snippet = CreateSnippetService.new(user_project, current_user, attrs).execute - if @snippet.saved? - present @snippet, with: Entities::ProjectSnippet - else + if @snippet.errors.any? render_validation_error!(@snippet) + else + present @snippet, with: Entities::ProjectSnippet end end From 158507d942137e947a0e78a66e85a475667dd765 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 11 Mar 2015 21:29:11 -0700 Subject: [PATCH 08/75] Add blue theme to GitLab --- app/assets/stylesheets/pages/profile.scss | 4 ++++ app/assets/stylesheets/themes/ui_blue.scss | 6 ++++++ app/views/profiles/design.html.haml | 5 +++++ lib/gitlab/theme.rb | 4 +++- 4 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 app/assets/stylesheets/themes/ui_blue.scss diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss index 0ab62b7ae4..81afe05162 100644 --- a/app/assets/stylesheets/pages/profile.scss +++ b/app/assets/stylesheets/pages/profile.scss @@ -80,6 +80,10 @@ &.violet { background: #548; } + + &.blue { + background: #2980b9; + } } } } diff --git a/app/assets/stylesheets/themes/ui_blue.scss b/app/assets/stylesheets/themes/ui_blue.scss new file mode 100644 index 0000000000..cb7980b5a0 --- /dev/null +++ b/app/assets/stylesheets/themes/ui_blue.scss @@ -0,0 +1,6 @@ +/** + * Modern GitLab UI theme + */ +.ui_blue { + @include dark-theme(#BECDE9, #2980b9, #1970a9, #096099); +} diff --git a/app/views/profiles/design.html.haml b/app/views/profiles/design.html.haml index 8d09595fd4..cc00d08d03 100644 --- a/app/views/profiles/design.html.haml +++ b/app/views/profiles/design.html.haml @@ -33,6 +33,11 @@ .prev.violet = f.radio_button :theme_id, 5 Violet + + = label_tag do + .prev.blue + = f.radio_button :theme_id, 6 + Blue %br .clearfix diff --git a/lib/gitlab/theme.rb b/lib/gitlab/theme.rb index a7c83a880f..9799e54de5 100644 --- a/lib/gitlab/theme.rb +++ b/lib/gitlab/theme.rb @@ -5,6 +5,7 @@ module Gitlab MODERN = 3 unless const_defined?(:MODERN) GRAY = 4 unless const_defined?(:GRAY) COLOR = 5 unless const_defined?(:COLOR) + BLUE = 6 unless const_defined?(:BLUE) def self.css_class_by_id(id) themes = { @@ -12,7 +13,8 @@ module Gitlab MARS => "ui_mars", MODERN => "ui_modern", GRAY => "ui_gray", - COLOR => "ui_color" + COLOR => "ui_color", + BLUE => "ui_blue" } id ||= Gitlab.config.gitlab.default_theme From 3c7e0f45c2d9c242bf45d153bb73e96ce7525a06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Rosen=C3=B6gger?= <123haynes@gmail.com> Date: Wed, 4 Mar 2015 12:58:40 +0100 Subject: [PATCH 09/75] replace images in emails with inline images This adds the functionality of replacing all images that were uploaded to gitlab with inline images(base64) in emails. This change fixes the broken images in emails that 7.8 introduced --- CHANGELOG | 1 + app/helpers/emails_helper.rb | 25 ++++++ app/views/notify/_note_message.html.haml | 2 +- app/views/notify/new_issue_email.html.haml | 2 +- .../notify/new_merge_request_email.html.haml | 2 +- spec/mailers/notify_spec.rb | 82 ++++++++++++++++++- 6 files changed, 108 insertions(+), 6 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 3b263a7d4f..e1e22102ed 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.9.0 (unreleased) + - Fix broken email images (Hannes Rosenögger) - Fix mass SQL statements on initial push (Hannes Rosenögger) - Add tag push notifications and normalize HipChat and Slack messages to be consistent (Stan Hu) - Add comment notification events to HipChat and Slack services (Stan Hu) diff --git a/app/helpers/emails_helper.rb b/app/helpers/emails_helper.rb index 92cc9c426b..08476f8516 100644 --- a/app/helpers/emails_helper.rb +++ b/app/helpers/emails_helper.rb @@ -1,3 +1,6 @@ +require 'html/pipeline' +require 'html/pipeline/gitlab' + module EmailsHelper # Google Actions @@ -39,4 +42,26 @@ module EmailsHelper lexer = Rugments::Lexers::Diff.new raw formatter.format(lexer.lex(diffcontent)) end + + def replace_image_links_with_base64(text, project) + # Used pipelines in GitLab: + # GitlabEmailImageFilter - replaces images that have been uploaded as attachments with inline images in emails. + # + # see https://gitlab.com/gitlab-org/html-pipeline-gitlab for more filters + filters = [ + HTML::Pipeline::Gitlab::GitlabEmailImageFilter + ] + + context = { + base_url: File.join(Gitlab.config.gitlab.url, project.path_with_namespace, 'uploads'), + upload_path: File.join(Rails.root, 'public', 'uploads', project.path_with_namespace), + } + + pipeline = HTML::Pipeline::Gitlab.new(filters).pipeline + + result = pipeline.call(text, context) + text = result[:output].to_html(save_with: 0) + + text.html_safe + end end diff --git a/app/views/notify/_note_message.html.haml b/app/views/notify/_note_message.html.haml index 5272dfa0ed..778a78acf5 100644 --- a/app/views/notify/_note_message.html.haml +++ b/app/views/notify/_note_message.html.haml @@ -1,2 +1,2 @@ %div - = markdown(@note.note) + = replace_image_links_with_base64(markdown(@note.note), @note.project) diff --git a/app/views/notify/new_issue_email.html.haml b/app/views/notify/new_issue_email.html.haml index f2f8eee18c..03cbee9460 100644 --- a/app/views/notify/new_issue_email.html.haml +++ b/app/views/notify/new_issue_email.html.haml @@ -1,5 +1,5 @@ -if @issue.description - = markdown(@issue.description) + = replace_image_links_with_base64(markdown(@issue.description), @issue.project) - if @issue.assignee_id.present? %p diff --git a/app/views/notify/new_merge_request_email.html.haml b/app/views/notify/new_merge_request_email.html.haml index f02d5111b2..729a7bb505 100644 --- a/app/views/notify/new_merge_request_email.html.haml +++ b/app/views/notify/new_merge_request_email.html.haml @@ -6,4 +6,4 @@ Assignee: #{@merge_request.author_name} → #{@merge_request.assignee_name} -if @merge_request.description - = markdown(@merge_request.description) + = replace_image_links_with_base64(markdown(@merge_request.description), @merge_request.project) diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb index b3c507ccbe..e3a3b54235 100644 --- a/spec/mailers/notify_spec.rb +++ b/spec/mailers/notify_spec.rb @@ -183,6 +183,13 @@ describe Notify do context 'for issues' do let(:issue) { create(:issue, author: current_user, assignee: assignee, project: project) } let(:issue_with_description) { create(:issue, author: current_user, assignee: assignee, project: project, description: Faker::Lorem.sentence) } + let(:issue_with_image) do + create(:issue, + author: current_user, + assignee: assignee, + project: project, + description: "![test](#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/12345/test.jpg)") + end describe 'that are new' do subject { Notify.new_issue_email(issue.assignee_id, issue.id) } @@ -207,6 +214,22 @@ describe Notify do end end + describe 'that contain images' do + let(:png) { File.read("#{Rails.root}/spec/fixtures/dk.png") } + let(:png_encoded) { Base64::encode64(png) } + + before :each do + file_path = File.join(Rails.root, 'public', 'uploads', issue_with_image.project.path_with_namespace, '12345/test.jpg') + allow(File).to receive(:file?).with(file_path).and_return(true) + allow(File).to receive(:read).with(file_path).and_return(png) + end + + subject { Notify.new_issue_email(issue_with_image.assignee_id, issue_with_image.id) } + it 'replaces attached images with inline images' do + is_expected.to have_body_text URI.encode(png_encoded) + end + end + describe 'that have been reassigned' do subject { Notify.reassigned_issue_email(recipient.id, issue.id, previous_assignee.id, current_user) } @@ -271,6 +294,14 @@ describe Notify do let(:merge_author) { create(:user) } let(:merge_request) { create(:merge_request, author: current_user, assignee: assignee, source_project: project, target_project: project) } let(:merge_request_with_description) { create(:merge_request, author: current_user, assignee: assignee, source_project: project, target_project: project, description: Faker::Lorem.sentence) } + let(:merge_request_with_image) do + create(:merge_request, + author: current_user, + assignee: assignee, + source_project: project, + target_project: project, + description: "![test](#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/12345/test.jpg)") + end describe 'that are new' do subject { Notify.new_merge_request_email(merge_request.assignee_id, merge_request.id) } @@ -307,6 +338,22 @@ describe Notify do end end + describe 'that are new and contain contain images in the description' do + let(:png) {File.read("#{Rails.root}/spec/fixtures/dk.png")} + let(:png_encoded) { Base64::encode64(png) } + + before :each do + file_path = File.join(Rails.root, 'public', 'uploads', merge_request_with_image.project.path_with_namespace, '/12345/test.jpg') + allow(File).to receive(:file?).with(file_path).and_return(true) + allow(File).to receive(:read).with(file_path).and_return(png) + end + + subject { Notify.new_merge_request_email(merge_request_with_image.assignee_id, merge_request_with_image.id) } + it 'replaces attached images with inline images' do + is_expected.to have_body_text URI.encode(png_encoded) + end + end + describe 'that are reassigned' do subject { Notify.reassigned_merge_request_email(recipient.id, merge_request.id, previous_assignee.id, current_user.id) } @@ -415,9 +462,12 @@ describe Notify do describe 'project access changed' do let(:project) { create(:project) } let(:user) { create(:user) } - let(:project_member) { create(:project_member, - project: project, - user: user) } + let(:project_member) do + create(:project_member, + project: project, + user: user) + end + subject { Notify.project_access_granted_email(project_member.id) } it_behaves_like 'an email sent from GitLab' @@ -457,6 +507,32 @@ describe Notify do end end + describe 'on a commit that contains an image' do + let(:commit) { project.repository.commit } + let(:note_with_image) do + create(:note, + project: project, + author: note_author, + note: "![test](#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/12345/test.jpg)") + end + + let(:png) {File.read("#{Rails.root}/spec/fixtures/dk.png")} + let(:png_encoded) { Base64::encode64(png) } + + before :each do + file_path = File.join(Rails.root, 'public', 'uploads', note_with_image.project.path_with_namespace, '12345/test.jpg') + allow(File).to receive(:file?).with(file_path).and_return(true) + allow(File).to receive(:read).with(file_path).and_return(png) + allow(Note).to receive(:find).with(note_with_image.id).and_return(note_with_image) + allow(note_with_image).to receive(:noteable).and_return(commit) + end + + subject { Notify.note_commit_email(recipient.id, note_with_image.id) } + it 'replaces attached images with inline images' do + is_expected.to have_body_text URI.encode(png_encoded) + end + end + describe 'on a commit' do let(:commit) { project.repository.commit } From 3175438f02ca4bc0469aca097e02b2671865ef43 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Thu, 12 Mar 2015 13:47:15 +0100 Subject: [PATCH 10/75] Fix missing GitHub organisation repositories on import page. --- CHANGELOG | 1 + app/controllers/import/github_controller.rb | 2 +- spec/controllers/import/github_controller_spec.rb | 7 +++++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 9b9e583255..5a5fb4f18a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -44,6 +44,7 @@ v 7.9.0 (unreleased) - Wrap commit message in EmailsOnPush email. - Send EmailsOnPush emails when deleting commits using force push. - Fix EmailsOnPush email comparison link to include first commit. + - Fix missing GitHub organisation repositories on import page. v 7.8.2 - Fix service migration issue when upgrading from versions prior to 7.3 diff --git a/app/controllers/import/github_controller.rb b/app/controllers/import/github_controller.rb index dc7668ee6f..8650b6464d 100644 --- a/app/controllers/import/github_controller.rb +++ b/app/controllers/import/github_controller.rb @@ -14,7 +14,7 @@ class Import::GithubController < Import::BaseController def status @repos = client.repos client.orgs.each do |org| - @repos += client.repos(org.login) + @repos += client.org_repos(org.login) end @already_added_projects = current_user.created_projects.where(import_type: "github") diff --git a/spec/controllers/import/github_controller_spec.rb b/spec/controllers/import/github_controller_spec.rb index b882041340..5b967bfcc0 100644 --- a/spec/controllers/import/github_controller_spec.rb +++ b/spec/controllers/import/github_controller_spec.rb @@ -27,17 +27,20 @@ describe Import::GithubController do describe "GET status" do before do @repo = OpenStruct.new(login: 'vim', full_name: 'asd/vim') + @org = OpenStruct.new(login: 'company') + @org_repo = OpenStruct.new(login: 'company', full_name: 'company/repo') end it "assigns variables" do @project = create(:project, import_type: 'github', creator_id: user.id) controller.stub_chain(:client, :repos).and_return([@repo]) - controller.stub_chain(:client, :orgs).and_return([]) + controller.stub_chain(:client, :orgs).and_return([@org]) + controller.stub_chain(:client, :org_repos).with(@org.login).and_return([@org_repo]) get :status expect(assigns(:already_added_projects)).to eq([@project]) - expect(assigns(:repos)).to eq([@repo]) + expect(assigns(:repos)).to eq([@repo, @org_repo]) end it "does not show already added project" do From fff34a7f4d58ff0add8c2cb043a4fd53d004bd71 Mon Sep 17 00:00:00 2001 From: Cameron Banga Date: Thu, 12 Mar 2015 10:49:46 -0500 Subject: [PATCH 11/75] Updated help documentation to properly reference EmojiOne. [ci skip] --- CHANGELOG | 1 + doc/markdown/markdown.md | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 90ed686448..fec90f1e22 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -52,6 +52,7 @@ v 7.9.0 (unreleased) - Starred projects page at dashboard - Make email display name configurable - Improve json validation in hook data + - Updated emoji help documentation to properly reference EmojiOne. v 7.8.4 - Fix issue_tracker_id substitution in custom issue trackers - Fix path and name duplication in namespaces diff --git a/doc/markdown/markdown.md b/doc/markdown/markdown.md index 1096ea9656..5277910377 100644 --- a/doc/markdown/markdown.md +++ b/doc/markdown/markdown.md @@ -140,25 +140,25 @@ But let's throw in a tag. ## Emoji - Sometimes you want to be a :ninja: and add some :glowing_star: to your :speech_balloon:. Well we have a gift for you: + Sometimes you want to :monkey: around a bit and add some :star2: to your :speech_balloon:. Well we have a gift for you: - :high_voltage_sign: You can use emoji anywhere GFM is supported. :victory_hand: + :zap: You can use emoji anywhere GFM is supported. :v: - You can use it to point out a :bug: or warn about :speak_no_evil_monkey: patches. And if someone improves your really :snail: code, send them some :cake:. People will :heart: you for that. + You can use it to point out a :bug: or warn about :speak_no_evil: patches. And if someone improves your really :snail: code, send them some :birthday:. People will :heart: you for that. - If you are new to this, don't be :fearful_face:. You can easily join the emoji :family:. All you need to do is to look up on the supported codes. + If you are new to this, don't be :fearful:. You can easily join the emoji :family:. All you need to do is to look up on the supported codes. - Consult the [Emoji Cheat Sheet](https://s3.amazonaws.com/emoji-cheatsheet/cheat_sheet.pdf) for a list of all supported emoji codes. :thumbsup: + Consult the [Emoji Cheat Sheet](http://emoji.codes) for a list of all supported emoji codes. :thumbsup: -Sometimes you want to be a :ninja: and add some :glowing_star: to your :speech_balloon:. Well we have a gift for you: +Sometimes you want to :monkey: around a bit and add some :star2: to your :speech_balloon:. Well we have a gift for you: -:high_voltage_sign: You can use emoji anywhere GFM is supported. :victory_hand: +:zap: You can use emoji anywhere GFM is supported. :v: -You can use it to point out a :bug: or warn about :speak_no_evil_monkey: patches. And if someone improves your really :snail: code, send them some :cake:. People will :heart: you for that. +You can use it to point out a :bug: or warn about :speak_no_evil: patches. And if someone improves your really :snail: code, send them some :birthday:. People will :heart: you for that. -If you are new to this, don't be :fearful_face:. You can easily join the emoji :family:. All you need to do is to look up on the supported codes. +If you are new to this, don't be :fearful:. You can easily join the emoji :family:. All you need to do is to look up on the supported codes. -Consult the [Emoji Cheat Sheet](https://s3.amazonaws.com/emoji-cheatsheet/cheat_sheet.pdf) for a list of all supported emoji codes. :thumbsup: +Consult the [Emoji Cheat Sheet](http://emoji.codes) for a list of all supported emoji codes. :thumbsup: ## Special GitLab References From dd78cd1ce4699afb76ee430e7d82b852333805d8 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 12 Mar 2015 10:04:09 -0700 Subject: [PATCH 12/75] Style improvements to import page --- .../javascripts/importer_status.js.coffee | 10 ++-- app/assets/stylesheets/base/gl_bootstrap.scss | 47 +++++++++++++++++++ app/views/import/bitbucket/status.html.haml | 2 +- app/views/import/github/status.html.haml | 2 +- app/views/import/gitlab/status.html.haml | 2 +- app/views/import/gitorious/status.html.haml | 2 +- 6 files changed, 56 insertions(+), 9 deletions(-) diff --git a/app/assets/javascripts/importer_status.js.coffee b/app/assets/javascripts/importer_status.js.coffee index e0e7771ab2..be8d225e73 100644 --- a/app/assets/javascripts/importer_status.js.coffee +++ b/app/assets/javascripts/importer_status.js.coffee @@ -16,20 +16,20 @@ class @ImporterStatus $(".js-import-all").click (event) => $(".js-add-to-import").each -> $(this).click() - + setAutoUpdate: -> setInterval (=> $.get @jobs_url, (data) => $.each data, (i, job) => job_item = $("#project_" + job.id) status_field = job_item.find(".job-status") - + if job.import_status == 'finished' job_item.removeClass("active").addClass("success") - status_field.html(' done') + status_field.html(' done') else if job.import_status == 'started' status_field.html(" started") else status_field.html(job.import_status) - - ), 4000 \ No newline at end of file + + ), 4000 diff --git a/app/assets/stylesheets/base/gl_bootstrap.scss b/app/assets/stylesheets/base/gl_bootstrap.scss index 0775c17181..16581e9ebf 100644 --- a/app/assets/stylesheets/base/gl_bootstrap.scss +++ b/app/assets/stylesheets/base/gl_bootstrap.scss @@ -197,3 +197,50 @@ text-decoration: underline; } } + +// Typography ================================================================= + +.text-primary, +.text-primary:hover { + color: $brand-primary; +} + +.text-success, +.text-success:hover { + color: $brand-success; +} + +.text-danger, +.text-danger:hover { + color: $brand-danger; +} + +.text-warning, +.text-warning:hover { + color: $brand-warning; +} + +.text-info, +.text-info:hover { + color: $brand-info; +} + +// Tables ===================================================================== + +table.table { + .dropdown-menu a { + text-decoration: none; + } + + .success, + .warning, + .danger, + .info { + color: #fff; + + a:not(.btn) { + text-decoration: underline; + color: #fff; + } + } +} diff --git a/app/views/import/bitbucket/status.html.haml b/app/views/import/bitbucket/status.html.haml index bcbbaadf3e..9da3c920c6 100644 --- a/app/views/import/bitbucket/status.html.haml +++ b/app/views/import/bitbucket/status.html.haml @@ -23,7 +23,7 @@ %strong= link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project] %td.job-status - if project.import_status == 'finished' - %span.cgreen + %span %i.fa.fa-check done - elsif project.import_status == 'started' diff --git a/app/views/import/github/status.html.haml b/app/views/import/github/status.html.haml index 883090a302..9c4d91013e 100644 --- a/app/views/import/github/status.html.haml +++ b/app/views/import/github/status.html.haml @@ -23,7 +23,7 @@ %strong= link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project] %td.job-status - if project.import_status == 'finished' - %span.cgreen + %span %i.fa.fa-check done - elsif project.import_status == 'started' diff --git a/app/views/import/gitlab/status.html.haml b/app/views/import/gitlab/status.html.haml index 41ac073eae..e809643d8d 100644 --- a/app/views/import/gitlab/status.html.haml +++ b/app/views/import/gitlab/status.html.haml @@ -23,7 +23,7 @@ %strong= link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project] %td.job-status - if project.import_status == 'finished' - %span.cgreen + %span %i.fa.fa-check done - elsif project.import_status == 'started' diff --git a/app/views/import/gitorious/status.html.haml b/app/views/import/gitorious/status.html.haml index ebe24747a0..645241a6c6 100644 --- a/app/views/import/gitorious/status.html.haml +++ b/app/views/import/gitorious/status.html.haml @@ -23,7 +23,7 @@ %strong= link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project] %td.job-status - if project.import_status == 'finished' - %span.cgreen + %span %i.fa.fa-check done - elsif project.import_status == 'started' From a1f5ae98e2afde84b028d17b489d7461f64a03d9 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Thu, 12 Mar 2015 10:10:19 -0700 Subject: [PATCH 13/75] Show asterisks instead of password in service edit form. --- app/helpers/projects_helper.rb | 10 ++++++++++ app/views/projects/services/_form.html.haml | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index a5d7372bbe..2225b11065 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -265,4 +265,14 @@ module ProjectsHelper "success" end end + + def service_field_value(type, value) + return value unless type == 'password' + + if value.present? + "***********" + else + nil + end + end end diff --git a/app/views/projects/services/_form.html.haml b/app/views/projects/services/_form.html.haml index eda59e6708..3492dd5bab 100644 --- a/app/views/projects/services/_form.html.haml +++ b/app/views/projects/services/_form.html.haml @@ -75,7 +75,7 @@ - @service.fields.each do |field| - name = field[:name] - title = field[:title] || name.humanize - - value = @service.send(name) unless field[:type] == 'password' + - value = service_field_value(field[:type], @service.send(name)) - type = field[:type] - placeholder = field[:placeholder] - choices = field[:choices] @@ -94,7 +94,7 @@ - elsif type == 'select' = f.select name, options_for_select(choices, value ? value : default_choice), {}, { class: "form-control" } - elsif type == 'password' - = f.password_field name, class: 'form-control' + = f.password_field name, placeholder: value, class: 'form-control' - if help %span.help-block= help From cdb64a81a8ca96961033b8ab06d5191ef5449634 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 12 Mar 2015 10:20:24 -0700 Subject: [PATCH 14/75] Add items into changelog --- CHANGELOG | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index abb47191f8..0ec9f3177e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -53,16 +53,18 @@ v 7.9.0 (unreleased) - Make email display name configurable - Improve json validation in hook data - Use Emoji One - - Updated emoji help documentation to properly reference EmojiOne. + - Fix missing GitHub organisation repositories on import page. + - Added blue thmeme + - Remove annoying notice messages when create/update merge request + - Allow smb:// links in Markdown text. + v 7.8.4 - Fix issue_tracker_id substitution in custom issue trackers - Fix path and name duplication in namespaces v 7.8.3 - Bump version of gitlab_git fixing annotated tags without message - - Allow smb:// links in Markdown text. - - Fix missing GitHub organisation repositories on import page. v 7.8.2 - Fix service migration issue when upgrading from versions prior to 7.3 From e7f4f0ae1db4b0d940d0c4f1e4b32bebf9e6c299 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 12 Mar 2015 11:53:21 -0700 Subject: [PATCH 15/75] Block user if he/she was blocked in Active Directory --- CHANGELOG | 1 + lib/gitlab/ldap/access.rb | 9 ++++++++- spec/lib/gitlab/ldap/access_spec.rb | 7 ++++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b0adaeb101..3e0bf6e700 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -59,6 +59,7 @@ v 7.9.0 (unreleased) - Added blue thmeme - Remove annoying notice messages when create/update merge request - Allow smb:// links in Markdown text. + - Block user if he/she was blocked in Active Directory v 7.8.4 - Fix issue_tracker_id substitution in custom issue trackers diff --git a/lib/gitlab/ldap/access.rb b/lib/gitlab/ldap/access.rb index 0c85acf7e6..6e30724e1f 100644 --- a/lib/gitlab/ldap/access.rb +++ b/lib/gitlab/ldap/access.rb @@ -34,7 +34,14 @@ module Gitlab def allowed? if Gitlab::LDAP::Person.find_by_dn(user.ldap_identity.extern_uid, adapter) return true unless ldap_config.active_directory - !Gitlab::LDAP::Person.disabled_via_active_directory?(user.ldap_identity.extern_uid, adapter) + + # Block user in GitLab if he/she was blocked in AD + if Gitlab::LDAP::Person.disabled_via_active_directory?(user.ldap_identity.extern_uid, adapter) + user.block unless user.blocked? + false + else + true + end else false end diff --git a/spec/lib/gitlab/ldap/access_spec.rb b/spec/lib/gitlab/ldap/access_spec.rb index a2b0524914..39d46efcbc 100644 --- a/spec/lib/gitlab/ldap/access_spec.rb +++ b/spec/lib/gitlab/ldap/access_spec.rb @@ -20,6 +20,11 @@ describe Gitlab::LDAP::Access do before { Gitlab::LDAP::Person.stub(disabled_via_active_directory?: true) } it { is_expected.to be_falsey } + + it "should block user in GitLab" do + access.allowed? + user.should be_blocked + end end context 'and has no disabled flag in active diretory' do @@ -38,4 +43,4 @@ describe Gitlab::LDAP::Access do end end end -end \ No newline at end of file +end From 7ac62388a5ba030dd60e6aef971eb32adf39ed0d Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 12 Mar 2015 13:56:53 -0700 Subject: [PATCH 16/75] Prevent database query each time we render group avatar --- app/helpers/application_helper.rb | 9 --------- app/helpers/groups_helper.rb | 12 ++++++++++++ app/helpers/namespaces_helper.rb | 2 +- app/views/admin/groups/show.html.haml | 2 +- app/views/dashboard/groups/index.html.haml | 2 +- app/views/groups/edit.html.haml | 2 +- app/views/groups/show.html.haml | 2 +- app/views/users/_groups.html.haml | 2 +- 8 files changed, 18 insertions(+), 15 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index a81e41819b..8ed6d59c20 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -86,15 +86,6 @@ module ApplicationHelper end end - def group_icon(group_path) - group = Group.find_by(path: group_path) - if group && group.avatar.present? - group.avatar.url - else - image_path('no_group_avatar.png') - end - end - def avatar_icon(user_email = '', size = nil) user = User.find_by(email: user_email) diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb index 03fd461a46..2d0d0b494f 100644 --- a/app/helpers/groups_helper.rb +++ b/app/helpers/groups_helper.rb @@ -40,4 +40,16 @@ module GroupsHelper false end end + + def group_icon(group) + if group.is_a?(String) + group = Group.find_by(path: group) + end + + if group && group.avatar.present? + group.avatar.url + else + image_path('no_group_avatar.png') + end + end end diff --git a/app/helpers/namespaces_helper.rb b/app/helpers/namespaces_helper.rb index 2bcfde6283..b3132a1f3b 100644 --- a/app/helpers/namespaces_helper.rb +++ b/app/helpers/namespaces_helper.rb @@ -28,7 +28,7 @@ module NamespacesHelper def namespace_icon(namespace, size = 40) if namespace.kind_of?(Group) - group_icon(namespace.path) + group_icon(namespace) else avatar_icon(namespace.owner.email, size) end diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml index bb7f197292..3040faa722 100644 --- a/app/views/admin/groups/show.html.haml +++ b/app/views/admin/groups/show.html.haml @@ -12,7 +12,7 @@ Group info: %ul.well-list %li - = image_tag group_icon(@group.path), class: "avatar s60" + = image_tag group_icon(@group), class: "avatar s60" %li %span.light Name: %strong= @group.name diff --git a/app/views/dashboard/groups/index.html.haml b/app/views/dashboard/groups/index.html.haml index 50e90b1c17..f7df535251 100644 --- a/app/views/dashboard/groups/index.html.haml +++ b/app/views/dashboard/groups/index.html.haml @@ -27,7 +27,7 @@ %i.fa.fa-sign-out Leave - = image_tag group_icon(group.path), class: "avatar s40 avatar-tile" + = image_tag group_icon(group), class: "avatar s40 avatar-tile" = link_to group, class: 'group-name' do %strong= group.name diff --git a/app/views/groups/edit.html.haml b/app/views/groups/edit.html.haml index c4eb00e892..838290e4ac 100644 --- a/app/views/groups/edit.html.haml +++ b/app/views/groups/edit.html.haml @@ -12,7 +12,7 @@ .form-group .col-sm-2 .col-sm-10 - = image_tag group_icon(@group.to_param), alt: '', class: 'avatar group-avatar s160' + = image_tag group_icon(@group), alt: '', class: 'avatar group-avatar s160' %p.light - if @group.avatar? You can change your group avatar here diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index a453889f74..25efe973d4 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -1,6 +1,6 @@ .dashboard %div - = image_tag group_icon(@group.path), class: "avatar group-avatar s90" + = image_tag group_icon(@group), class: "avatar group-avatar s90" .clearfix %h2 = @group.name diff --git a/app/views/users/_groups.html.haml b/app/views/users/_groups.html.haml index cb84570a6d..f360fbb3d5 100644 --- a/app/views/users/_groups.html.haml +++ b/app/views/users/_groups.html.haml @@ -1,4 +1,4 @@ .clearfix - groups.each do |group| = link_to group, class: 'profile-groups-avatars inline', title: group.name do - = image_tag group_icon(group.path), class: 'avatar group-avatar s40' + = image_tag group_icon(group), class: 'avatar group-avatar s40' From bf0c04e5ff61cd68177e52c15128aea9b1a41427 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 12 Mar 2015 14:51:41 -0700 Subject: [PATCH 17/75] Fix specs --- spec/helpers/application_helper_spec.rb | 18 ------------------ spec/helpers/groups_helper.rb | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 18 deletions(-) create mode 100644 spec/helpers/groups_helper.rb diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index 99ff8a32ea..4c11709ed6 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -39,24 +39,6 @@ describe ApplicationHelper do end end - describe 'group_icon' do - avatar_file_path = File.join(Rails.root, 'public', 'gitlab_logo.png') - - it 'should return an url for the avatar' do - group = create(:group) - group.avatar = File.open(avatar_file_path) - group.save! - expect(group_icon(group.path).to_s). - to match("/uploads/group/avatar/#{ group.id }/gitlab_logo.png") - end - - it 'should give default avatar_icon when no avatar is present' do - group = create(:group) - group.save! - expect(group_icon(group.path)).to match('group_avatar.png') - end - end - describe 'project_icon' do avatar_file_path = File.join(Rails.root, 'public', 'gitlab_logo.png') diff --git a/spec/helpers/groups_helper.rb b/spec/helpers/groups_helper.rb new file mode 100644 index 0000000000..3e99ab84ec --- /dev/null +++ b/spec/helpers/groups_helper.rb @@ -0,0 +1,21 @@ +require 'spec_helper' + +describe GroupsHelper do + describe 'group_icon' do + avatar_file_path = File.join(Rails.root, 'public', 'gitlab_logo.png') + + it 'should return an url for the avatar' do + group = create(:group) + group.avatar = File.open(avatar_file_path) + group.save! + expect(group_icon(group.path).to_s). + to match("/uploads/group/avatar/#{ group.id }/gitlab_logo.png") + end + + it 'should give default avatar_icon when no avatar is present' do + group = create(:group) + group.save! + expect(group_icon(group.path)).to match('group_avatar.png') + end + end +end From f0cbbd70bba7c44e9b09a3472e6c2f6f58623150 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 12 Mar 2015 15:37:00 -0700 Subject: [PATCH 18/75] Use same constant for amount of items per page --- app/controllers/admin/groups_controller.rb | 6 +++--- app/controllers/admin/projects_controller.rb | 6 +++--- app/controllers/application_controller.rb | 2 ++ app/controllers/dashboard/groups_controller.rb | 2 +- app/controllers/dashboard/milestones_controller.rb | 2 +- app/controllers/dashboard_controller.rb | 4 ++-- app/controllers/explore/groups_controller.rb | 2 +- app/controllers/explore/projects_controller.rb | 6 +++--- app/controllers/groups/milestones_controller.rb | 2 +- app/controllers/groups_controller.rb | 4 ++-- app/controllers/profiles_controller.rb | 2 +- app/controllers/projects/branches_controller.rb | 2 +- app/controllers/projects/issues_controller.rb | 2 +- app/controllers/projects/labels_controller.rb | 2 +- app/controllers/projects/merge_requests_controller.rb | 2 +- app/controllers/projects/milestones_controller.rb | 2 +- app/controllers/projects/tags_controller.rb | 2 +- app/controllers/projects/wikis_controller.rb | 2 +- app/controllers/snippets_controller.rb | 4 ++-- 19 files changed, 29 insertions(+), 27 deletions(-) diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb index 65dc027c8e..e338abeac4 100644 --- a/app/controllers/admin/groups_controller.rb +++ b/app/controllers/admin/groups_controller.rb @@ -5,12 +5,12 @@ class Admin::GroupsController < Admin::ApplicationController @groups = Group.all @groups = @groups.sort(@sort = params[:sort]) @groups = @groups.search(params[:name]) if params[:name].present? - @groups = @groups.page(params[:page]).per(20) + @groups = @groups.page(params[:page]).per(PER_PAGE) end def show - @members = @group.members.order("access_level DESC").page(params[:members_page]).per(30) - @projects = @group.projects.page(params[:projects_page]).per(30) + @members = @group.members.order("access_level DESC").page(params[:members_page]).per(PER_PAGE) + @projects = @group.projects.page(params[:projects_page]).per(PER_PAGE) end def new diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb index 2b1fc862b7..5176a8399a 100644 --- a/app/controllers/admin/projects_controller.rb +++ b/app/controllers/admin/projects_controller.rb @@ -11,15 +11,15 @@ class Admin::ProjectsController < Admin::ApplicationController @projects = @projects.abandoned if params[:abandoned].present? @projects = @projects.search(params[:name]) if params[:name].present? @projects = @projects.sort(@sort = params[:sort]) - @projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]).per(20) + @projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]).per(PER_PAGE) end def show if @group - @group_members = @group.members.order("access_level DESC").page(params[:group_members_page]).per(30) + @group_members = @group.members.order("access_level DESC").page(params[:group_members_page]).per(PER_PAGE) end - @project_members = @project.project_members.page(params[:project_members_page]).per(30) + @project_members = @project.project_members.page(params[:project_members_page]).per(PER_PAGE) end def transfer diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index df1a588313..e284f31f7e 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -4,6 +4,8 @@ class ApplicationController < ActionController::Base include Gitlab::CurrentSettings include GitlabRoutingHelper + PER_PAGE = 20 + before_filter :authenticate_user_from_token! before_filter :authenticate_user! before_filter :reject_blocked! diff --git a/app/controllers/dashboard/groups_controller.rb b/app/controllers/dashboard/groups_controller.rb index 61d691e636..b827639978 100644 --- a/app/controllers/dashboard/groups_controller.rb +++ b/app/controllers/dashboard/groups_controller.rb @@ -1,6 +1,6 @@ class Dashboard::GroupsController < ApplicationController def index - @user_groups = current_user.group_members.page(params[:page]).per(20) + @user_groups = current_user.group_members.page(params[:page]).per(PER_PAGE) end def leave diff --git a/app/controllers/dashboard/milestones_controller.rb b/app/controllers/dashboard/milestones_controller.rb index 386e283f3a..cb51792df1 100644 --- a/app/controllers/dashboard/milestones_controller.rb +++ b/app/controllers/dashboard/milestones_controller.rb @@ -8,7 +8,7 @@ class Dashboard::MilestonesController < ApplicationController else state('active') end @dashboard_milestones = Milestones::GroupService.new(project_milestones).execute - @dashboard_milestones = Kaminari.paginate_array(@dashboard_milestones).page(params[:page]).per(30) + @dashboard_milestones = Kaminari.paginate_array(@dashboard_milestones).page(params[:page]).per(PER_PAGE) end def show diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 0500619909..9bd853ed5c 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -25,13 +25,13 @@ class DashboardController < ApplicationController def merge_requests @merge_requests = get_merge_requests_collection - @merge_requests = @merge_requests.page(params[:page]).per(20) + @merge_requests = @merge_requests.page(params[:page]).per(PER_PAGE) @merge_requests = @merge_requests.preload(:author, :target_project) end def issues @issues = get_issues_collection - @issues = @issues.page(params[:page]).per(20) + @issues = @issues.page(params[:page]).per(PER_PAGE) @issues = @issues.preload(:author, :project) respond_to do |format| diff --git a/app/controllers/explore/groups_controller.rb b/app/controllers/explore/groups_controller.rb index ada7031fea..c51a4a211a 100644 --- a/app/controllers/explore/groups_controller.rb +++ b/app/controllers/explore/groups_controller.rb @@ -8,6 +8,6 @@ class Explore::GroupsController < ApplicationController @groups = GroupsFinder.new.execute(current_user) @groups = @groups.search(params[:search]) if params[:search].present? @groups = @groups.sort(@sort = params[:sort]) - @groups = @groups.page(params[:page]).per(20) + @groups = @groups.page(params[:page]).per(PER_PAGE) end end diff --git a/app/controllers/explore/projects_controller.rb b/app/controllers/explore/projects_controller.rb index d664624fa6..b295f295bb 100644 --- a/app/controllers/explore/projects_controller.rb +++ b/app/controllers/explore/projects_controller.rb @@ -11,17 +11,17 @@ class Explore::ProjectsController < ApplicationController @projects = @projects.where(visibility_level: params[:visibility_level]) if params[:visibility_level].present? @projects = @projects.search(params[:search]) if params[:search].present? @projects = @projects.sort(@sort = params[:sort]) - @projects = @projects.includes(:namespace).page(params[:page]).per(20) + @projects = @projects.includes(:namespace).page(params[:page]).per(PER_PAGE) end def trending @trending_projects = TrendingProjectsFinder.new.execute(current_user) - @trending_projects = @trending_projects.page(params[:page]).per(10) + @trending_projects = @trending_projects.page(params[:page]).per(PER_PAGE) end def starred @starred_projects = ProjectsFinder.new.execute(current_user) @starred_projects = @starred_projects.reorder('star_count DESC') - @starred_projects = @starred_projects.page(params[:page]).per(10) + @starred_projects = @starred_projects.page(params[:page]).per(PER_PAGE) end end diff --git a/app/controllers/groups/milestones_controller.rb b/app/controllers/groups/milestones_controller.rb index 6802e529b5..c46b8fff88 100644 --- a/app/controllers/groups/milestones_controller.rb +++ b/app/controllers/groups/milestones_controller.rb @@ -10,7 +10,7 @@ class Groups::MilestonesController < ApplicationController else state('active') end @group_milestones = Milestones::GroupService.new(project_milestones).execute - @group_milestones = Kaminari.paginate_array(@group_milestones).page(params[:page]).per(30) + @group_milestones = Kaminari.paginate_array(@group_milestones).page(params[:page]).per(PER_PAGE) end def show diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 89f94fa0d4..7e336803fb 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -52,13 +52,13 @@ class GroupsController < Groups::ApplicationController def merge_requests @merge_requests = get_merge_requests_collection - @merge_requests = @merge_requests.page(params[:page]).per(20) + @merge_requests = @merge_requests.page(params[:page]).per(PER_PAGE) @merge_requests = @merge_requests.preload(:author, :target_project) end def issues @issues = get_issues_collection - @issues = @issues.page(params[:page]).per(20) + @issues = @issues.page(params[:page]).per(PER_PAGE) @issues = @issues.preload(:author, :project) respond_to do |format| diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb index a7863aba75..1b9a86ee42 100644 --- a/app/controllers/profiles_controller.rb +++ b/app/controllers/profiles_controller.rb @@ -43,7 +43,7 @@ class ProfilesController < ApplicationController end def history - @events = current_user.recent_events.page(params[:page]).per(20) + @events = current_user.recent_events.page(params[:page]).per(PER_PAGE) end def update_username diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb index 690501f306..f049e96e61 100644 --- a/app/controllers/projects/branches_controller.rb +++ b/app/controllers/projects/branches_controller.rb @@ -8,7 +8,7 @@ class Projects::BranchesController < Projects::ApplicationController def index @sort = params[:sort] || 'name' @branches = @repository.branches_sorted_by(@sort) - @branches = Kaminari.paginate_array(@branches).page(params[:page]).per(30) + @branches = Kaminari.paginate_array(@branches).page(params[:page]).per(PER_PAGE) end def recent diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index 1f1a9b4d43..4266bcaef1 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -20,7 +20,7 @@ class Projects::IssuesController < Projects::ApplicationController terms = params['issue_search'] @issues = get_issues_collection @issues = @issues.full_search(terms) if terms.present? - @issues = @issues.page(params[:page]).per(20) + @issues = @issues.page(params[:page]).per(PER_PAGE) respond_to do |format| format.html diff --git a/app/controllers/projects/labels_controller.rb b/app/controllers/projects/labels_controller.rb index 5e31fce4b0..207a01ed3b 100644 --- a/app/controllers/projects/labels_controller.rb +++ b/app/controllers/projects/labels_controller.rb @@ -7,7 +7,7 @@ class Projects::LabelsController < Projects::ApplicationController respond_to :js, :html def index - @labels = @project.labels.page(params[:page]).per(20) + @labels = @project.labels.page(params[:page]).per(PER_PAGE) end def new diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 57c017e799..10c34584c8 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -18,7 +18,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController def index @merge_requests = get_merge_requests_collection - @merge_requests = @merge_requests.page(params[:page]).per(20) + @merge_requests = @merge_requests.page(params[:page]).per(PER_PAGE) end def show diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb index afdb560e73..b49b549547 100644 --- a/app/controllers/projects/milestones_controller.rb +++ b/app/controllers/projects/milestones_controller.rb @@ -18,7 +18,7 @@ class Projects::MilestonesController < Projects::ApplicationController end @milestones = @milestones.includes(:project) - @milestones = @milestones.page(params[:page]).per(20) + @milestones = @milestones.page(params[:page]).per(PER_PAGE) end def new diff --git a/app/controllers/projects/tags_controller.rb b/app/controllers/projects/tags_controller.rb index 03fface2d2..c4f27a6d98 100644 --- a/app/controllers/projects/tags_controller.rb +++ b/app/controllers/projects/tags_controller.rb @@ -7,7 +7,7 @@ class Projects::TagsController < Projects::ApplicationController def index sorted = VersionSorter.rsort(@repository.tag_names) - @tags = Kaminari.paginate_array(sorted).page(params[:page]).per(30) + @tags = Kaminari.paginate_array(sorted).page(params[:page]).per(PER_PAGE) end def create diff --git a/app/controllers/projects/wikis_controller.rb b/app/controllers/projects/wikis_controller.rb index 3392fbca91..643167947b 100644 --- a/app/controllers/projects/wikis_controller.rb +++ b/app/controllers/projects/wikis_controller.rb @@ -7,7 +7,7 @@ class Projects::WikisController < Projects::ApplicationController before_filter :load_project_wiki def pages - @wiki_pages = Kaminari.paginate_array(@project_wiki.pages).page(params[:page]).per(30) + @wiki_pages = Kaminari.paginate_array(@project_wiki.pages).page(params[:page]).per(PER_PAGE) end def show diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index 6ac048e4b8..ae501362dc 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -16,7 +16,7 @@ class SnippetsController < ApplicationController layout :determine_layout def index - @snippets = SnippetsFinder.new.execute(current_user, filter: :all).page(params[:page]).per(20) + @snippets = SnippetsFinder.new.execute(current_user, filter: :all).page(params[:page]).per(PER_PAGE) end def user_index @@ -28,7 +28,7 @@ class SnippetsController < ApplicationController filter: :by_user, user: @user, scope: params[:scope] }). - page(params[:page]).per(20) + page(params[:page]).per(PER_PAGE) if @user == current_user render 'current_user_index' From 80b2f3fb86d6e6b16565b9e9de82dda169926bcb Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 12 Mar 2015 16:20:58 -0700 Subject: [PATCH 19/75] Implement merge requests search It is same search like we have at issues page. It allows to quickly filter merge requests based on title or desription. I copy-pasted some js code from Issues.js. In future search (filtering) logic should be refactoed into one class for merge requests and issues --- CHANGELOG | 1 + app/assets/javascripts/dispatcher.js.coffee | 1 + app/assets/javascripts/issues.js.coffee | 2 +- .../javascripts/merge_requests.js.coffee | 37 ++++++++++++++++--- .../projects/merge_requests_controller.rb | 11 ++++++ app/views/projects/issues/index.html.haml | 9 +---- .../merge_requests/_merge_requests.html.haml | 13 +++++++ .../projects/merge_requests/index.html.haml | 31 +++++----------- .../shared/_issuable_search_form.html.haml | 9 +++++ features/project/merge_requests.feature | 7 ++++ features/steps/project/merge_requests.rb | 4 ++ 11 files changed, 90 insertions(+), 35 deletions(-) create mode 100644 app/views/projects/merge_requests/_merge_requests.html.haml create mode 100644 app/views/shared/_issuable_search_form.html.haml diff --git a/CHANGELOG b/CHANGELOG index b0adaeb101..d352656eba 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -59,6 +59,7 @@ v 7.9.0 (unreleased) - Added blue thmeme - Remove annoying notice messages when create/update merge request - Allow smb:// links in Markdown text. + - Filter merge request by title or description at Merge Requests page v 7.8.4 - Fix issue_tracker_id substitution in custom issue trackers diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee index 928232e95b..e1015a63d5 100644 --- a/app/assets/javascripts/dispatcher.js.coffee +++ b/app/assets/javascripts/dispatcher.js.coffee @@ -52,6 +52,7 @@ class Dispatcher new ZenMode() when 'projects:merge_requests:index' shortcut_handler = new ShortcutsNavigation() + MergeRequests.init() when 'dashboard:show' new Dashboard() new Activities() diff --git a/app/assets/javascripts/issues.js.coffee b/app/assets/javascripts/issues.js.coffee index 6513f4bcef..40bb9e9cb0 100644 --- a/app/assets/javascripts/issues.js.coffee +++ b/app/assets/javascripts/issues.js.coffee @@ -47,7 +47,7 @@ initSearch: -> @timer = null $("#issue_search").keyup -> - clearTimeout(@timer); + clearTimeout(@timer) @timer = setTimeout(Issues.filterResults, 500) filterResults: => diff --git a/app/assets/javascripts/merge_requests.js.coffee b/app/assets/javascripts/merge_requests.js.coffee index 9201c84c5e..83434c1b9b 100644 --- a/app/assets/javascripts/merge_requests.js.coffee +++ b/app/assets/javascripts/merge_requests.js.coffee @@ -1,8 +1,35 @@ # # * Filter merge requests # -@merge_requestsPage = -> - $('#assignee_id').select2() - $('#milestone_id').select2() - $('#milestone_id, #assignee_id').on 'change', -> - $(this).closest('form').submit() +@MergeRequests = + init: -> + MergeRequests.initSearch() + + # Make sure we trigger ajax request only after user stop typing + initSearch: -> + @timer = null + $("#issue_search").keyup -> + clearTimeout(@timer) + @timer = setTimeout(MergeRequests.filterResults, 500) + + filterResults: => + form = $("#issue_search_form") + search = $("#issue_search").val() + $('.merge-requests-holder').css("opacity", '0.5') + issues_url = form.attr('action') + '? '+ form.serialize() + + $.ajax + type: "GET" + url: form.attr('action') + data: form.serialize() + complete: -> + $('.merge-requests-holder').css("opacity", '1.0') + success: (data) -> + $('.merge-requests-holder').html(data.html) + # Change url so if user reload a page - search results are saved + History.replaceState {page: issues_url}, document.title, issues_url + MergeRequests.reload() + dataType: "json" + + reload: -> + $('#filter_issue_search').val($('#issue_search').val()) diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 57c017e799..a8bc544789 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -17,8 +17,19 @@ class Projects::MergeRequestsController < Projects::ApplicationController before_filter :authorize_modify_merge_request!, only: [:close, :edit, :update, :sort] def index + terms = params['issue_search'] @merge_requests = get_merge_requests_collection + @merge_requests = @merge_requests.full_search(terms) if terms.present? @merge_requests = @merge_requests.page(params[:page]).per(20) + + respond_to do |format| + format.html + format.json do + render json: { + html: view_to_html_string("projects/merge_requests/_merge_requests") + } + end + end end def show diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml index cbbcb1d06c..2cb94d10b6 100644 --- a/app/views/projects/issues/index.html.haml +++ b/app/views/projects/issues/index.html.haml @@ -6,14 +6,7 @@ = link_to namespace_project_issues_path(@project.namespace, @project, :atom, { private_token: current_user.private_token }), class: 'btn append-right-10' do %i.fa.fa-rss - = form_tag namespace_project_issues_path(@project.namespace, @project), method: :get, id: "issue_search_form", class: 'pull-left issue-search-form' do - .append-right-10.hidden-xs.hidden-sm - = search_field_tag :issue_search, params[:issue_search], { placeholder: 'Filter by title or description', class: 'form-control issue_search search-text-input input-mn-300' } - = hidden_field_tag :state, params['state'] - = hidden_field_tag :scope, params['scope'] - = hidden_field_tag :assignee_id, params['assignee_id'] - = hidden_field_tag :milestone_id, params['milestone_id'] - = hidden_field_tag :label_id, params['label_id'] + = render 'shared/issuable_search_form', path: namespace_project_issues_path(@project.namespace, @project) - if can? current_user, :write_issue, @project = link_to new_namespace_project_issue_path(@project.namespace, @project, issue: { assignee_id: params[:assignee_id], milestone_id: params[:milestone_id]}), class: "btn btn-new pull-left", title: "New Issue", id: "new_issue_link" do diff --git a/app/views/projects/merge_requests/_merge_requests.html.haml b/app/views/projects/merge_requests/_merge_requests.html.haml new file mode 100644 index 0000000000..b8a0ca9a42 --- /dev/null +++ b/app/views/projects/merge_requests/_merge_requests.html.haml @@ -0,0 +1,13 @@ +.panel.panel-default + %ul.well-list.mr-list + = render @merge_requests + - if @merge_requests.blank? + %li + .nothing-here-block No merge requests to show + +- if @merge_requests.present? + .pull-right + %span.cgray.pull-right #{@merge_requests.total_count} merge requests for this filter + + = paginate @merge_requests, theme: "gitlab" + diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml index e3b9a28033..d7992bdd19 100644 --- a/app/views/projects/merge_requests/index.html.haml +++ b/app/views/projects/merge_requests/index.html.haml @@ -1,22 +1,11 @@ +.append-bottom-10 + .pull-right + = render 'shared/issuable_search_form', path: namespace_project_merge_requests_path(@project.namespace, @project) + + - if can? current_user, :write_merge_request, @project + = link_to new_namespace_project_merge_request_path(@project.namespace, @project), class: "btn btn-new pull-left", title: "New Merge Request" do + %i.fa.fa-plus + New Merge Request + = render 'shared/issuable_filter' .merge-requests-holder - .append-bottom-10 - .pull-right - - if can? current_user, :write_merge_request, @project - = link_to new_namespace_project_merge_request_path(@project.namespace, @project), class: "btn btn-new pull-left", title: "New Merge Request" do - %i.fa.fa-plus - New Merge Request - = render 'shared/issuable_filter' - .panel.panel-default - %ul.well-list.mr-list - = render @merge_requests - - if @merge_requests.blank? - %li - .nothing-here-block No merge requests to show - - if @merge_requests.present? - .pull-right - %span.cgray.pull-right #{@merge_requests.total_count} merge requests for this filter - - = paginate @merge_requests, theme: "gitlab" - -:javascript - $(merge_requestsPage); + = render 'merge_requests' diff --git a/app/views/shared/_issuable_search_form.html.haml b/app/views/shared/_issuable_search_form.html.haml new file mode 100644 index 0000000000..639d203dcd --- /dev/null +++ b/app/views/shared/_issuable_search_form.html.haml @@ -0,0 +1,9 @@ += form_tag(path, method: :get, id: "issue_search_form", class: 'pull-left issue-search-form') do + .append-right-10.hidden-xs.hidden-sm + = search_field_tag :issue_search, params[:issue_search], { placeholder: 'Filter by title or description', class: 'form-control issue_search search-text-input input-mn-300' } + = hidden_field_tag :state, params['state'] + = hidden_field_tag :scope, params['scope'] + = hidden_field_tag :assignee_id, params['assignee_id'] + = hidden_field_tag :author_id, params['author_id'] + = hidden_field_tag :milestone_id, params['milestone_id'] + = hidden_field_tag :label_id, params['label_id'] diff --git a/features/project/merge_requests.feature b/features/project/merge_requests.feature index 7c029f05d7..adad100e56 100644 --- a/features/project/merge_requests.feature +++ b/features/project/merge_requests.feature @@ -218,3 +218,10 @@ Feature: Project Merge Requests And I click link "Edit" for the merge request And I preview a description text like "Bug fixed :smile:" Then I should see the Markdown write tab + + @javascript + Scenario: I search merge request + Given I click link "All" + When I fill in merge request search with "Fe" + Then I should see "Feature NS-03" in merge requests + And I should not see "Bug NS-04" in merge requests diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb index 263f2ef243..b67b2e58ca 100644 --- a/features/steps/project/merge_requests.rb +++ b/features/steps/project/merge_requests.rb @@ -276,6 +276,10 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps end end + step 'I fill in merge request search with "Fe"' do + fill_in 'issue_search', with: "Fe" + end + def merge_request @merge_request ||= MergeRequest.find_by!(title: "Bug NS-05") end From 2718955441587618933a632008b85762247081a2 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 13 Mar 2015 13:47:26 +0100 Subject: [PATCH 20/75] Fix import pages not working after first load. --- CHANGELOG | 1 + lib/gitlab/bitbucket_import/client.rb | 2 +- lib/gitlab/github_import/client.rb | 2 +- lib/gitlab/gitlab_import/client.rb | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 97376c85ec..7c7cbb366e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -61,6 +61,7 @@ v 7.9.0 (unreleased) - Allow smb:// links in Markdown text. - Filter merge request by title or description at Merge Requests page - Block user if he/she was blocked in Active Directory + - Fix import pages not working after first load. v 7.8.4 - Fix issue_tracker_id substitution in custom issue trackers diff --git a/lib/gitlab/bitbucket_import/client.rb b/lib/gitlab/bitbucket_import/client.rb index c907bebaef..1e4906c9e3 100644 --- a/lib/gitlab/bitbucket_import/client.rb +++ b/lib/gitlab/bitbucket_import/client.rb @@ -92,7 +92,7 @@ module Gitlab end def bitbucket_options - OmniAuth::Strategies::Bitbucket.default_options[:client_options] + OmniAuth::Strategies::Bitbucket.default_options[:client_options].dup end end end diff --git a/lib/gitlab/github_import/client.rb b/lib/gitlab/github_import/client.rb index 676d226bdd..7fe076b333 100644 --- a/lib/gitlab/github_import/client.rb +++ b/lib/gitlab/github_import/client.rb @@ -46,7 +46,7 @@ module Gitlab end def github_options - OmniAuth::Strategies::GitHub.default_options[:client_options] + OmniAuth::Strategies::GitHub.default_options[:client_options].dup end end end diff --git a/lib/gitlab/gitlab_import/client.rb b/lib/gitlab/gitlab_import/client.rb index ecf4ff94e3..2236439c6c 100644 --- a/lib/gitlab/gitlab_import/client.rb +++ b/lib/gitlab/gitlab_import/client.rb @@ -71,7 +71,7 @@ module Gitlab end def gitlab_options - OmniAuth::Strategies::GitLab.default_options[:client_options] + OmniAuth::Strategies::GitLab.default_options[:client_options].dup end end end From f96dc6295aeb6f7d731c635c1a8a8ff609b4510f Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 6 Mar 2015 12:25:31 +0100 Subject: [PATCH 21/75] Everything from gitlab_git is already UTF-8. --- app/controllers/projects/graphs_controller.rb | 4 ++-- app/models/repository.rb | 4 ++-- app/views/projects/blame/show.html.haml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/controllers/projects/graphs_controller.rb b/app/controllers/projects/graphs_controller.rb index 752474b4a4..6e54af356e 100644 --- a/app/controllers/projects/graphs_controller.rb +++ b/app/controllers/projects/graphs_controller.rb @@ -28,8 +28,8 @@ class Projects::GraphsController < Projects::ApplicationController @commits.each do |commit| @log << { - author_name: commit.author_name.force_encoding('UTF-8'), - author_email: commit.author_email.force_encoding('UTF-8'), + author_name: commit.author_name, + author_email: commit.author_email, date: commit.committed_date.strftime("%Y-%m-%d") } end diff --git a/app/models/repository.rb b/app/models/repository.rb index 6117db418a..47758b8ad6 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -136,8 +136,8 @@ class Repository commit = Gitlab::Git::Commit.new(rugged_commit) { - author_name: commit.author_name.force_encoding('UTF-8'), - author_email: commit.author_email.force_encoding('UTF-8'), + author_name: commit.author_name, + author_email: commit.author_email, additions: commit.stats.additions, deletions: commit.stats.deletions, } diff --git a/app/views/projects/blame/show.html.haml b/app/views/projects/blame/show.html.haml index 5a33d18e63..4cc1fedb1c 100644 --- a/app/views/projects/blame/show.html.haml +++ b/app/views/projects/blame/show.html.haml @@ -30,5 +30,5 @@ %code :erb <% lines.each do |line| %> - <%= highlight(@blob.name, line.force_encoding("utf-8"), true).html_safe %> + <%= highlight(@blob.name, line, true).html_safe %> <% end %> From 7f4cffd88b393a55f6462ce870807c7afd7ca98a Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 6 Mar 2015 12:25:42 +0100 Subject: [PATCH 22/75] Reuse blob object fetched by Gitlab::Git::Blame. --- app/controllers/projects/blame_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/projects/blame_controller.rb b/app/controllers/projects/blame_controller.rb index 489a6ae566..a87b8270a2 100644 --- a/app/controllers/projects/blame_controller.rb +++ b/app/controllers/projects/blame_controller.rb @@ -7,7 +7,7 @@ class Projects::BlameController < Projects::ApplicationController before_filter :authorize_download_code! def show - @blob = @repository.blob_at(@commit.id, @path) - @blame = Gitlab::Git::Blame.new(project.repository, @commit.id, @path) + @blame = Gitlab::Git::Blame.new(@repository, @commit.id, @path) + @blob = @blame.blob end end From 4e49f21b141e8cbbf581c119c7524f6e9553f136 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 13 Mar 2015 14:51:48 +0100 Subject: [PATCH 23/75] Set push data object kind in PushDataBuilder. --- app/services/create_tag_service.rb | 4 +--- app/services/git_tag_push_service.rb | 4 +--- lib/gitlab/push_data_builder.rb | 3 ++- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/app/services/create_tag_service.rb b/app/services/create_tag_service.rb index dfc5677c9d..755202310a 100644 --- a/app/services/create_tag_service.rb +++ b/app/services/create_tag_service.rb @@ -40,9 +40,7 @@ class CreateTagService < BaseService end def create_push_data(project, user, tag) - data = Gitlab::PushDataBuilder. + Gitlab::PushDataBuilder. build(project, user, Gitlab::Git::BLANK_SHA, tag.target, "#{Gitlab::Git::TAG_REF_PREFIX}#{tag.name}", []) - data[:object_kind] = "tag_push" - data end end diff --git a/app/services/git_tag_push_service.rb b/app/services/git_tag_push_service.rb index cd92f50b02..666bc482f8 100644 --- a/app/services/git_tag_push_service.rb +++ b/app/services/git_tag_push_service.rb @@ -16,8 +16,6 @@ class GitTagPushService private def create_push_data(oldrev, newrev, ref) - data = Gitlab::PushDataBuilder.build(project, user, oldrev, newrev, ref, []) - data[:object_kind] = "tag_push" - data + Gitlab::PushDataBuilder.build(project, user, oldrev, newrev, ref, []) end end diff --git a/lib/gitlab/push_data_builder.rb b/lib/gitlab/push_data_builder.rb index 0cc6b0ac69..ea9012b884 100644 --- a/lib/gitlab/push_data_builder.rb +++ b/lib/gitlab/push_data_builder.rb @@ -28,9 +28,10 @@ module Gitlab # Get latest 20 commits ASC commits_limited = commits.last(20) + type = Gitlab::Git.tag_ref?(ref) ? "tag_push" : "push" # Hash to be passed as post_receive_data data = { - object_kind: "push", + object_kind: type, before: oldrev, after: newrev, ref: ref, From 09791774a594972d410fa72f5e0a256f19f0915a Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 13 Mar 2015 15:42:31 +0100 Subject: [PATCH 24/75] Use custom LDAP label in LDAP signin form. --- CHANGELOG | 1 + app/views/devise/sessions/_new_ldap.html.haml | 6 +++--- app/views/devise/shared/_signin_box.html.haml | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 97376c85ec..6342e68805 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -61,6 +61,7 @@ v 7.9.0 (unreleased) - Allow smb:// links in Markdown text. - Filter merge request by title or description at Merge Requests page - Block user if he/she was blocked in Active Directory + - Use custom LDAP label in LDAP signin form. v 7.8.4 - Fix issue_tracker_id substitution in custom issue trackers diff --git a/app/views/devise/sessions/_new_ldap.html.haml b/app/views/devise/sessions/_new_ldap.html.haml index e986989a72..812e22373a 100644 --- a/app/views/devise/sessions/_new_ldap.html.haml +++ b/app/views/devise/sessions/_new_ldap.html.haml @@ -1,4 +1,4 @@ -= form_tag(user_omniauth_callback_path(provider), id: 'new_ldap_user' ) do - = text_field_tag :username, nil, {class: "form-control top", placeholder: "LDAP Login", autofocus: "autofocus"} += form_tag(user_omniauth_callback_path(server['provider_name']), id: 'new_ldap_user' ) do + = text_field_tag :username, nil, {class: "form-control top", placeholder: "#{server['label']} Login", autofocus: "autofocus"} = password_field_tag :password, nil, {class: "form-control bottom", placeholder: "Password"} - = button_tag "LDAP Sign in", class: "btn-save btn" + = button_tag "#{server['label']} Sign in", class: "btn-save btn" diff --git a/app/views/devise/shared/_signin_box.html.haml b/app/views/devise/shared/_signin_box.html.haml index 8faa6398a6..c76574db45 100644 --- a/app/views/devise/shared/_signin_box.html.haml +++ b/app/views/devise/shared/_signin_box.html.haml @@ -17,7 +17,7 @@ .tab-content - @ldap_servers.each_with_index do |server, i| %div.tab-pane{id: "tab-#{server['provider_name']}", class: (:active if i.zero?)} - = render 'devise/sessions/new_ldap', provider: server['provider_name'] + = render 'devise/sessions/new_ldap', server: server - if signin_enabled? %div#tab-signin.tab-pane = render 'devise/sessions/new_base' From affb5b3ff48f9037349eac77f86adb7c946663ce Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Fri, 13 Mar 2015 07:48:35 -0700 Subject: [PATCH 25/75] Update documentation for object_kind field in Webhook push and tag push Webhooks --- CHANGELOG | 1 + doc/web_hooks/web_hooks.md | 2 ++ 2 files changed, 3 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 97376c85ec..a2e139eca3 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.9.0 (unreleased) + - Update documentation for object_kind field in Webhook push and tag push Webhooks (Stan Hu) - Fix broken email images (Hannes Rosenögger) - Fix mass SQL statements on initial push (Hannes Rosenögger) - Add tag push notifications and normalize HipChat and Slack messages to be consistent (Stan Hu) diff --git a/doc/web_hooks/web_hooks.md b/doc/web_hooks/web_hooks.md index 3cccd84b06..851f50f5e9 100644 --- a/doc/web_hooks/web_hooks.md +++ b/doc/web_hooks/web_hooks.md @@ -16,6 +16,7 @@ Triggered when you push to the repository except when pushing tags. ```json { + "object_kind": "push", "before": "95790bf891e76fee5e1747ab589903a6a1f80f22", "after": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", "ref": "refs/heads/master", @@ -66,6 +67,7 @@ Triggered when you create (or delete) tags to the repository. ```json { + "object_kind": "tag_push", "ref": "refs/tags/v1.0.0", "before": "0000000000000000000000000000000000000000", "after": "82b3d5ae55f7080f1e6022629cdb57bfae7cccc7", From 84d28209b6f8a63f35ad082bc8851e28550643e1 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 13 Mar 2015 14:55:17 +0100 Subject: [PATCH 26/75] Use PushDataBuilder where applicable. --- app/services/create_branch_service.rb | 14 +++++++++++--- app/services/create_tag_service.rb | 4 ++-- app/services/delete_branch_service.rb | 11 +++++++++-- app/services/event_create_service.rb | 20 -------------------- 4 files changed, 22 insertions(+), 27 deletions(-) diff --git a/app/services/create_branch_service.rb b/app/services/create_branch_service.rb index 5e971c7891..f835f06e72 100644 --- a/app/services/create_branch_service.rb +++ b/app/services/create_branch_service.rb @@ -17,10 +17,13 @@ class CreateBranchService < BaseService new_branch = repository.find_branch(branch_name) if new_branch - EventCreateService.new.push_ref(project, current_user, new_branch, 'add') - return success(new_branch) + push_data = build_push_data(project, current_user, new_branch) + + EventCreateService.new.push(project, current_user, push_data) + + success(new_branch) else - return error('Invalid reference name') + error('Invalid reference name') end end @@ -29,4 +32,9 @@ class CreateBranchService < BaseService out[:branch] = branch out end + + def build_push_data(project, user, branch) + Gitlab::PushDataBuilder. + build(project, user, Gitlab::Git::BLANK_SHA, branch.target, "#{Gitlab::Git::BRANCH_REF_PREFIX}#{branch.name}", []) + end end diff --git a/app/services/create_tag_service.rb b/app/services/create_tag_service.rb index 755202310a..af4b537cb9 100644 --- a/app/services/create_tag_service.rb +++ b/app/services/create_tag_service.rb @@ -21,9 +21,9 @@ class CreateTagService < BaseService new_tag = repository.find_tag(tag_name) if new_tag - EventCreateService.new.push_ref(project, current_user, new_tag, 'add', Gitlab::Git::TAG_REF_PREFIX) - push_data = create_push_data(project, current_user, new_tag) + + EventCreateService.new.push(project, current_user, push_data) project.execute_hooks(push_data.dup, :tag_push_hooks) project.execute_services(push_data.dup, :tag_push_hooks) diff --git a/app/services/delete_branch_service.rb b/app/services/delete_branch_service.rb index c26aee2b0a..f2d5ed818c 100644 --- a/app/services/delete_branch_service.rb +++ b/app/services/delete_branch_service.rb @@ -25,10 +25,12 @@ class DeleteBranchService < BaseService end if repository.rm_branch(branch_name) - EventCreateService.new.push_ref(project, current_user, branch, 'rm') + push_data = build_push_data(branch) + + EventCreateService.new.push(project, current_user, push_data) success('Branch was removed') else - return error('Failed to remove branch') + error('Failed to remove branch') end end @@ -43,4 +45,9 @@ class DeleteBranchService < BaseService out[:message] = message out end + + def build_push_data(branch) + Gitlab::PushDataBuilder + .build(project, current_user, branch.target, Gitlab::Git::BLANK_SHA, "#{Gitlab::Git::BRANCH_REF_PREFIX}#{branch.name}", []) + end end diff --git a/app/services/event_create_service.rb b/app/services/event_create_service.rb index dc52d6d89d..103d6b0a08 100644 --- a/app/services/event_create_service.rb +++ b/app/services/event_create_service.rb @@ -62,26 +62,6 @@ class EventCreateService create_event(project, current_user, Event::CREATED) end - def push_ref(project, current_user, ref, action = 'add', prefix = Gitlab::Git::BRANCH_REF_PREFIX) - commit = project.repository.commit(ref.target) - - if action.to_s == 'add' - before = Gitlab::Git::BLANK_SHA - after = commit.id - else - before = commit.id - after = Gitlab::Git::BLANK_SHA - end - - data = { - ref: "#{prefix}#{ref.name}", - before: before, - after: after - } - - push(project, current_user, data) - end - def push(project, current_user, push_data) create_event(project, current_user, Event::PUSHED, data: push_data) end From f2024b1e06587c2b274d4982a48d80d052bba088 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 13 Mar 2015 14:55:38 +0100 Subject: [PATCH 27/75] More consistent method naming. --- app/services/git_push_service.rb | 5 +++-- app/services/git_tag_push_service.rb | 8 +++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb index bfabfd7ade..4885e1b2fc 100644 --- a/app/services/git_push_service.rb +++ b/app/services/git_push_service.rb @@ -53,7 +53,8 @@ class GitPushService process_commit_messages(ref) end - @push_data = post_receive_data(oldrev, newrev, ref) + @push_data = build_push_data(oldrev, newrev, ref) + EventCreateService.new.push(project, user, @push_data) project.execute_hooks(@push_data.dup, :push_hooks) project.execute_services(@push_data.dup, :push_hooks) @@ -101,7 +102,7 @@ class GitPushService end end - def post_receive_data(oldrev, newrev, ref) + def build_push_data(oldrev, newrev, ref) Gitlab::PushDataBuilder. build(project, user, oldrev, newrev, ref, push_commits) end diff --git a/app/services/git_tag_push_service.rb b/app/services/git_tag_push_service.rb index 666bc482f8..0d8e6e85e4 100644 --- a/app/services/git_tag_push_service.rb +++ b/app/services/git_tag_push_service.rb @@ -3,19 +3,21 @@ class GitTagPushService def execute(project, user, oldrev, newrev, ref) @project, @user = project, user - @push_data = create_push_data(oldrev, newrev, ref) + + @push_data = build_push_data(oldrev, newrev, ref) EventCreateService.new.push(project, user, @push_data) - project.repository.expire_cache project.execute_hooks(@push_data.dup, :tag_push_hooks) project.execute_services(@push_data.dup, :tag_push_hooks) + project.repository.expire_cache + true end private - def create_push_data(oldrev, newrev, ref) + def build_push_data(oldrev, newrev, ref) Gitlab::PushDataBuilder.build(project, user, oldrev, newrev, ref, []) end end From 10421674afdc8a18cdab52288e736d06e3015096 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 13 Mar 2015 14:56:08 +0100 Subject: [PATCH 28/75] Ecevute hooks and services when branches are created/deleted through web. --- app/services/create_branch_service.rb | 2 ++ app/services/delete_branch_service.rb | 3 +++ 2 files changed, 5 insertions(+) diff --git a/app/services/create_branch_service.rb b/app/services/create_branch_service.rb index f835f06e72..cf7ae4345f 100644 --- a/app/services/create_branch_service.rb +++ b/app/services/create_branch_service.rb @@ -20,6 +20,8 @@ class CreateBranchService < BaseService push_data = build_push_data(project, current_user, new_branch) EventCreateService.new.push(project, current_user, push_data) + project.execute_hooks(push_data.dup, :push_hooks) + project.execute_services(push_data.dup, :push_hooks) success(new_branch) else diff --git a/app/services/delete_branch_service.rb b/app/services/delete_branch_service.rb index f2d5ed818c..b19b112a0c 100644 --- a/app/services/delete_branch_service.rb +++ b/app/services/delete_branch_service.rb @@ -28,6 +28,9 @@ class DeleteBranchService < BaseService push_data = build_push_data(branch) EventCreateService.new.push(project, current_user, push_data) + project.execute_hooks(push_data.dup, :push_hooks) + project.execute_services(push_data.dup, :push_hooks) + success('Branch was removed') else error('Failed to remove branch') From 12b779e70b54692f4f00cb386440833bd1426a93 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 13 Mar 2015 14:56:53 +0100 Subject: [PATCH 29/75] Move tag deletion to service and execute hooks and services. --- app/controllers/projects/tags_controller.rb | 11 +++--- app/services/delete_tag_service.rb | 42 +++++++++++++++++++++ 2 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 app/services/delete_tag_service.rb diff --git a/app/controllers/projects/tags_controller.rb b/app/controllers/projects/tags_controller.rb index c4f27a6d98..83f4937bce 100644 --- a/app/controllers/projects/tags_controller.rb +++ b/app/controllers/projects/tags_controller.rb @@ -24,14 +24,13 @@ class Projects::TagsController < Projects::ApplicationController end def destroy - tag = @repository.find_tag(params[:id]) - - if tag && @repository.rm_tag(tag.name) - EventCreateService.new.push_ref(@project, current_user, tag, 'rm', Gitlab::Git::TAG_REF_PREFIX) - end + DeleteTagService.new(project, current_user).execute(params[:id]) respond_to do |format| - format.html { redirect_to namespace_project_tags_path } + format.html do + redirect_to namespace_project_tags_path(@project.namespace, + @project) + end format.js end end diff --git a/app/services/delete_tag_service.rb b/app/services/delete_tag_service.rb new file mode 100644 index 0000000000..0c83640113 --- /dev/null +++ b/app/services/delete_tag_service.rb @@ -0,0 +1,42 @@ +require_relative 'base_service' + +class DeleteTagService < BaseService + def execute(tag_name) + repository = project.repository + tag = repository.find_tag(tag_name) + + # No such tag + unless tag + return error('No such tag', 404) + end + + if repository.rm_tag(tag_name) + push_data = build_push_data(tag) + + EventCreateService.new.push(project, current_user, push_data) + project.execute_hooks(push_data.dup, :tag_push_hooks) + project.execute_services(push_data.dup, :tag_push_hooks) + + success('Tag was removed') + else + error('Failed to remove tag') + end + end + + def error(message, return_code = 400) + out = super(message) + out[:return_code] = return_code + out + end + + def success(message) + out = super() + out[:message] = message + out + end + + def build_push_data(tag) + Gitlab::PushDataBuilder + .build(project, current_user, tag.target, Gitlab::Git::BLANK_SHA, "#{Gitlab::Git::TAG_REF_PREFIX}#{tag.name}", []) + end +end From b160db1482255146e58317be4b16b1e9aebc3748 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 13 Mar 2015 14:57:27 +0100 Subject: [PATCH 30/75] Add changelog item. --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 97376c85ec..0905cc01be 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -61,6 +61,7 @@ v 7.9.0 (unreleased) - Allow smb:// links in Markdown text. - Filter merge request by title or description at Merge Requests page - Block user if he/she was blocked in Active Directory + - Execute hooks and services when branch or tag is created or deleted through web interface. v 7.8.4 - Fix issue_tracker_id substitution in custom issue trackers From 9bb5986d4afff761ddc344413fdb34babb4c9d70 Mon Sep 17 00:00:00 2001 From: Elliot Date: Thu, 12 Mar 2015 13:35:51 -0700 Subject: [PATCH 31/75] Remove unnecessary fetch of commit messages for initial push. This will reduce the memory usage significantly. --- CHANGELOG | 1 + app/services/git_push_service.rb | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b0adaeb101..896e6a6531 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.9.0 (unreleased) + - Remove unnecessary fetch of commit messages on initial push (Perforce Software) - Fix broken email images (Hannes Rosenögger) - Fix mass SQL statements on initial push (Hannes Rosenögger) - Add tag push notifications and normalize HipChat and Slack messages to be consistent (Stan Hu) diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb index bfabfd7ade..232028b1e0 100644 --- a/app/services/git_push_service.rb +++ b/app/services/git_push_service.rb @@ -29,9 +29,6 @@ class GitPushService elsif push_to_new_branch?(ref, oldrev) # Re-find the pushed commits. if is_default_branch?(ref) - # Initial push to the default branch. Take the full history of that branch as "newly pushed". - @push_commits = project.repository.commits(newrev) - # Set protection on the default branch if configured if (current_application_settings.default_branch_protection != PROTECTION_NONE) developers_can_push = current_application_settings.default_branch_protection == PROTECTION_DEV_CAN_PUSH ? true : false From b09e8c771c19953cbebbce5b546d0d92ba9d623e Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 13 Mar 2015 09:47:50 -0700 Subject: [PATCH 32/75] Bump gitlab_git to 7.1.1 Verify found object is actually a commit in Commit.find --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 064ed0958a..44f024a4b8 100644 --- a/Gemfile +++ b/Gemfile @@ -39,7 +39,7 @@ gem "browser" # Extracting information from a git repository # Provide access to Gitlab::Git library -gem "gitlab_git", '7.1.0' +gem "gitlab_git", '~> 7.1.0' # Ruby/Rack Git Smart-HTTP Server Handler gem 'gitlab-grack', '~> 2.0.0.rc2', require: 'grack' diff --git a/Gemfile.lock b/Gemfile.lock index c847424a7c..b331c29f7e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -213,7 +213,7 @@ GEM mime-types (~> 1.19) gitlab_emoji (0.1.0) gemojione (~> 2.0) - gitlab_git (7.1.0) + gitlab_git (7.1.1) activesupport (~> 4.0) charlock_holmes (~> 0.6) gitlab-linguist (~> 3.0) @@ -709,7 +709,7 @@ DEPENDENCIES gitlab-grack (~> 2.0.0.rc2) gitlab-linguist (~> 3.0.1) gitlab_emoji (~> 0.1) - gitlab_git (= 7.1.0) + gitlab_git (~> 7.1.0) gitlab_meta (= 7.0) gitlab_omniauth-ldap (= 1.2.0) gollum-lib (~> 4.0.0) From a1b3e239ee0fdf43d511ea96ed30770336bb9c3f Mon Sep 17 00:00:00 2001 From: Andrea Ruggiero Date: Fri, 13 Mar 2015 21:27:05 +0100 Subject: [PATCH 33/75] Fix typo in CHANGELOG.md --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 5ccedcbc8c..21dc1bb267 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -57,7 +57,7 @@ v 7.9.0 (unreleased) - Use Emoji One - Updated emoji help documentation to properly reference EmojiOne. - Fix missing GitHub organisation repositories on import page. - - Added blue thmeme + - Added blue theme - Remove annoying notice messages when create/update merge request - Allow smb:// links in Markdown text. - Filter merge request by title or description at Merge Requests page From 2172d7ff9e6369d963199348291046f6e06a4215 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Rosen=C3=B6gger?= <123haynes@gmail.com> Date: Fri, 13 Mar 2015 22:17:51 +0100 Subject: [PATCH 34/75] Revert "Merge branch 'follow-on-mr376' into 'master'" This reverts commit 07f9a3f928d39accf876d052b265844f74130099, reversing changes made to 4803675190833cdf7e83558a32b2f2ea3283dce0. Reverted this because the data is used in hooks as well. --- CHANGELOG | 1 - app/services/git_push_service.rb | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index faf74ff255..5ccedcbc8c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,7 +2,6 @@ Please view this file on the master branch, on stable branches it's out of date. v 7.9.0 (unreleased) - Update documentation for object_kind field in Webhook push and tag push Webhooks (Stan Hu) - - Remove unnecessary fetch of commit messages on initial push (Perforce Software) - Fix broken email images (Hannes Rosenögger) - Fix mass SQL statements on initial push (Hannes Rosenögger) - Add tag push notifications and normalize HipChat and Slack messages to be consistent (Stan Hu) diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb index e4c30dd6df..4885e1b2fc 100644 --- a/app/services/git_push_service.rb +++ b/app/services/git_push_service.rb @@ -29,6 +29,9 @@ class GitPushService elsif push_to_new_branch?(ref, oldrev) # Re-find the pushed commits. if is_default_branch?(ref) + # Initial push to the default branch. Take the full history of that branch as "newly pushed". + @push_commits = project.repository.commits(newrev) + # Set protection on the default branch if configured if (current_application_settings.default_branch_protection != PROTECTION_NONE) developers_can_push = current_application_settings.default_branch_protection == PROTECTION_DEV_CAN_PUSH ? true : false From 8fed435208fed3115c740eb630c263a97b5a631d Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 13 Mar 2015 16:40:15 +0100 Subject: [PATCH 35/75] Unblock user if they were unblocked in AD. --- CHANGELOG | 2 +- lib/gitlab/ldap/access.rb | 1 + spec/lib/gitlab/ldap/access_spec.rb | 11 ++++++++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 97376c85ec..3511a94ba0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -60,7 +60,7 @@ v 7.9.0 (unreleased) - Remove annoying notice messages when create/update merge request - Allow smb:// links in Markdown text. - Filter merge request by title or description at Merge Requests page - - Block user if he/she was blocked in Active Directory + - Block and unblock user if he/she was blocked/unblocked in Active Directory v 7.8.4 - Fix issue_tracker_id substitution in custom issue trackers diff --git a/lib/gitlab/ldap/access.rb b/lib/gitlab/ldap/access.rb index 6e30724e1f..960fb3849b 100644 --- a/lib/gitlab/ldap/access.rb +++ b/lib/gitlab/ldap/access.rb @@ -40,6 +40,7 @@ module Gitlab user.block unless user.blocked? false else + user.activate if user.blocked? true end else diff --git a/spec/lib/gitlab/ldap/access_spec.rb b/spec/lib/gitlab/ldap/access_spec.rb index 39d46efcbc..707a0521ab 100644 --- a/spec/lib/gitlab/ldap/access_spec.rb +++ b/spec/lib/gitlab/ldap/access_spec.rb @@ -28,9 +28,18 @@ describe Gitlab::LDAP::Access do end context 'and has no disabled flag in active diretory' do - before { Gitlab::LDAP::Person.stub(disabled_via_active_directory?: false) } + before do + user.block + + Gitlab::LDAP::Person.stub(disabled_via_active_directory?: false) + end it { is_expected.to be_truthy } + + it "should unblock user in GitLab" do + access.allowed? + user.should_not be_blocked + end end context 'without ActiveDirectory enabled' do From 141168ad3cf0ad2f79f0a5c64c29e7f95c2064b5 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Fri, 13 Mar 2015 17:14:34 -0700 Subject: [PATCH 36/75] Change default number of unicorn workers to three. --- config/unicorn.rb.example | 2 +- doc/install/requirements.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/unicorn.rb.example b/config/unicorn.rb.example index 29253b71f4..3aee718097 100644 --- a/config/unicorn.rb.example +++ b/config/unicorn.rb.example @@ -16,7 +16,7 @@ # Read about unicorn workers here: # http://doc.gitlab.com/ee/install/requirements.html#unicorn-workers # -worker_processes 2 +worker_processes 3 # Since Unicorn is never exposed to outside clients, it does not need to # run on the standard HTTP port (80), there is no reason to start Unicorn diff --git a/doc/install/requirements.md b/doc/install/requirements.md index 5bdb9caa2b..65ddb3e3cf 100644 --- a/doc/install/requirements.md +++ b/doc/install/requirements.md @@ -80,7 +80,7 @@ It's possible to increase the amount of unicorn workers and tis will usually hel For most instances we recommend using: CPU cores + 1 = unicorn workers. So for a machine with 2 cores, 3 unicorn workers is ideal. -For all machines that have 1GB and up we recommend a minimum of two unicorn workers. +For all machines that have 1GB and up we recommend a minimum of three unicorn workers. If you have a 512MB machine with a magnetic (non-SSD) swap drive we recommend to configure only one Unicorn worker to prevent excessive swapping. With one Unicorn worker only git over ssh access will work because the git over HTTP access requires two running workers (one worker to receive the user request and one worker for the authorization check). If you have a 512MB machine with a SSD drive you can use two Unicorn workers, this will allow HTTP access although it will be slow due to swapping. From 8c2655b5bf935830313db99fc83c34771ecbd609 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Fri, 13 Mar 2015 17:44:54 -0700 Subject: [PATCH 37/75] Remove rubyracer gem. --- Gemfile | 1 - Gemfile.lock | 6 ------ 2 files changed, 7 deletions(-) diff --git a/Gemfile b/Gemfile index 44f024a4b8..439d0c313e 100644 --- a/Gemfile +++ b/Gemfile @@ -268,7 +268,6 @@ end group :production do gem "gitlab_meta", '7.0' - gem "therubyracer" end gem "newrelic_rpm" diff --git a/Gemfile.lock b/Gemfile.lock index b331c29f7e..397735d994 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -320,7 +320,6 @@ GEM addressable (~> 2.3) letter_opener (1.1.2) launchy (~> 2.2) - libv8 (3.16.14.7) listen (2.3.1) celluloid (>= 0.15.2) rb-fsevent (>= 0.9.3) @@ -479,7 +478,6 @@ GEM redis-store (~> 1.1.0) redis-store (1.1.4) redis (>= 2.2) - ref (1.0.5) request_store (1.0.5) rest-client (1.6.7) mime-types (>= 1.16) @@ -600,9 +598,6 @@ GEM tins (~> 0.8) terminal-table (1.4.5) test_after_commit (0.2.2) - therubyracer (0.12.0) - libv8 (~> 3.16.14.0) - ref thin (1.6.1) daemons (>= 1.0.9) eventmachine (>= 1.0.0) @@ -788,7 +783,6 @@ DEPENDENCIES stamp state_machine test_after_commit - therubyracer thin tinder (~> 1.9.2) turbolinks From 3aded9d5816b8605d5ccf486ab2e38247e2b654f Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Fri, 13 Mar 2015 17:47:30 -0700 Subject: [PATCH 38/75] Update changelog with change to unicorn workers number recommendation. --- CHANGELOG | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 3a2cd3ed65..ba4f6e6de9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -36,16 +36,16 @@ v 7.9.0 (unreleased) - Send notifications and leave system comments when bulk updating issues. - Automatically link commit ranges to compare page: sha1...sha4 or sha1..sha4 (includes sha1 in comparison) - Move groups page from profile to dashboard - - Starred projects page at dashboard + - Starred projects page at dashboard - Blocking user does not remove him/her from project/groups but show blocked label - Change subject of EmailsOnPush emails to include namespace, project and branch. - Change subject of EmailsOnPush emails to include first commit message when multiple were pushed. - Remove confusing footer from EmailsOnPush mail body. - - Add list of changed files to EmailsOnPush emails. - - Add option to send EmailsOnPush emails from committer email if domain matches. + - Add list of changed files to EmailsOnPush emails. + - Add option to send EmailsOnPush emails from committer email if domain matches. - Add option to disable code diffs in EmailOnPush emails. - Wrap commit message in EmailsOnPush email. - - Send EmailsOnPush emails when deleting commits using force push. + - Send EmailsOnPush emails when deleting commits using force push. - Fix EmailsOnPush email comparison link to include first commit. - Fix highliht of selected lines in file - Reject access to group/project avatar if the user doesn't have access. @@ -66,6 +66,7 @@ v 7.9.0 (unreleased) - Use custom LDAP label in LDAP signin form. - Execute hooks and services when branch or tag is created or deleted through web interface. - Block and unblock user if he/she was blocked/unblocked in Active Directory + - Raise recommended number of unicorn workers from 2 to 3 v 7.8.4 - Fix issue_tracker_id substitution in custom issue trackers From 89d3028b20d769185b20d9af8e2e2f58d29667b8 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Fri, 13 Mar 2015 19:00:16 -0700 Subject: [PATCH 39/75] Update monthly doc to mention wip blogpost for next release. --- doc/release/monthly.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/doc/release/monthly.md b/doc/release/monthly.md index ec96be27f3..cfe01896d8 100644 --- a/doc/release/monthly.md +++ b/doc/release/monthly.md @@ -178,6 +178,10 @@ Update [installation.md](/doc/install/installation.md) to the newest version in Follow the [release doc in the Omnibus repository](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/release.md). This can happen before tagging because Omnibus uses tags in its own repo and SHA1's to refer to the GitLab codebase. +## Update GitLab.com with the stable version + +- Deploy the package (should not need downtime because of the small difference with RC1) +- Deploy the package for ci.gitlab.com ## Release CE, EE and CI @@ -199,10 +203,10 @@ Proposed tweet "Release of GitLab X.X & CI Y.Y! FEATURE, FEATURE and FEATURE < Consider creating a post on Hacker News. -## Update GitLab.com with the stable version - -- Deploy the package (should not need downtime because of the small difference with RC1) - ## Release new AMIs [Follow this guide](https://dev.gitlab.org/gitlab/AMI/blob/master/README.md) + +## 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). From 2da2720584e162c53436a046380740bd64c3ad24 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 13 Mar 2015 19:20:25 -0700 Subject: [PATCH 40/75] Improve css for file actions --- app/assets/stylesheets/base/gl_bootstrap.scss | 5 +--- app/assets/stylesheets/generic/files.scss | 24 +++++++------------ app/views/help/ui.html.haml | 19 +++++++++++++++ app/views/projects/blame/show.html.haml | 7 +++--- app/views/projects/blob/_blob.html.haml | 10 ++++---- app/views/projects/snippets/show.html.haml | 4 ++-- .../search/results/_snippet_blob.html.haml | 6 ----- app/views/snippets/show.html.haml | 4 ++-- 8 files changed, 43 insertions(+), 36 deletions(-) diff --git a/app/assets/stylesheets/base/gl_bootstrap.scss b/app/assets/stylesheets/base/gl_bootstrap.scss index 16581e9ebf..7012d31e31 100644 --- a/app/assets/stylesheets/base/gl_bootstrap.scss +++ b/app/assets/stylesheets/base/gl_bootstrap.scss @@ -152,12 +152,9 @@ */ .panel { .panel-heading { - font-size: 14px; - line-height: 18px; - .panel-head-actions { position: relative; - top: -6px; + top: -5px; float: right; } } diff --git a/app/assets/stylesheets/generic/files.scss b/app/assets/stylesheets/generic/files.scss index 1ed41272ac..dca6b957d2 100644 --- a/app/assets/stylesheets/generic/files.scss +++ b/app/assets/stylesheets/generic/files.scss @@ -18,27 +18,21 @@ text-align: left; padding: 10px 15px; - .options { + .file-actions { float: right; - margin-top: -3px; + position: relative; + top: -5px; + + .btn { + padding: 0px 10px; + font-size: 13px; + line-height: 28px; + } } .left-options { margin-top: -3px; } - - .file_name { - font-weight: bold; - padding-left: 3px; - font-size: 14px; - - small { - color: #888; - font-size: 13px; - font-weight: normal; - padding-left: 10px; - } - } } .file-content { background: #fff; diff --git a/app/views/help/ui.html.haml b/app/views/help/ui.html.haml index 58de5b7c86..ed03f885dc 100644 --- a/app/views/help/ui.html.haml +++ b/app/views/help/ui.html.haml @@ -21,6 +21,8 @@ = link_to 'Alerts', '#alerts' %li = link_to 'Forms', '#forms' + %li + = link_to 'Files', '#file' %li = link_to 'Markdown', '#markdown' @@ -193,6 +195,23 @@ Remember me %button.btn.btn-default{:type => "submit"} Sign in + %h2#file File + %h3 + %code .file-holder + + - blob = Snippet.new(content: "Wow\nSuch\nFile") + .example + .file-holder + .file-title + Awesome file + .file-actions + .btn-group + %a.btn Edit + %a.btn Remove + .file-contenta.code + = render 'shared/file_highlight', blob: blob + + %h2#markdown Markdown %h3 %code .md or .wiki and others diff --git a/app/views/projects/blame/show.html.haml b/app/views/projects/blame/show.html.haml index 4cc1fedb1c..e6a859fea8 100644 --- a/app/views/projects/blame/show.html.haml +++ b/app/views/projects/blame/show.html.haml @@ -4,10 +4,11 @@ .file-holder .file-title %i.fa.fa-file - %span.file_name + %strong = @path - %small= number_to_human_size @blob.size - %span.options= render "projects/blob/actions" + %small= number_to_human_size @blob.size + .file-actions + = render "projects/blob/actions" .file-content.blame.highlight %table - @blame.each do |commit, lines, since| diff --git a/app/views/projects/blob/_blob.html.haml b/app/views/projects/blob/_blob.html.haml index 9ff61f3887..ba60bd9286 100644 --- a/app/views/projects/blob/_blob.html.haml +++ b/app/views/projects/blob/_blob.html.haml @@ -21,12 +21,14 @@ %div#tree-content-holder.tree-content-holder %article.file-holder - .file-title.clearfix + .file-title %i.fa.fa-file - %span.file_name + %strong = blob.name - %small= number_to_human_size blob.size - %span.options.hidden-xs= render "actions" + %small + = number_to_human_size(blob.size) + .file-actions.hidden-xs + = render "actions" - if blob.text? = render "text", blob: blob - elsif blob.image? diff --git a/app/views/projects/snippets/show.html.haml b/app/views/projects/snippets/show.html.haml index 345848fa6d..408e3c0224 100644 --- a/app/views/projects/snippets/show.html.haml +++ b/app/views/projects/snippets/show.html.haml @@ -23,9 +23,9 @@ .file-holder .file-title %i.fa.fa-file - %span.file_name + %strong = @snippet.file_name - .options + .file-actions .btn-group - if can?(current_user, :modify_project_snippet, @snippet) = link_to "edit", edit_namespace_project_snippet_path(@project.namespace, @project, @snippet), class: "btn btn-small", title: 'Edit Snippet' diff --git a/app/views/search/results/_snippet_blob.html.haml b/app/views/search/results/_snippet_blob.html.haml index 6fc2cdf636..8af393777f 100644 --- a/app/views/search/results/_snippet_blob.html.haml +++ b/app/views/search/results/_snippet_blob.html.haml @@ -13,12 +13,6 @@ .file-title %i.fa.fa-file %strong= snippet_blob[:snippet_object].file_name - %span.options - .btn-group.tree-btn-group.pull-right - - if snippet_blob[:snippet_object].author == current_user - = link_to "Edit", edit_snippet_path(snippet_blob[:snippet_object]), class: "btn btn-tiny", title: 'Edit Snippet' - = link_to "Delete", snippet_path(snippet_blob[:snippet_object]), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-tiny", title: 'Delete Snippet' - = link_to "Raw", raw_snippet_path(snippet_blob[:snippet_object]), class: "btn btn-tiny", target: "_blank" - if gitlab_markdown?(snippet_blob[:snippet_object].file_name) .file-content.wiki - snippet_blob[:snippet_chunks].each do |snippet| diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml index f5bc543de1..d9436caaad 100644 --- a/app/views/snippets/show.html.haml +++ b/app/views/snippets/show.html.haml @@ -31,9 +31,9 @@ .file-holder .file-title %i.fa.fa-file - %span.file_name + %strong = @snippet.file_name - .options + .file-actions .btn-group - if can?(current_user, :modify_personal_snippet, @snippet) = link_to "edit", edit_snippet_path(@snippet), class: "btn btn-small", title: 'Edit Snippet' From dffa2fa9e92e37a664afa2807fd5b01fbbd87ef2 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 13 Mar 2015 23:40:46 -0700 Subject: [PATCH 41/75] Use sass variabled for backgroung and border colors --- app/assets/stylesheets/base/gl_variables.scss | 4 ++-- app/assets/stylesheets/base/variables.scss | 3 ++- app/assets/stylesheets/generic/files.scss | 14 ++++++----- app/assets/stylesheets/generic/highlight.scss | 2 +- app/assets/stylesheets/generic/selects.scss | 2 +- app/assets/stylesheets/generic/tables.scss | 2 +- app/assets/stylesheets/pages/diff.scss | 23 +++++++++++-------- app/assets/stylesheets/pages/graph.scss | 4 ++-- .../stylesheets/pages/merge_requests.scss | 4 ++-- 9 files changed, 33 insertions(+), 25 deletions(-) diff --git a/app/assets/stylesheets/base/gl_variables.scss b/app/assets/stylesheets/base/gl_variables.scss index ea230646a8..ce82ad8031 100644 --- a/app/assets/stylesheets/base/gl_variables.scss +++ b/app/assets/stylesheets/base/gl_variables.scss @@ -716,8 +716,8 @@ $panel-border-radius: 0; // $panel-footer-bg: #f5f5f5 $panel-default-text: $text-color; -// $panel-default-border: #ddd -// $panel-default-heading-bg: #f5f5f5 +$panel-default-border: $border-color; +$panel-default-heading-bg: $background-color; // $panel-primary-text: #fff // $panel-primary-border: $brand-primary diff --git a/app/assets/stylesheets/base/variables.scss b/app/assets/stylesheets/base/variables.scss index 54af78ee08..4e2c64aa13 100644 --- a/app/assets/stylesheets/base/variables.scss +++ b/app/assets/stylesheets/base/variables.scss @@ -1,6 +1,5 @@ $style_color: #474D57; $hover: #FFF3EB; -$box_bg: #F9F9F9; $gl-link-color: #446e9b; $nprogress-color: #c0392b; $gl-font-size: 14px; @@ -9,6 +8,8 @@ $sidebar_width: 230px; $avatar_radius: 50%; $code_font_size: 13px; $code_line_height: 1.5; +$border-color: #dce4ec; +$background-color: #ECF0F1; /* * State colors: diff --git a/app/assets/stylesheets/generic/files.scss b/app/assets/stylesheets/generic/files.scss index dca6b957d2..91220a856a 100644 --- a/app/assets/stylesheets/generic/files.scss +++ b/app/assets/stylesheets/generic/files.scss @@ -3,7 +3,7 @@ * */ .file-holder { - border: 1px solid #CCC; + border: 1px solid $border-color; margin-bottom: 1em; table { @@ -11,8 +11,9 @@ } .file-title { - background: #EEE; - border-bottom: 1px solid #CCC; + position: relative; + background: $background-color; + border-bottom: 1px solid $border-color; text-shadow: 0 1px 1px #fff; margin: 0; text-align: left; @@ -20,8 +21,9 @@ .file-actions { float: right; - position: relative; - top: -5px; + position: absolute; + top: 5px; + right: 15px; .btn { padding: 0px 10px; @@ -113,7 +115,7 @@ ol { margin-left: 40px; padding: 10px 0; - border-left: 1px solid #CCC; + border-left: 1px solid $border-color; margin-bottom: 0; background: white; li { diff --git a/app/assets/stylesheets/generic/highlight.scss b/app/assets/stylesheets/generic/highlight.scss index 0f8225d682..2e13ee842e 100644 --- a/app/assets/stylesheets/generic/highlight.scss +++ b/app/assets/stylesheets/generic/highlight.scss @@ -57,7 +57,7 @@ .note-text .code { border: none; box-shadow: none; - background: $box_bg; + background: $background-color; padding: 1em; overflow-x: auto; diff --git a/app/assets/stylesheets/generic/selects.scss b/app/assets/stylesheets/generic/selects.scss index af0ecb192d..c13a685a52 100644 --- a/app/assets/stylesheets/generic/selects.scss +++ b/app/assets/stylesheets/generic/selects.scss @@ -2,7 +2,7 @@ .select2-container, .select2-container.select2-drop-above { .select2-choice { background: #FFF; - border-color: #BBB; + border-color: #CCC; padding: 6px 14px; line-height: 1.42857143; height: auto; diff --git a/app/assets/stylesheets/generic/tables.scss b/app/assets/stylesheets/generic/tables.scss index 71a7d4abae..a66e45577d 100644 --- a/app/assets/stylesheets/generic/tables.scss +++ b/app/assets/stylesheets/generic/tables.scss @@ -9,7 +9,7 @@ table { th { font-weight: normal; font-size: 15px; - border-bottom: 1px solid #CCC !important; + border-bottom: 1px solid $border-color !important; } td { border-color: #F1F1F1 !important; diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss index 54311a6885..5a9f93dc03 100644 --- a/app/assets/stylesheets/pages/diff.scss +++ b/app/assets/stylesheets/pages/diff.scss @@ -1,25 +1,30 @@ .diff-file { - border: 1px solid #CCC; + border: 1px solid $border-color; margin-bottom: 1em; .diff-header { - @extend .clearfix; - background: #EEE; - border-bottom: 1px solid #CCC; - padding: 5px 5px 5px 10px; + position: relative; + background: $background-color; + border-bottom: 1px solid $border-color; + padding: 10px 15px; color: #555; z-index: 10; > span { + @include str-truncated(65%); font-family: $monospace_font; - line-height: 2; } .diff-btn-group { float: right; + position: absolute; + top: 5px; + right: 15px; .btn { - background-color: #FFF; + padding: 0px 10px; + font-size: 13px; + line-height: 28px; } } @@ -87,7 +92,7 @@ background: #F5F5F5; color: rgba(0,0,0,0.3); padding: 0px 5px; - border-right: 1px solid #ccc; + border-right: 1px solid $border-color; text-align: right; min-width: 35px; max-width: 50px; @@ -136,7 +141,7 @@ background: #ffecec; } &.matched { - color: #ccc; + color: $border-color; background: #fafafa; } &.parallel { diff --git a/app/assets/stylesheets/pages/graph.scss b/app/assets/stylesheets/pages/graph.scss index 3d878d1e52..c3b10d144e 100644 --- a/app/assets/stylesheets/pages/graph.scss +++ b/app/assets/stylesheets/pages/graph.scss @@ -1,11 +1,11 @@ .project-network { - border: 1px solid #CCC; + border: 1px solid $border-color; .controls { color: #888; font-size: 14px; padding: 5px; - border-bottom: 1px solid #bbb; + border-bottom: 1px solid $border-color; background: #EEE; } diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index 9bd34b7376..6babb824f3 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -123,10 +123,10 @@ } .mr-state-widget { - background: $box_bg; + background: $background-color; margin-bottom: 20px; color: #666; - border: 1px solid #EEE; + border: 1px solid $border-color; @include box-shadow(0 1px 1px rgba(0, 0, 0, 0.09)); .ci_widget { From abf90611cbfd54590444a2f0221d2cbd7d8a6747 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Sat, 14 Mar 2015 00:13:15 -0700 Subject: [PATCH 42/75] Improve import buttons on new project page --- app/assets/stylesheets/pages/projects.scss | 5 +++ app/views/projects/new.html.haml | 43 +++++++++------------- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index bfd05973d7..e359aa4502 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -301,3 +301,8 @@ table.table.protected-branches-list tr.no-border { border: 0; } } + +.project-import .btn { + float: left; + margin-right: 10px; +} diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index 00b912742b..264012506a 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -40,52 +40,45 @@ The import will time out after 4 minutes. For big repositories, use a clone/push combination. For SVN repositories, check #{link_to "this migrating from SVN doc.", "http://doc.gitlab.com/ce/workflow/migrating_from_svn.html"} + .project-import.form-group - .col-sm-2 + %label.control-label Import projects from .col-sm-10 - if github_import_enabled? - = link_to status_import_github_path do + = link_to status_import_github_path, class: 'btn' do %i.fa.fa-github - Import projects from GitHub + GitHub - else - = link_to '#', class: 'how_to_import_link light' do + = link_to '#', class: 'how_to_import_link light btn' do %i.fa.fa-github - Import projects from GitHub + GitHub = render 'github_import_modal' - .project-import.form-group - .col-sm-2 - .col-sm-10 + - if bitbucket_import_enabled? - = link_to status_import_bitbucket_path do + = link_to status_import_bitbucket_path, class: 'btn' do %i.fa.fa-bitbucket - Import projects from Bitbucket + Bitbucket - else - = link_to '#', class: 'how_to_import_link light' do + = link_to '#', class: 'how_to_import_link light btn' do %i.fa.fa-bitbucket - Import projects from Bitbucket + Bitbucket = render 'bitbucket_import_modal' - - unless request.host == 'gitlab.com' - .project-import.form-group - .col-sm-2 - .col-sm-10 + - unless request.host == 'gitlab.com' - if gitlab_import_enabled? - = link_to status_import_gitlab_path do + = link_to status_import_gitlab_path, class: 'btn' do %i.fa.fa-heart - Import projects from GitLab.com + GitLab.com - else - = link_to '#', class: 'how_to_import_link light' do + = link_to '#', class: 'how_to_import_link light btn' do %i.fa.fa-heart - Import projects from GitLab.com + GitLab.com = render 'gitlab_import_modal' - .project-import.form-group - .col-sm-2 - .col-sm-10 - = link_to new_import_gitorious_path do + = link_to new_import_gitorious_path, class: 'btn' do %i.icon-gitorious.icon-gitorious-small - Import projects from Gitorious.org + Gitorious.org %hr.prepend-botton-10 From 30ca451fd4f926998868b9db524e8fa98cd9457d Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Sat, 14 Mar 2015 00:29:32 -0700 Subject: [PATCH 43/75] Refactor buttons --- app/assets/stylesheets/generic/buttons.scss | 15 --------------- app/assets/stylesheets/pages/commit.scss | 3 ++- app/helpers/diff_helper.rb | 4 ++-- .../admin/applications/_delete_form.html.haml | 2 +- .../admin/broadcast_messages/index.html.haml | 2 +- app/views/admin/groups/index.html.haml | 4 ++-- app/views/admin/groups/show.html.haml | 2 +- app/views/admin/hooks/index.html.haml | 4 ++-- app/views/admin/projects/index.html.haml | 4 ++-- app/views/admin/projects/show.html.haml | 6 +++--- app/views/admin/users/index.html.haml | 8 ++++---- app/views/admin/users/show.html.haml | 6 +++--- app/views/dashboard/groups/index.html.haml | 4 ++-- .../applications/_delete_form.html.haml | 2 +- .../_delete_form.html.haml | 2 +- app/views/events/_event_last_push.html.haml | 2 +- app/views/groups/edit.html.haml | 2 +- .../groups/group_members/_group_member.html.haml | 8 ++++---- app/views/groups/milestones/index.html.haml | 4 ++-- app/views/groups/milestones/show.html.haml | 4 ++-- app/views/groups/projects.html.haml | 6 +++--- app/views/profiles/applications.html.haml | 2 +- app/views/profiles/emails/index.html.haml | 2 +- app/views/profiles/keys/_key.html.haml | 2 +- app/views/profiles/show.html.haml | 4 ++-- app/views/projects/blob/_actions.html.haml | 12 ++++++------ app/views/projects/branches/_branch.html.haml | 6 +++--- .../projects/deploy_keys/_deploy_key.html.haml | 6 +++--- app/views/projects/diffs/_file.html.haml | 2 +- app/views/projects/diffs/_stats.html.haml | 2 +- app/views/projects/diffs/_warning.html.haml | 10 +++++----- app/views/projects/edit.html.haml | 4 ++-- app/views/projects/hooks/index.html.haml | 4 ++-- app/views/projects/issues/_issue.html.haml | 6 +++--- .../show/_remove_source_branch.html.haml | 2 +- .../projects/milestones/_milestone.html.haml | 4 ++-- app/views/projects/new.html.haml | 2 +- .../protected_branches/_branches_list.html.haml | 2 +- app/views/projects/snippets/show.html.haml | 6 +++--- app/views/projects/tags/_tag.html.haml | 4 ++-- .../team_members/_group_members.html.haml | 2 +- .../projects/team_members/_team_member.html.haml | 2 +- app/views/projects/tree/show.html.haml | 2 +- app/views/projects/wikis/edit.html.haml | 2 +- app/views/search/_filter.html.haml | 4 ++-- .../shared/_choose_group_avatar_button.html.haml | 2 +- app/views/snippets/show.html.haml | 6 +++--- app/views/snippets/user_index.html.haml | 2 +- 48 files changed, 92 insertions(+), 106 deletions(-) diff --git a/app/assets/stylesheets/generic/buttons.scss b/app/assets/stylesheets/generic/buttons.scss index 0224484d82..cd6bf64c0a 100644 --- a/app/assets/stylesheets/generic/buttons.scss +++ b/app/assets/stylesheets/generic/buttons.scss @@ -21,18 +21,6 @@ float: right; } - &.btn-small { - padding: 2px 10px; - font-size: 12px; - } - - &.btn-tiny { - font-size: 11px; - padding: 2px 6px; - line-height: 16px; - margin: 2px; - } - &.btn-close { color: $gl-danger; border-color: $gl-danger; @@ -84,6 +72,3 @@ } } } - -.btn-group-small > .btn { @extend .btn.btn-small; } -.btn-group-tiny > .btn { @extend .btn.btn-tiny; } diff --git a/app/assets/stylesheets/pages/commit.scss b/app/assets/stylesheets/pages/commit.scss index f46d6542c0..e7125c0399 100644 --- a/app/assets/stylesheets/pages/commit.scss +++ b/app/assets/stylesheets/pages/commit.scss @@ -30,7 +30,8 @@ color: #666; font-size: 14px; font-weight: normal; - padding: 10px 0; + padding: 3px 0; + margin-bottom: 10px; } .commit-info-row { diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb index 8c921cba54..f81504991d 100644 --- a/app/helpers/diff_helper.rb +++ b/app/helpers/diff_helper.rb @@ -122,7 +122,7 @@ module DiffHelper params_copy = params.dup params_copy[:view] = 'inline' - link_to url_for(params_copy), id: "commit-diff-viewtype", class: (params[:view] != 'parallel' ? 'btn active' : 'btn') do + link_to url_for(params_copy), id: "commit-diff-viewtype", class: (params[:view] != 'parallel' ? 'btn btn-sm active' : 'btn btn-sm') do 'Inline' end end @@ -131,7 +131,7 @@ module DiffHelper params_copy = params.dup params_copy[:view] = 'parallel' - link_to url_for(params_copy), id: "commit-diff-viewtype", class: (params[:view] == 'parallel' ? 'btn active' : 'btn') do + link_to url_for(params_copy), id: "commit-diff-viewtype", class: (params[:view] == 'parallel' ? 'btn active btn-sm' : 'btn btn-sm') do 'Side-by-side' end end diff --git a/app/views/admin/applications/_delete_form.html.haml b/app/views/admin/applications/_delete_form.html.haml index 371ac55209..3147cbd659 100644 --- a/app/views/admin/applications/_delete_form.html.haml +++ b/app/views/admin/applications/_delete_form.html.haml @@ -1,4 +1,4 @@ -- submit_btn_css ||= 'btn btn-link btn-remove btn-small' +- submit_btn_css ||= 'btn btn-link btn-remove btn-sm' = form_tag admin_application_path(application) do %input{:name => "_method", :type => "hidden", :value => "delete"}/ = submit_tag 'Destroy', onclick: "return confirm('Are you sure?')", class: submit_btn_css \ No newline at end of file diff --git a/app/views/admin/broadcast_messages/index.html.haml b/app/views/admin/broadcast_messages/index.html.haml index 7b483ee655..c0afaf16d8 100644 --- a/app/views/admin/broadcast_messages/index.html.haml +++ b/app/views/admin/broadcast_messages/index.html.haml @@ -52,7 +52,7 @@ %strong #{broadcast_message.ends_at.to_s(:short)}   - = link_to [:admin, broadcast_message], method: :delete, remote: true, class: 'remove-row btn btn-tiny' do + = link_to [:admin, broadcast_message], method: :delete, remote: true, class: 'remove-row btn btn-xs' do %i.fa.fa-times.cred .message= broadcast_message.message diff --git a/app/views/admin/groups/index.html.haml b/app/views/admin/groups/index.html.haml index 8ae9a1edea..4c53ff5570 100644 --- a/app/views/admin/groups/index.html.haml +++ b/app/views/admin/groups/index.html.haml @@ -40,8 +40,8 @@ %li .clearfix .pull-right.prepend-top-10 - = link_to 'Edit', edit_admin_group_path(group), id: "edit_#{dom_id(group)}", class: "btn btn-small" - = link_to 'Destroy', [:admin, group], data: {confirm: "REMOVE #{group.name}? Are you sure?"}, method: :delete, class: "btn btn-small btn-remove" + = link_to 'Edit', edit_admin_group_path(group), id: "edit_#{dom_id(group)}", class: "btn btn-sm" + = link_to 'Destroy', [:admin, group], data: {confirm: "REMOVE #{group.name}? Are you sure?"}, method: :delete, class: "btn btn-sm btn-remove" %h4 = link_to [:admin, group] do diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml index 3040faa722..a28eae3892 100644 --- a/app/views/admin/groups/show.html.haml +++ b/app/views/admin/groups/show.html.haml @@ -80,7 +80,7 @@ = link_to user.name, admin_user_path(user) %span.pull-right.light = member.human_access - = link_to group_group_member_path(@group, member), data: { confirm: remove_user_from_group_message(@group, user) }, method: :delete, remote: true, class: "btn-tiny btn btn-remove", title: 'Remove user from group' do + = link_to group_group_member_path(@group, member), data: { confirm: remove_user_from_group_message(@group, user) }, 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' diff --git a/app/views/admin/hooks/index.html.haml b/app/views/admin/hooks/index.html.haml index 0c5db0805f..7a9dc113f2 100644 --- a/app/views/admin/hooks/index.html.haml +++ b/app/views/admin/hooks/index.html.haml @@ -33,5 +33,5 @@ %strong= hook.url .pull-right - = link_to 'Test Hook', admin_hook_test_path(hook), class: "btn btn-small" - = link_to 'Remove', admin_hook_path(hook), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-remove btn-small" + = link_to 'Test Hook', admin_hook_test_path(hook), class: "btn btn-sm" + = link_to 'Remove', admin_hook_path(hook), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-remove btn-sm" diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml index 3a1e61d5d8..3bbe10bc27 100644 --- a/app/views/admin/projects/index.html.haml +++ b/app/views/admin/projects/index.html.haml @@ -74,8 +74,8 @@ .pull-right %span.label.label-gray = repository_size(project) - = link_to 'Edit', edit_namespace_project_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn btn-small" - = link_to 'Destroy', [project.namespace.becomes(Namespace), project], data: { confirm: remove_project_message(project) }, method: :delete, class: "btn btn-small btn-remove" + = link_to 'Edit', edit_namespace_project_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn btn-sm" + = link_to 'Destroy', [project.namespace.becomes(Namespace), project], data: { confirm: remove_project_message(project) }, method: :delete, class: "btn btn-sm btn-remove" - if @projects.blank? .nothing-here-block 0 projects matches = paginate @projects, theme: "gitlab" diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml index 1421c2ea90..ebb3b3a636 100644 --- a/app/views/admin/projects/show.html.haml +++ b/app/views/admin/projects/show.html.haml @@ -97,7 +97,7 @@ %strong #{@group.name} group members (#{@group.group_members.count}) .pull-right - = link_to admin_group_path(@group), class: 'btn btn-small' do + = link_to admin_group_path(@group), class: 'btn btn-sm' do %i.fa.fa-pencil-square-o %ul.well-list - @group_members.each do |member| @@ -111,7 +111,7 @@ %small (#{@project.users.count}) .pull-right - = link_to namespace_project_team_index_path(@project.namespace, @project), class: "btn btn-tiny" do + = link_to namespace_project_team_index_path(@project.namespace, @project), class: "btn btn-xs" do %i.fa.fa-pencil-square-o Manage Access %ul.well-list.team_members @@ -126,7 +126,7 @@ %span.light Owner - else %span.light= project_member.human_access - = link_to namespace_project_team_member_path(@project.namespace, @project, user), data: { confirm: remove_from_project_team_message(@project, user)}, method: :delete, remote: true, class: "btn btn-small btn-remove" do + = link_to namespace_project_team_member_path(@project.namespace, @project, user), data: { confirm: remove_from_project_team_message(@project, user)}, method: :delete, remote: true, class: "btn btn-sm btn-remove" do %i.fa.fa-times .panel-footer = paginate @project_members, param_name: 'project_members_page', theme: 'gitlab' diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml index 35e9fd5154..25c1730ef7 100644 --- a/app/views/admin/users/index.html.haml +++ b/app/views/admin/users/index.html.haml @@ -78,11 +78,11 @@ %i.fa.fa-envelope = mail_to user.email, user.email, class: 'light'   - = link_to 'Edit', edit_admin_user_path(user), id: "edit_#{dom_id(user)}", class: "btn btn-small" + = link_to 'Edit', edit_admin_user_path(user), id: "edit_#{dom_id(user)}", class: "btn btn-sm" - unless user == current_user - if user.blocked? - = link_to 'Unblock', unblock_admin_user_path(user), method: :put, class: "btn btn-small success" + = link_to 'Unblock', unblock_admin_user_path(user), method: :put, class: "btn btn-sm success" - else - = link_to 'Block', block_admin_user_path(user), data: {confirm: 'USER WILL BE BLOCKED! Are you sure?'}, method: :put, class: "btn btn-small btn-remove" - = link_to 'Destroy', [:admin, user], data: { confirm: "USER #{user.name} WILL BE REMOVED! All tickets linked to this user will also be removed! Maybe block the user instead? Are you sure?" }, method: :delete, class: "btn btn-small btn-remove" + = link_to 'Block', block_admin_user_path(user), data: {confirm: 'USER WILL BE BLOCKED! Are you sure?'}, method: :put, class: "btn btn-sm btn-remove" + = link_to 'Destroy', [:admin, user], data: { confirm: "USER #{user.name} WILL BE REMOVED! All tickets linked to this user will also be removed! Maybe block the user instead? Are you sure?" }, method: :delete, class: "btn btn-sm btn-remove" = paginate @users, theme: "gitlab" diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml index 90c9f8c2f9..5cf423ead8 100644 --- a/app/views/admin/users/show.html.haml +++ b/app/views/admin/users/show.html.haml @@ -46,7 +46,7 @@ %li %span.light Secondary email: %strong= email.email - = link_to remove_email_admin_user_path(@user, email), data: { confirm: "Are you sure you want to remove #{email.email}?" }, method: :delete, class: "btn-tiny btn btn-remove pull-right", title: 'Remove secondary email', id: "remove_email_#{email.id}" do + = link_to remove_email_admin_user_path(@user, email), data: { confirm: "Are you sure you want to remove #{email.email}?" }, method: :delete, class: "btn-xs btn btn-remove pull-right", title: 'Remove secondary email', id: "remove_email_#{email.id}" do %i.fa.fa-times %li @@ -182,7 +182,7 @@ .pull-right %span.light= user_group.human_access - unless user_group.owner? - = link_to group_group_member_path(group, user_group), data: { confirm: remove_user_from_group_message(group, @user) }, method: :delete, remote: true, class: "btn-tiny btn btn-remove", title: 'Remove user from group' do + = link_to group_group_member_path(group, user_group), data: { confirm: remove_user_from_group_message(group, @user) }, method: :delete, remote: true, class: "btn-xs btn btn-remove", title: 'Remove user from group' do %i.fa.fa-times.fa-inverse - else .nothing-here-block This user has no groups. @@ -221,7 +221,7 @@ %span.light= tm.human_access - if tm.respond_to? :project - = link_to namespace_project_team_member_path(project.namespace, project, @user), data: { confirm: remove_from_project_team_message(project, @user) }, remote: true, method: :delete, class: "btn-tiny btn btn-remove", title: 'Remove user from project' do + = link_to namespace_project_team_member_path(project.namespace, project, @user), data: { confirm: remove_from_project_team_message(project, @user) }, remote: true, method: :delete, class: "btn-xs btn btn-remove", title: 'Remove user from project' do %i.fa.fa-times #ssh-keys.tab-pane = render 'profiles/keys/key_table', admin: true diff --git a/app/views/dashboard/groups/index.html.haml b/app/views/dashboard/groups/index.html.haml index f7df535251..c232644b02 100644 --- a/app/views/dashboard/groups/index.html.haml +++ b/app/views/dashboard/groups/index.html.haml @@ -18,12 +18,12 @@ %li .pull-right - if can?(current_user, :manage_group, group) - = link_to edit_group_path(group), class: "btn-small btn btn-grouped" do + = link_to edit_group_path(group), class: "btn-sm btn btn-grouped" do %i.fa.fa-cogs Settings - if can?(current_user, :destroy, user_group) - = link_to leave_dashboard_group_path(group), data: { confirm: leave_group_message(group.name) }, method: :delete, class: "btn-small btn btn-grouped", title: 'Remove user from group' do + = link_to leave_dashboard_group_path(group), data: { confirm: leave_group_message(group.name) }, method: :delete, class: "btn-sm btn btn-grouped", title: 'Remove user from group' do %i.fa.fa-sign-out Leave diff --git a/app/views/doorkeeper/applications/_delete_form.html.haml b/app/views/doorkeeper/applications/_delete_form.html.haml index bf8098f38d..6a5c917049 100644 --- a/app/views/doorkeeper/applications/_delete_form.html.haml +++ b/app/views/doorkeeper/applications/_delete_form.html.haml @@ -1,4 +1,4 @@ -- submit_btn_css ||= 'btn btn-link btn-remove btn-small' +- submit_btn_css ||= 'btn btn-link btn-remove btn-sm' = form_tag oauth_application_path(application) do %input{:name => "_method", :type => "hidden", :value => "delete"}/ = submit_tag 'Destroy', onclick: "return confirm('Are you sure?')", class: submit_btn_css \ No newline at end of file diff --git a/app/views/doorkeeper/authorized_applications/_delete_form.html.haml b/app/views/doorkeeper/authorized_applications/_delete_form.html.haml index 5cbb4a70c1..4bba72167e 100644 --- a/app/views/doorkeeper/authorized_applications/_delete_form.html.haml +++ b/app/views/doorkeeper/authorized_applications/_delete_form.html.haml @@ -1,4 +1,4 @@ - submit_btn_css ||= 'btn btn-link btn-remove' = form_tag oauth_authorized_application_path(application) do %input{:name => "_method", :type => "hidden", :value => "delete"}/ - = submit_tag 'Revoke', onclick: "return confirm('Are you sure?')", class: 'btn btn-link btn-remove btn-small' \ No newline at end of file + = submit_tag 'Revoke', onclick: "return confirm('Are you sure?')", class: 'btn btn-link btn-remove btn-sm' \ No newline at end of file diff --git a/app/views/events/_event_last_push.html.haml b/app/views/events/_event_last_push.html.haml index cb40aa9970..d2f0005142 100644 --- a/app/views/events/_event_last_push.html.haml +++ b/app/views/events/_event_last_push.html.haml @@ -9,6 +9,6 @@ #{time_ago_with_tooltip(event.created_at)} .pull-right - = link_to new_mr_path_from_push_event(event), title: "New Merge Request", class: "btn btn-create btn-small" do + = link_to new_mr_path_from_push_event(event), title: "New Merge Request", class: "btn btn-create btn-sm" do Create Merge Request %hr diff --git a/app/views/groups/edit.html.haml b/app/views/groups/edit.html.haml index 838290e4ac..49e7180bf9 100644 --- a/app/views/groups/edit.html.haml +++ b/app/views/groups/edit.html.haml @@ -21,7 +21,7 @@ = render 'shared/choose_group_avatar_button', f: f - if @group.avatar? %hr - = link_to 'Remove avatar', group_avatar_path(@group.to_param), data: { confirm: "Group avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-small remove-avatar" + = link_to 'Remove avatar', group_avatar_path(@group.to_param), data: { confirm: "Group avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-sm remove-avatar" .form-actions = f.submit 'Save group', class: "btn btn-save" diff --git a/app/views/groups/group_members/_group_member.html.haml b/app/views/groups/group_members/_group_member.html.haml index 6267006f63..5bef796c5a 100644 --- a/app/views/groups/group_members/_group_member.html.haml +++ b/app/views/groups/group_members/_group_member.html.haml @@ -17,19 +17,19 @@ %strong= member.human_access - if show_controls - if can?(current_user, :modify, member) - = button_tag class: "btn-tiny btn js-toggle-button", + = button_tag class: "btn-xs btn js-toggle-button", title: 'Edit access level', type: 'button' do %i.fa.fa-pencil-square-o - if can?(current_user, :destroy, member) - if current_user == member.user - = link_to leave_dashboard_group_path(@group), data: { confirm: leave_group_message(@group.name)}, method: :delete, class: "btn-tiny btn btn-remove", title: 'Remove user from group' do + = link_to leave_dashboard_group_path(@group), data: { confirm: leave_group_message(@group.name)}, method: :delete, class: "btn-xs btn btn-remove", title: 'Remove user from group' do %i.fa.fa-minus.fa-inverse - else - = link_to group_group_member_path(@group, member), data: { confirm: remove_user_from_group_message(@group, user) }, method: :delete, remote: true, class: "btn-tiny btn btn-remove", title: 'Remove user from group' do + = link_to group_group_member_path(@group, member), data: { confirm: remove_user_from_group_message(@group, user) }, method: :delete, remote: true, class: "btn-xs btn btn-remove", title: 'Remove user from group' do %i.fa.fa-minus.fa-inverse .edit-member.hide.js-toggle-content = form_for [@group, member], remote: true do |f| .alert.prepend-top-20 = f.select :access_level, options_for_select(GroupMember.access_level_roles, member.access_level) - = f.submit 'Save', class: 'btn btn-save btn-small' + = f.submit 'Save', class: 'btn btn-save btn-sm' diff --git a/app/views/groups/milestones/index.html.haml b/app/views/groups/milestones/index.html.haml index 9febaab04a..57dc235f5b 100644 --- a/app/views/groups/milestones/index.html.haml +++ b/app/views/groups/milestones/index.html.haml @@ -22,9 +22,9 @@ .pull-right - if can?(current_user, :manage_group, @group) - if milestone.closed? - = link_to 'Reopen Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :activate }), method: :put, class: "btn btn-small btn-grouped btn-reopen" + = link_to 'Reopen Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :activate }), method: :put, class: "btn btn-sm btn-grouped btn-reopen" - else - = link_to 'Close Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :close }), method: :put, class: "btn btn-small btn-close" + = link_to 'Close Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :close }), method: :put, class: "btn btn-sm btn-close" %h4 = link_to_gfm truncate(milestone.title, length: 100), group_milestone_path(@group, milestone.safe_title, title: milestone.title) %div diff --git a/app/views/groups/milestones/show.html.haml b/app/views/groups/milestones/show.html.haml index dd2d84499b..fea70f5cbc 100644 --- a/app/views/groups/milestones/show.html.haml +++ b/app/views/groups/milestones/show.html.haml @@ -8,9 +8,9 @@ .pull-right - if can?(current_user, :manage_group, @group) - if @group_milestone.active? - = link_to 'Close Milestone', group_milestone_path(@group, @group_milestone.safe_title, title: @group_milestone.title, milestone: {state_event: :close }), method: :put, class: "btn btn-small btn-close" + = link_to 'Close Milestone', group_milestone_path(@group, @group_milestone.safe_title, title: @group_milestone.title, milestone: {state_event: :close }), method: :put, class: "btn btn-sm btn-close" - else - = link_to 'Reopen Milestone', group_milestone_path(@group, @group_milestone.safe_title, title: @group_milestone.title, milestone: {state_event: :activate }), method: :put, class: "btn btn-small btn-grouped btn-reopen" + = link_to 'Reopen Milestone', group_milestone_path(@group, @group_milestone.safe_title, title: @group_milestone.title, milestone: {state_event: :activate }), method: :put, class: "btn btn-sm btn-grouped btn-reopen" %hr - if (@group_milestone.total_items_count == @group_milestone.closed_items_count) && @group_milestone.active? diff --git a/app/views/groups/projects.html.haml b/app/views/groups/projects.html.haml index c95347b3a5..3b8c26ed39 100644 --- a/app/views/groups/projects.html.haml +++ b/app/views/groups/projects.html.haml @@ -16,9 +16,9 @@ %span.label.label-gray = repository_size(project) .pull-right - = link_to 'Members', namespace_project_team_index_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn btn-small" - = link_to 'Edit', edit_namespace_project_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn btn-small" - = link_to 'Remove', project, data: { confirm: remove_project_message(project)}, method: :delete, class: "btn btn-small btn-remove" + = link_to 'Members', namespace_project_team_index_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn btn-sm" + = link_to 'Edit', edit_namespace_project_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn btn-sm" + = link_to 'Remove', project, data: { confirm: remove_project_message(project)}, method: :delete, class: "btn btn-sm btn-remove" - if @projects.blank? .nothing-here-block This group has no projects yet diff --git a/app/views/profiles/applications.html.haml b/app/views/profiles/applications.html.haml index c8c522e981..97e98948f3 100644 --- a/app/views/profiles/applications.html.haml +++ b/app/views/profiles/applications.html.haml @@ -23,7 +23,7 @@ - application.redirect_uri.split.each do |uri| %div= uri %td= application.access_tokens.count - %td= link_to 'Edit', edit_oauth_application_path(application), class: 'btn btn-link btn-small' + %td= link_to 'Edit', edit_oauth_application_path(application), class: 'btn btn-link btn-sm' %td= render 'doorkeeper/applications/delete_form', application: application %fieldset.oauth-authorized-applications.prepend-top-20 diff --git a/app/views/profiles/emails/index.html.haml b/app/views/profiles/emails/index.html.haml index 3bbad6fdf7..9d8f33cbba 100644 --- a/app/views/profiles/emails/index.html.haml +++ b/app/views/profiles/emails/index.html.haml @@ -25,7 +25,7 @@ %strong= email.email %span.cgray added #{time_ago_with_tooltip(email.created_at)} - = link_to 'Remove', profile_email_path(email), data: { confirm: 'Are you sure?'}, method: :delete, class: 'btn btn-small btn-remove pull-right' + = link_to 'Remove', profile_email_path(email), data: { confirm: 'Are you sure?'}, method: :delete, class: 'btn btn-sm btn-remove pull-right' %h4 Add email address = form_for 'email', url: profile_emails_path, html: { class: 'form-horizontal' } do |f| diff --git a/app/views/profiles/keys/_key.html.haml b/app/views/profiles/keys/_key.html.haml index 8892302e25..fe5770f45c 100644 --- a/app/views/profiles/keys/_key.html.haml +++ b/app/views/profiles/keys/_key.html.haml @@ -9,4 +9,4 @@ %span.cgray added #{time_ago_with_tooltip(key.created_at)} %td - = link_to 'Remove', path_to_key(key, is_admin), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn btn-small btn-remove delete-key pull-right" + = link_to 'Remove', path_to_key(key, is_admin), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn btn-sm btn-remove delete-key pull-right" diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml index 1a7bc353bf..e6b204451c 100644 --- a/app/views/profiles/show.html.haml +++ b/app/views/profiles/show.html.haml @@ -77,7 +77,7 @@ %br or change it at #{link_to "gravatar.com", "http://gravatar.com"} %hr - %a.choose-btn.btn.btn-small.js-choose-user-avatar-button + %a.choose-btn.btn.btn-sm.js-choose-user-avatar-button %i.fa.fa-paperclip %span Choose File ...   @@ -86,7 +86,7 @@ .light The maximum file size allowed is 200KB. - if @user.avatar? %hr - = link_to 'Remove avatar', profile_avatar_path, data: { confirm: "Avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-small remove-avatar" + = link_to 'Remove avatar', profile_avatar_path, data: { confirm: "Avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-sm remove-avatar" - if @user.public_profile? .alert.alert-info diff --git a/app/views/projects/blob/_actions.html.haml b/app/views/projects/blob/_actions.html.haml index b5b29540bb..13f8271b97 100644 --- a/app/views/projects/blob/_actions.html.haml +++ b/app/views/projects/blob/_actions.html.haml @@ -1,22 +1,22 @@ .btn-group.tree-btn-group = edit_blob_link(@project, @ref, @path) = link_to 'Raw', namespace_project_raw_path(@project.namespace, @project, @id), - class: 'btn btn-small', target: '_blank' + class: 'btn btn-sm', target: '_blank' -# only show normal/blame view links for text files - if @blob.text? - if current_page? namespace_project_blame_path(@project.namespace, @project, @id) = link_to 'Normal View', namespace_project_blob_path(@project.namespace, @project, @id), - class: 'btn btn-small' + class: 'btn btn-sm' - else = link_to 'Blame', namespace_project_blame_path(@project.namespace, @project, @id), - class: 'btn btn-small' unless @blob.empty? + class: 'btn btn-sm' unless @blob.empty? = link_to 'History', namespace_project_commits_path(@project.namespace, @project, @id), - class: 'btn btn-small' + class: 'btn btn-sm' - if @ref != @commit.sha = link_to 'Permalink', namespace_project_blob_path(@project.namespace, @project, - tree_join(@commit.sha, @path)), class: 'btn btn-small' + tree_join(@commit.sha, @path)), class: 'btn btn-sm' - if allowed_tree_edit? - = button_tag class: 'remove-blob btn btn-small btn-remove', + = button_tag class: 'remove-blob btn btn-sm btn-remove', 'data-toggle' => 'modal', 'data-target' => '#modal-remove-blob' do Remove diff --git a/app/views/projects/branches/_branch.html.haml b/app/views/projects/branches/_branch.html.haml index 8de629b03e..0de8c509f2 100644 --- a/app/views/projects/branches/_branch.html.haml +++ b/app/views/projects/branches/_branch.html.haml @@ -11,14 +11,14 @@ protected .pull-right - if can?(current_user, :download_code, @project) - = render 'projects/repositories/download_archive', ref: branch.name, btn_class: 'btn-grouped btn-group-small' + = render 'projects/repositories/download_archive', ref: branch.name, btn_class: 'btn-grouped btn-group-sm' - if branch.name != @repository.root_ref - = link_to namespace_project_compare_index_path(@project.namespace, @project, from: @repository.root_ref, to: branch.name), class: 'btn btn-grouped btn-small', method: :post, title: "Compare" do + = link_to namespace_project_compare_index_path(@project.namespace, @project, from: @repository.root_ref, to: branch.name), class: 'btn btn-grouped btn-sm', method: :post, title: "Compare" do %i.fa.fa-files-o Compare - if can_remove_branch?(@project, branch.name) - = link_to namespace_project_branch_path(@project.namespace, @project, branch.name), class: 'btn btn-grouped btn-small btn-remove remove-row', method: :delete, data: { confirm: 'Removed branch cannot be restored. Are you sure?'}, remote: true do + = link_to namespace_project_branch_path(@project.namespace, @project, branch.name), class: 'btn btn-grouped btn-sm btn-remove remove-row', method: :delete, data: { confirm: 'Removed branch cannot be restored. Are you sure?'}, remote: true do %i.fa.fa-trash-o - if commit diff --git a/app/views/projects/deploy_keys/_deploy_key.html.haml b/app/views/projects/deploy_keys/_deploy_key.html.haml index 230e164f24..a2faa9d5e2 100644 --- a/app/views/projects/deploy_keys/_deploy_key.html.haml +++ b/app/views/projects/deploy_keys/_deploy_key.html.haml @@ -1,16 +1,16 @@ %li .pull-right - if @available_keys.include?(deploy_key) - = link_to enable_namespace_project_deploy_key_path(@project.namespace, @project, deploy_key), class: 'btn btn-small', method: :put do + = link_to enable_namespace_project_deploy_key_path(@project.namespace, @project, deploy_key), class: 'btn btn-sm', method: :put do %i.fa.fa-plus Enable - else - if deploy_key.projects.count > 1 - = link_to disable_namespace_project_deploy_key_path(@project.namespace, @project, deploy_key), class: 'btn btn-small', method: :put do + = link_to disable_namespace_project_deploy_key_path(@project.namespace, @project, deploy_key), class: 'btn btn-sm', method: :put do %i.fa.fa-power-off Disable - else - = link_to 'Remove', namespace_project_deploy_key_path(@project.namespace, @project, deploy_key), data: { confirm: 'You are going to remove deploy key. Are you sure?'}, method: :delete, class: "btn btn-remove delete-key btn-small pull-right" + = link_to 'Remove', namespace_project_deploy_key_path(@project.namespace, @project, deploy_key), data: { confirm: 'You are going to remove deploy key. Are you sure?'}, method: :delete, class: "btn btn-remove delete-key btn-sm pull-right" - key_project = deploy_key.projects.include?(@project) ? @project : deploy_key.projects.first diff --git a/app/views/projects/diffs/_file.html.haml b/app/views/projects/diffs/_file.html.haml index 2569e91ccf..36d98b2671 100644 --- a/app/views/projects/diffs/_file.html.haml +++ b/app/views/projects/diffs/_file.html.haml @@ -27,7 +27,7 @@ = check_box_tag nil, 1, false, class: 'js-toggle-diff-line-wrap' Wrap text   - = link_to '#', class: 'js-toggle-diff-comments btn btn-small' do + = link_to '#', class: 'js-toggle-diff-comments btn btn-sm' do %i.fa.fa-chevron-down Show/Hide comments   diff --git a/app/views/projects/diffs/_stats.html.haml b/app/views/projects/diffs/_stats.html.haml index 9b5eb84a86..d387ec2f75 100644 --- a/app/views/projects/diffs/_stats.html.haml +++ b/app/views/projects/diffs/_stats.html.haml @@ -9,7 +9,7 @@ and %strong.cred #{@commit.stats.deletions} deletions   - = link_to '#', class: 'btn btn-small js-toggle-button' do + = link_to '#', class: 'btn btn-sm js-toggle-button' do Show diff stats %i.fa.fa-chevron-down .file-stats.js-toggle-content.hide diff --git a/app/views/projects/diffs/_warning.html.haml b/app/views/projects/diffs/_warning.html.haml index af1f342afb..47abbba2eb 100644 --- a/app/views/projects/diffs/_warning.html.haml +++ b/app/views/projects/diffs/_warning.html.haml @@ -3,15 +3,15 @@ Too many changes. .pull-right - unless diff_hard_limit_enabled? - = link_to "Reload with full diff", url_for(params.merge(force_show_diff: true)), class: "btn btn-small btn-warning" + = link_to "Reload with full diff", url_for(params.merge(force_show_diff: true)), class: "btn btn-sm btn-warning" - if current_controller?(:commit) or current_controller?(:merge_requests) - if current_controller?(:commit) - = link_to "Plain diff", namespace_project_commit_path(@project.namespace, @project, @commit, format: :diff), class: "btn btn-warning btn-small" - = link_to "Email patch", namespace_project_commit_path(@project.namespace, @project, @commit, format: :patch), class: "btn btn-warning btn-small" + = link_to "Plain diff", namespace_project_commit_path(@project.namespace, @project, @commit, format: :diff), class: "btn btn-warning btn-sm" + = link_to "Email patch", namespace_project_commit_path(@project.namespace, @project, @commit, format: :patch), class: "btn btn-warning btn-sm" - elsif @merge_request && @merge_request.persisted? - = link_to "Plain diff", merge_request_path(@merge_request, format: :diff), class: "btn btn-warning btn-small" - = link_to "Email patch", merge_request_path(@merge_request, format: :patch), class: "btn btn-warning btn-small" + = link_to "Plain diff", merge_request_path(@merge_request, format: :diff), class: "btn btn-warning btn-sm" + = link_to "Email patch", merge_request_path(@merge_request, format: :patch), class: "btn btn-warning btn-sm" %p To preserve performance only %strong #{allowed_diff_size} of #{diffs.size} diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index b4c36beda8..e0d75113a5 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -87,7 +87,7 @@ You can change your project avatar here - else You can upload a project avatar here - %a.choose-btn.btn.btn-small.js-choose-project-avatar-button + %a.choose-btn.btn.btn-sm.js-choose-project-avatar-button %i.icon-paper-clip %span Choose File ...   @@ -96,7 +96,7 @@ .light The maximum file size allowed is 200KB. - if @project.avatar? %hr - = link_to 'Remove avatar', namespace_project_avatar_path(@project.namespace, @project), data: { confirm: "Project avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-small remove-avatar" + = link_to 'Remove avatar', namespace_project_avatar_path(@project.namespace, @project), data: { confirm: "Project avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-sm remove-avatar" .form-actions = f.submit 'Save changes', class: "btn btn-save" diff --git a/app/views/projects/hooks/index.html.haml b/app/views/projects/hooks/index.html.haml index e70cf5c388..bbaddba31b 100644 --- a/app/views/projects/hooks/index.html.haml +++ b/app/views/projects/hooks/index.html.haml @@ -58,8 +58,8 @@ - @hooks.each do |hook| %li .pull-right - = link_to 'Test Hook', test_namespace_project_hook_path(@project.namespace, @project, hook), class: "btn btn-small btn-grouped" - = link_to 'Remove', namespace_project_hook_path(@project.namespace, @project, hook), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn btn-remove btn-small btn-grouped" + = link_to 'Test Hook', test_namespace_project_hook_path(@project.namespace, @project, hook), class: "btn btn-sm btn-grouped" + = link_to 'Remove', namespace_project_hook_path(@project.namespace, @project, hook), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn btn-remove btn-sm btn-grouped" .clearfix %span.monospace= hook.url %p diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml index 01e2133e28..3b50ce0135 100644 --- a/app/views/projects/issues/_issue.html.haml +++ b/app/views/projects/issues/_issue.html.haml @@ -41,10 +41,10 @@ .issue-actions - if can? current_user, :modify_issue, issue - if issue.closed? - = link_to 'Reopen', issue_path(issue, issue: {state_event: :reopen }, status_only: true), method: :put, class: "btn btn-small btn-grouped reopen_issue btn-reopen", remote: true + = link_to 'Reopen', issue_path(issue, issue: {state_event: :reopen }, status_only: true), method: :put, class: "btn btn-sm btn-grouped reopen_issue btn-reopen", remote: true - else - = link_to 'Close', issue_path(issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn btn-small btn-grouped close_issue btn-close", remote: true - = link_to edit_namespace_project_issue_path(issue.project.namespace, issue.project, issue), class: "btn btn-small edit-issue-link btn-grouped" do + = link_to 'Close', issue_path(issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn btn-sm btn-grouped close_issue btn-close", remote: true + = link_to edit_namespace_project_issue_path(issue.project.namespace, issue.project, issue), class: "btn btn-sm edit-issue-link btn-grouped" do %i.fa.fa-pencil-square-o Edit diff --git a/app/views/projects/merge_requests/show/_remove_source_branch.html.haml b/app/views/projects/merge_requests/show/_remove_source_branch.html.haml index 0a642b7e6d..59cb85edfc 100644 --- a/app/views/projects/merge_requests/show/_remove_source_branch.html.haml +++ b/app/views/projects/merge_requests/show/_remove_source_branch.html.haml @@ -4,7 +4,7 @@ - elsif can_remove_branch?(@merge_request.source_project, @merge_request.source_branch) && @merge_request.merged? .remove_source_branch_widget %p Changes merged into #{@merge_request.target_branch}. You can remove source branch now - = link_to namespace_project_branch_path(@merge_request.source_project.namespace, @merge_request.source_project, @source_branch), remote: true, method: :delete, class: "btn btn-primary btn-small remove_source_branch" do + = link_to namespace_project_branch_path(@merge_request.source_project.namespace, @merge_request.source_project, @source_branch), remote: true, method: :delete, class: "btn btn-primary btn-sm remove_source_branch" do %i.fa.fa-times Remove Source Branch diff --git a/app/views/projects/milestones/_milestone.html.haml b/app/views/projects/milestones/_milestone.html.haml index dcf56541db..7039c85bb2 100644 --- a/app/views/projects/milestones/_milestone.html.haml +++ b/app/views/projects/milestones/_milestone.html.haml @@ -1,10 +1,10 @@ %li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone) } .pull-right - if can?(current_user, :admin_milestone, milestone.project) and milestone.active? - = link_to edit_namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), class: "btn btn-small edit-milestone-link btn-grouped" do + = link_to edit_namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), class: "btn btn-sm edit-milestone-link btn-grouped" do %i.fa.fa-pencil-square-o Edit - = link_to 'Close Milestone', namespace_project_milestone_path(@project.namespace, @project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-small btn-close" + = link_to 'Close Milestone', namespace_project_milestone_path(@project.namespace, @project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-sm btn-close" %h4 = link_to_gfm truncate(milestone.title, length: 100), namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone) - if milestone.expired? and not milestone.closed? diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index 00b912742b..183343913c 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -104,7 +104,7 @@ .pull-right .light Need a group for several dependent projects? - = link_to new_group_path, class: "btn btn-tiny" do + = link_to new_group_path, class: "btn btn-xs" do Create a group .save-project-loader.hide diff --git a/app/views/projects/protected_branches/_branches_list.html.haml b/app/views/projects/protected_branches/_branches_list.html.haml index 5406b80dc1..bb49f4de87 100644 --- a/app/views/projects/protected_branches/_branches_list.html.haml +++ b/app/views/projects/protected_branches/_branches_list.html.haml @@ -31,4 +31,4 @@ %td .pull-right - if can? current_user, :admin_project, @project - = link_to 'Unprotect', [@project.namespace.becomes(Namespace), @project, branch], data: { confirm: 'Branch will be writable for developers. Are you sure?' }, method: :delete, class: "btn btn-remove btn-small" + = link_to 'Unprotect', [@project.namespace.becomes(Namespace), @project, branch], data: { confirm: 'Branch will be writable for developers. Are you sure?' }, method: :delete, class: "btn btn-remove btn-sm" diff --git a/app/views/projects/snippets/show.html.haml b/app/views/projects/snippets/show.html.haml index 408e3c0224..d19689a105 100644 --- a/app/views/projects/snippets/show.html.haml +++ b/app/views/projects/snippets/show.html.haml @@ -28,10 +28,10 @@ .file-actions .btn-group - if can?(current_user, :modify_project_snippet, @snippet) - = link_to "edit", edit_namespace_project_snippet_path(@project.namespace, @project, @snippet), class: "btn btn-small", title: 'Edit Snippet' - = link_to "raw", raw_namespace_project_snippet_path(@project.namespace, @project, @snippet), class: "btn btn-small", target: "_blank" + = link_to "edit", edit_namespace_project_snippet_path(@project.namespace, @project, @snippet), class: "btn btn-sm", title: 'Edit Snippet' + = link_to "raw", raw_namespace_project_snippet_path(@project.namespace, @project, @snippet), class: "btn btn-sm", target: "_blank" - if can?(current_user, :admin_project_snippet, @snippet) - = link_to "remove", namespace_project_snippet_path(@project.namespace, @project, @snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-small btn-remove", title: 'Delete Snippet' + = link_to "remove", namespace_project_snippet_path(@project.namespace, @project, @snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-sm btn-remove", title: 'Delete Snippet' = render 'shared/snippets/blob' %div#notes= render "projects/notes/notes_with_form" diff --git a/app/views/projects/tags/_tag.html.haml b/app/views/projects/tags/_tag.html.haml index 8da07222cb..f22308e54b 100644 --- a/app/views/projects/tags/_tag.html.haml +++ b/app/views/projects/tags/_tag.html.haml @@ -9,9 +9,9 @@ = strip_gpg_signature(tag.message) .pull-right - if can? current_user, :download_code, @project - = render 'projects/repositories/download_archive', ref: tag.name, btn_class: 'btn-grouped btn-group-small' + = render 'projects/repositories/download_archive', ref: tag.name, btn_class: 'btn-grouped btn-group-sm' - if can?(current_user, :admin_project, @project) - = link_to namespace_project_tag_path(@project.namespace, @project, tag.name), class: 'btn btn-small btn-remove remove-row grouped', method: :delete, data: { confirm: 'Removed tag cannot be restored. Are you sure?'}, remote: true do + = link_to namespace_project_tag_path(@project.namespace, @project, tag.name), class: 'btn btn-sm btn-remove remove-row grouped', method: :delete, data: { confirm: 'Removed tag cannot be restored. Are you sure?'}, remote: true do %i.fa.fa-trash-o - if commit diff --git a/app/views/projects/team_members/_group_members.html.haml b/app/views/projects/team_members/_group_members.html.haml index df3c914fde..12bd828a5e 100644 --- a/app/views/projects/team_members/_group_members.html.haml +++ b/app/views/projects/team_members/_group_members.html.haml @@ -4,7 +4,7 @@ %strong #{@group.name} group members (#{group_users_count}) .pull-right - = link_to members_group_path(@group), class: 'btn btn-small' do + = link_to members_group_path(@group), class: 'btn btn-sm' do %i.fa.fa-pencil-square-o %ul.well-list - @group.group_members.order('access_level DESC').limit(20).each do |member| diff --git a/app/views/projects/team_members/_team_member.html.haml b/app/views/projects/team_members/_team_member.html.haml index eb81544740..1a755bbd56 100644 --- a/app/views/projects/team_members/_team_member.html.haml +++ b/app/views/projects/team_members/_team_member.html.haml @@ -7,7 +7,7 @@ = form_for(member, as: :project_member, url: namespace_project_team_member_path(@project.namespace, @project, member.user)) do |f| = f.select :access_level, options_for_select(ProjectMember.access_roles, member.access_level), {}, class: "trigger-submit"   - = link_to namespace_project_team_member_path(@project.namespace, @project, user), data: { confirm: remove_from_project_team_message(@project, user)}, method: :delete, class: "btn-tiny btn btn-remove", title: 'Remove user from team' do + = link_to namespace_project_team_member_path(@project.namespace, @project, user), data: { confirm: remove_from_project_team_message(@project, user)}, method: :delete, class: "btn-xs btn btn-remove", title: 'Remove user from team' do %i.fa.fa-minus.fa-inverse = image_tag avatar_icon(user.email, 32), class: "avatar s32" %p diff --git a/app/views/projects/tree/show.html.haml b/app/views/projects/tree/show.html.haml index fc4616da6e..feca145369 100644 --- a/app/views/projects/tree/show.html.haml +++ b/app/views/projects/tree/show.html.haml @@ -3,7 +3,7 @@ - if can? current_user, :download_code, @project .tree-download-holder - = render 'projects/repositories/download_archive', ref: @ref, btn_class: 'btn-group-small pull-right hidden-xs hidden-sm', split_button: true + = render 'projects/repositories/download_archive', ref: @ref, btn_class: 'btn-group-sm pull-right hidden-xs hidden-sm', split_button: true #tree-holder.tree-holder.clearfix = render "tree", tree: @tree diff --git a/app/views/projects/wikis/edit.html.haml b/app/views/projects/wikis/edit.html.haml index 5567f1af22..566850cb78 100644 --- a/app/views/projects/wikis/edit.html.haml +++ b/app/views/projects/wikis/edit.html.haml @@ -9,5 +9,5 @@ .pull-right - if @page.persisted? && can?(current_user, :admin_wiki, @project) - = link_to namespace_project_wiki_path(@project.namespace, @project, @page), data: { confirm: "Are you sure you want to delete this page?"}, method: :delete, class: "btn btn-small btn-remove" do + = link_to namespace_project_wiki_path(@project.namespace, @project, @page), data: { confirm: "Are you sure you want to delete this page?"}, method: :delete, class: "btn btn-sm btn-remove" do Delete this page diff --git a/app/views/search/_filter.html.haml b/app/views/search/_filter.html.haml index c635c04fb8..ffc145497a 100644 --- a/app/views/search/_filter.html.haml +++ b/app/views/search/_filter.html.haml @@ -1,5 +1,5 @@ .dropdown.inline - %button.dropdown-toggle.btn.btn-small{type: 'button', 'data-toggle' => 'dropdown'} + %button.dropdown-toggle.btn.btn-sm{type: 'button', 'data-toggle' => 'dropdown'} %i.fa.fa-tags %span.light Group: - if @group.present? @@ -17,7 +17,7 @@ = group.name .dropdown.inline.prepend-left-10.project-filter - %button.dropdown-toggle.btn.btn-small{type: 'button', 'data-toggle' => 'dropdown'} + %button.dropdown-toggle.btn.btn-sm{type: 'button', 'data-toggle' => 'dropdown'} %i.fa.fa-tags %span.light Project: - if @project.present? diff --git a/app/views/shared/_choose_group_avatar_button.html.haml b/app/views/shared/_choose_group_avatar_button.html.haml index 299c0bd42a..000532b1c9 100644 --- a/app/views/shared/_choose_group_avatar_button.html.haml +++ b/app/views/shared/_choose_group_avatar_button.html.haml @@ -1,4 +1,4 @@ -%a.choose-btn.btn.btn-small.js-choose-group-avatar-button +%a.choose-btn.btn.btn-sm.js-choose-group-avatar-button %i.fa.fa-paperclip %span Choose File ...   diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml index d9436caaad..edfa2092df 100644 --- a/app/views/snippets/show.html.haml +++ b/app/views/snippets/show.html.haml @@ -36,8 +36,8 @@ .file-actions .btn-group - if can?(current_user, :modify_personal_snippet, @snippet) - = link_to "edit", edit_snippet_path(@snippet), class: "btn btn-small", title: 'Edit Snippet' - = link_to "raw", raw_snippet_path(@snippet), class: "btn btn-small", target: "_blank" + = link_to "edit", edit_snippet_path(@snippet), class: "btn btn-sm", title: 'Edit Snippet' + = link_to "raw", raw_snippet_path(@snippet), class: "btn btn-sm", target: "_blank" - if can?(current_user, :admin_personal_snippet, @snippet) - = link_to "remove", snippet_path(@snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-small btn-remove", title: 'Delete Snippet' + = link_to "remove", snippet_path(@snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-sm btn-remove", title: 'Delete Snippet' = render 'shared/snippets/blob' diff --git a/app/views/snippets/user_index.html.haml b/app/views/snippets/user_index.html.haml index 67f3a68aa2..df524cd18b 100644 --- a/app/views/snippets/user_index.html.haml +++ b/app/views/snippets/user_index.html.haml @@ -5,7 +5,7 @@ \/ Snippets - if current_user - = link_to new_snippet_path, class: "btn btn-small add_new pull-right", title: "New Snippet" do + = link_to new_snippet_path, class: "btn btn-sm add_new pull-right", title: "New Snippet" do Add new snippet %hr From f311e189d5449f6118fc84746c62e33585e4c39c Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Sat, 14 Mar 2015 00:33:26 -0700 Subject: [PATCH 44/75] Improve compare switch button --- app/assets/stylesheets/pages/commits.scss | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss index e167d044e4..84361e1548 100644 --- a/app/assets/stylesheets/pages/commits.scss +++ b/app/assets/stylesheets/pages/commits.scss @@ -1,17 +1,11 @@ .commits-compare-switch{ + @extend .btn; background: image-url("switch_icon.png") no-repeat center center; - width: 32px; - height: 32px; text-indent: -9999px; float: left; margin-right: 9px; - border: 1px solid #DDD; - @include border-radius(4px); - padding: 4px; - background-color: #EEE; } - .lists-separator { margin: 10px 0; border-color: #DDD; From 9b445c683657a85a090af69b12545b657fe5f616 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Sat, 14 Mar 2015 01:47:06 -0700 Subject: [PATCH 45/75] Return some merge widget styles and make it more compact --- app/assets/stylesheets/base/gl_bootstrap.scss | 5 +++++ app/assets/stylesheets/pages/merge_requests.scss | 11 +++-------- .../projects/merge_requests/show/_mr_accept.html.haml | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/assets/stylesheets/base/gl_bootstrap.scss b/app/assets/stylesheets/base/gl_bootstrap.scss index 7012d31e31..be1ee90c18 100644 --- a/app/assets/stylesheets/base/gl_bootstrap.scss +++ b/app/assets/stylesheets/base/gl_bootstrap.scss @@ -187,6 +187,11 @@ } } +.panel-succes .panel-heading, +.panel-info .panel-heading, +.panel-danger .panel-heading, +.panel-warning .panel-heading, +.panel-primary .panel-heading, .alert { a { @extend .alert-link; diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index 6babb824f3..d41e34caba 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -12,14 +12,8 @@ } .accept-merge-holder { - margin-top: 5px; - .accept-action { display: inline-block; - - .accept_merge_request { - padding: 10px 20px; - } } .accept-control { @@ -123,10 +117,11 @@ } .mr-state-widget { - background: $background-color; + font-size: 13px; + background: #F9F9F9; margin-bottom: 20px; color: #666; - border: 1px solid $border-color; + border: 1px solid #EEE; @include box-shadow(0 1px 1px rgba(0, 0, 0, 0.09)); .ci_widget { diff --git a/app/views/projects/merge_requests/show/_mr_accept.html.haml b/app/views/projects/merge_requests/show/_mr_accept.html.haml index fb2c3220b8..9f51f84d40 100644 --- a/app/views/projects/merge_requests/show/_mr_accept.html.haml +++ b/app/views/projects/merge_requests/show/_mr_accept.html.haml @@ -30,7 +30,7 @@ text: @merge_request.merge_commit_message, rows: 14, hint: true - %hr + %br .light If you still want to merge this request manually - use %strong From 6235b027ec19f3ba0e668a6ee6e77d861c4f68bd Mon Sep 17 00:00:00 2001 From: Vasilij Schneidermann Date: Sat, 14 Mar 2015 10:22:06 +0100 Subject: [PATCH 46/75] Fix typo --- lib/support/deploy/deploy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/support/deploy/deploy.sh b/lib/support/deploy/deploy.sh index 4684957233..adea4c7a74 100755 --- a/lib/support/deploy/deploy.sh +++ b/lib/support/deploy/deploy.sh @@ -4,7 +4,7 @@ # If any command return non-zero status - stop deploy set -e -echo 'Deploy: Stoping sidekiq..' +echo 'Deploy: Stopping sidekiq..' cd /home/git/gitlab/ && sudo -u git -H bundle exec rake sidekiq:stop RAILS_ENV=production echo 'Deploy: Show deploy index page' From 5710c1aaf865d56013e272d2f32abe70d987eafc Mon Sep 17 00:00:00 2001 From: Vinnie Okada Date: Sat, 14 Mar 2015 10:30:48 -0600 Subject: [PATCH 47/75] Update snippet authorization Allow authors and admins to update the visibility level of personal and project snippets. --- app/models/ability.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/models/ability.rb b/app/models/ability.rb index 890417e780..652c6001e0 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -225,13 +225,15 @@ class Ability [:issue, :note, :project_snippet, :personal_snippet, :merge_request].each do |name| define_method "#{name}_abilities" do |user, subject| - if subject.author == user - [ + if subject.author == user || user.is_admin? + rules = [ :"read_#{name}", :"write_#{name}", :"modify_#{name}", :"admin_#{name}" ] + rules.push(:change_visibility_level) if subject.is_a?(Snippet) + rules elsif subject.respond_to?(:assignee) && subject.assignee == user [ :"read_#{name}", From 13e9f4f33420bf0bae0b61b98dd3c2301d6f6223 Mon Sep 17 00:00:00 2001 From: Vinnie Okada Date: Sat, 14 Mar 2015 10:33:02 -0600 Subject: [PATCH 48/75] Add tests for snippet services Add Rspec tests for the new UpdateSnippetService and CreateSnippetService classes. --- spec/services/create_snippet_service_spec.rb | 44 +++++++++++++++++ spec/services/update_snippet_service_spec.rb | 52 ++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 spec/services/create_snippet_service_spec.rb create mode 100644 spec/services/update_snippet_service_spec.rb diff --git a/spec/services/create_snippet_service_spec.rb b/spec/services/create_snippet_service_spec.rb new file mode 100644 index 0000000000..08689c15ca --- /dev/null +++ b/spec/services/create_snippet_service_spec.rb @@ -0,0 +1,44 @@ +require 'spec_helper' + +describe CreateSnippetService do + before do + @user = create :user + @admin = create :user, admin: true + @opts = { + title: 'Test snippet', + file_name: 'snippet.rb', + content: 'puts "hello world"', + visibility_level: Gitlab::VisibilityLevel::PRIVATE + } + end + + context 'When public visibility is restricted' do + before do + allow_any_instance_of(ApplicationSetting).to( + receive(:restricted_visibility_levels).and_return( + [Gitlab::VisibilityLevel::PUBLIC] + ) + ) + + @opts.merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) + end + + it 'non-admins should not be able to create a public snippet' do + snippet = create_snippet(nil, @user, @opts) + expect(snippet.errors.messages).to have_key(:visibility_level) + expect(snippet.errors.messages[:visibility_level].first).to( + match('Public visibility has been restricted') + ) + end + + it 'admins should be able to create a public snippet' do + snippet = create_snippet(nil, @admin, @opts) + expect(snippet.errors.any?).to be_falsey + expect(snippet.visibility_level).to eq(Gitlab::VisibilityLevel::PUBLIC) + end + end + + def create_snippet(project, user, opts) + CreateSnippetService.new(project, user, opts).execute + end +end diff --git a/spec/services/update_snippet_service_spec.rb b/spec/services/update_snippet_service_spec.rb new file mode 100644 index 0000000000..841ef9bfed --- /dev/null +++ b/spec/services/update_snippet_service_spec.rb @@ -0,0 +1,52 @@ +require 'spec_helper' + +describe UpdateSnippetService do + before do + @user = create :user + @admin = create :user, admin: true + @opts = { + title: 'Test snippet', + file_name: 'snippet.rb', + content: 'puts "hello world"', + visibility_level: Gitlab::VisibilityLevel::PRIVATE + } + end + + context 'When public visibility is restricted' do + before do + allow_any_instance_of(ApplicationSetting).to( + receive(:restricted_visibility_levels).and_return( + [Gitlab::VisibilityLevel::PUBLIC] + ) + ) + + @snippet = create_snippet(@project, @user, @opts) + @opts.merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) + end + + it 'non-admins should not be able to update to public visibility' do + old_visibility = @snippet.visibility_level + update_snippet(@project, @user, @snippet, @opts) + expect(@snippet.errors.messages).to have_key(:visibility_level) + expect(@snippet.errors.messages[:visibility_level].first).to( + match('Public visibility has been restricted') + ) + expect(@snippet.visibility_level).to eq(old_visibility) + end + + it 'admins should be able to update to pubic visibility' do + old_visibility = @snippet.visibility_level + update_snippet(@project, @admin, @snippet, @opts) + expect(@snippet.visibility_level).not_to eq(old_visibility) + expect(@snippet.visibility_level).to eq(Gitlab::VisibilityLevel::PUBLIC) + end + end + + def create_snippet(project, user, opts) + CreateSnippetService.new(project, user, opts).execute + end + + def update_snippet(project = nil, user, snippet, opts) + UpdateSnippetService.new(project, user, snippet, opts).execute + end +end From d7f357a386162f645ba5a8550dfa1d3b22d0ff2c Mon Sep 17 00:00:00 2001 From: Vinnie Okada Date: Sat, 14 Mar 2015 12:20:40 -0600 Subject: [PATCH 49/75] Use pre-wrap for diff code in discussion view --- CHANGELOG | 1 + app/assets/stylesheets/pages/notes.scss | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index ba4f6e6de9..7bc561b6e0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -23,6 +23,7 @@ v 7.9.0 (unreleased) - Fix checkbox alignment on the application settings page. - Generalize image upload in drag and drop in markdown to all files (Hannes Rosenögger) - Fix mass-unassignment of issues (Robert Speicher) + - Fix hidden diff comments in merge request discussion view - Allow user confirmation to be skipped for new users via API - Add a service to send updates to an Irker gateway (Romain Coltel) - Add brakeman (security scanner for Ruby on Rails) diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index 384ff6d740..70505dc430 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -89,6 +89,11 @@ ul.notes { } } +// Diff code in discussion view +.discussion-body .diff-file .line_content { + white-space: pre-wrap; +} + .diff-file .notes_holder { font-size: 13px; line-height: 18px; From 99f995755ef4b445216dd7baae35f5a4846ef30c Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 13 Mar 2015 16:16:51 +0100 Subject: [PATCH 50/75] Use `group_member` instead of `users_group` or `membership`. --- .../groups/group_members_controller.rb | 6 ++--- .../profiles/notifications_controller.rb | 6 ++--- app/mailers/emails/groups.rb | 8 +++---- app/models/ability.rb | 10 ++++---- app/services/notification_service.rb | 10 ++++---- app/views/admin/users/show.html.haml | 24 +++++++++---------- app/views/dashboard/groups/index.html.haml | 12 +++++----- .../group_members/_group_member.html.haml | 4 ++-- .../group_access_granted_email.html.haml | 2 +- .../group_access_granted_email.text.erb | 2 +- .../profiles/notifications/show.html.haml | 6 ++--- lib/api/group_members.rb | 10 ++++---- spec/models/members/group_member_spec.rb | 12 +++++----- spec/services/notification_service_spec.rb | 6 ++--- 14 files changed, 59 insertions(+), 59 deletions(-) diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb index b083cf5d8c..132452d61c 100644 --- a/app/controllers/groups/group_members_controller.rb +++ b/app/controllers/groups/group_members_controller.rb @@ -18,10 +18,10 @@ class Groups::GroupMembersController < Groups::ApplicationController end def destroy - @users_group = @group.group_members.find(params[:id]) + @group_member = @group.group_members.find(params[:id]) - if can?(current_user, :destroy, @users_group) # May fail if last owner. - @users_group.destroy + if can?(current_user, :destroy_group_member, @group_member) # May fail if last owner. + @group_member.destroy respond_to do |format| format.html { redirect_to members_group_path(@group), notice: 'User was successfully removed from group.' } format.js { render nothing: true } diff --git a/app/controllers/profiles/notifications_controller.rb b/app/controllers/profiles/notifications_controller.rb index 433c19189a..3fdcbbab61 100644 --- a/app/controllers/profiles/notifications_controller.rb +++ b/app/controllers/profiles/notifications_controller.rb @@ -14,9 +14,9 @@ class Profiles::NotificationsController < ApplicationController @saved = if type == 'global' current_user.update_attributes(user_params) elsif type == 'group' - users_group = current_user.group_members.find(params[:notification_id]) - users_group.notification_level = params[:notification_level] - users_group.save + group_member = current_user.group_members.find(params[:notification_id]) + group_member.notification_level = params[:notification_level] + group_member.save else project_member = current_user.project_members.find(params[:notification_id]) project_member.notification_level = params[:notification_level] diff --git a/app/mailers/emails/groups.rb b/app/mailers/emails/groups.rb index 8c09389985..26f43bf955 100644 --- a/app/mailers/emails/groups.rb +++ b/app/mailers/emails/groups.rb @@ -1,10 +1,10 @@ module Emails module Groups - def group_access_granted_email(user_group_id) - @membership = GroupMember.find(user_group_id) - @group = @membership.group + def group_access_granted_email(group_member_id) + @group_member = GroupMember.find(group_member_id) + @group = @group_member.group @target_url = group_url(@group) - mail(to: @membership.user.email, + mail(to: @group_member.user.email, subject: subject("Access to group was granted")) end end diff --git a/app/models/ability.rb b/app/models/ability.rb index 890417e780..773b51a7bc 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -14,7 +14,7 @@ class Ability when "MergeRequest" then merge_request_abilities(user, subject) when "Group" then group_abilities(user, subject) when "Namespace" then namespace_abilities(user, subject) - when "GroupMember" then users_group_abilities(user, subject) + when "GroupMember" then group_member_abilities(user, subject) else [] end.concat(global_abilities(user)) end @@ -248,17 +248,17 @@ class Ability end end - def users_group_abilities(user, subject) + def group_member_abilities(user, subject) rules = [] target_user = subject.user group = subject.group can_manage = group_abilities(user, group).include?(:manage_group) if can_manage && (user != target_user) - rules << :modify - rules << :destroy + rules << :modify_group_member + rules << :destroy_group_member end if !group.last_owner?(user) && (can_manage || (user == target_user)) - rules << :destroy + rules << :destroy_group_member end rules end diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 0063b7ce40..843cb0c5ee 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -194,11 +194,11 @@ class NotificationService project_members = project_member_notification(project) users_with_project_level_global = project_member_notification(project, Notification::N_GLOBAL) - users_with_group_level_global = users_group_notification(project, Notification::N_GLOBAL) + users_with_group_level_global = group_member_notification(project, Notification::N_GLOBAL) users = users_with_global_level_watch([users_with_project_level_global, users_with_group_level_global].flatten.uniq) users_with_project_setting = select_project_member_setting(project, users_with_project_level_global, users) - users_with_group_setting = select_users_group_setting(project, project_members, users_with_group_level_global, users) + users_with_group_setting = select_group_member_setting(project, project_members, users_with_group_level_global, users) User.where(id: users_with_project_setting.concat(users_with_group_setting).uniq).to_a end @@ -213,7 +213,7 @@ class NotificationService end end - def users_group_notification(project, notification_level) + def group_member_notification(project, notification_level) if project.group project.group.group_members.where(notification_level: notification_level).pluck(:user_id) else @@ -243,8 +243,8 @@ class NotificationService end # Build a list of users based on group notification settings - def select_users_group_setting(project, project_members, global_setting, users_global_level_watch) - uids = users_group_notification(project, Notification::N_WATCH) + def select_group_member_setting(project, project_members, global_setting, users_global_level_watch) + uids = group_member_notification(project, Notification::N_WATCH) # Group setting is watch, add to users list if user is not project member users = [] diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml index 5cf423ead8..0a2934d3bd 100644 --- a/app/views/admin/users/show.html.haml +++ b/app/views/admin/users/show.html.haml @@ -174,15 +174,15 @@ .panel.panel-default .panel-heading Groups: %ul.well-list - - @user.group_members.each do |user_group| - - group = user_group.group + - @user.group_members.each do |group_member| + - group = group_member.group %li.group_member - %span{class: ("list-item-name" unless user_group.owner?)} + %span{class: ("list-item-name" unless group_member.owner?)} %strong= link_to group.name, admin_group_path(group) .pull-right - %span.light= user_group.human_access - - unless user_group.owner? - = link_to group_group_member_path(group, user_group), data: { confirm: remove_user_from_group_message(group, @user) }, method: :delete, remote: true, class: "btn-xs btn btn-remove", title: 'Remove user from group' do + %span.light= group_member.human_access + - unless group_member.owner? + = link_to group_group_member_path(group, group_member), data: { confirm: remove_user_from_group_message(group, @user) }, method: :delete, remote: true, class: "btn-xs btn btn-remove", title: 'Remove user from group' do %i.fa.fa-times.fa-inverse - else .nothing-here-block This user has no groups. @@ -207,21 +207,21 @@ .panel-heading Joined projects (#{@joined_projects.count}) %ul.well-list - @joined_projects.sort_by(&:name_with_namespace).each do |project| - - tm = project.team.find_tm(@user.id) + - member = project.team.find_member(@user.id) %li.project_member .list-item-name = link_to admin_namespace_project_path(project.namespace, project), class: dom_class(project) do = project.name_with_namespace - - if tm + - if member .pull-right - - if tm.owner? + - if member.owner? %span.light Owner - else - %span.light= tm.human_access + %span.light= member.human_access - - if tm.respond_to? :project - = link_to namespace_project_team_member_path(project.namespace, project, @user), data: { confirm: remove_from_project_team_message(project, @user) }, remote: true, method: :delete, class: "btn-xs btn btn-remove", title: 'Remove user from project' do + - if member.respond_to? :project + = link_to namespace_project_project_member_path(project.namespace, project, @user), data: { confirm: remove_from_project_team_message(project, @user) }, remote: true, method: :delete, class: "btn-xs btn btn-remove", title: 'Remove user from project' do %i.fa.fa-times #ssh-keys.tab-pane = render 'profiles/keys/key_table', admin: true diff --git a/app/views/dashboard/groups/index.html.haml b/app/views/dashboard/groups/index.html.haml index c232644b02..76f7d660f3 100644 --- a/app/views/dashboard/groups/index.html.haml +++ b/app/views/dashboard/groups/index.html.haml @@ -11,10 +11,10 @@ .panel.panel-default .panel-heading %strong Groups - (#{@user_groups.count}) + (#{@group_members.count}) %ul.well-list - - @user_groups.each do |user_group| - - group = user_group.group + - @group_members.each do |group_member| + - group = group_member.group %li .pull-right - if can?(current_user, :manage_group, group) @@ -22,7 +22,7 @@ %i.fa.fa-cogs Settings - - if can?(current_user, :destroy, user_group) + - if can?(current_user, :destroy_group_member, group_member) = link_to leave_dashboard_group_path(group), data: { confirm: leave_group_message(group.name) }, method: :delete, class: "btn-sm btn btn-grouped", title: 'Remove user from group' do %i.fa.fa-sign-out Leave @@ -32,9 +32,9 @@ %strong= group.name as - %strong #{user_group.human_access} + %strong #{group_member.human_access} %div.light #{pluralize(group.projects.count, "project")}, #{pluralize(group.users.count, "user")} -= paginate @user_groups += paginate @group_members diff --git a/app/views/groups/group_members/_group_member.html.haml b/app/views/groups/group_members/_group_member.html.haml index 5bef796c5a..2fc91df093 100644 --- a/app/views/groups/group_members/_group_member.html.haml +++ b/app/views/groups/group_members/_group_member.html.haml @@ -16,11 +16,11 @@ %span.pull-right %strong= member.human_access - if show_controls - - if can?(current_user, :modify, member) + - if can?(current_user, :modify_group_member, member) = button_tag class: "btn-xs btn js-toggle-button", title: 'Edit access level', type: 'button' do %i.fa.fa-pencil-square-o - - if can?(current_user, :destroy, member) + - if can?(current_user, :destroy_group_member, member) - if current_user == member.user = link_to leave_dashboard_group_path(@group), data: { confirm: leave_group_message(@group.name)}, method: :delete, class: "btn-xs btn btn-remove", title: 'Remove user from group' do %i.fa.fa-minus.fa-inverse diff --git a/app/views/notify/group_access_granted_email.html.haml b/app/views/notify/group_access_granted_email.html.haml index 823ebf7734..f1916d624b 100644 --- a/app/views/notify/group_access_granted_email.html.haml +++ b/app/views/notify/group_access_granted_email.html.haml @@ -1,4 +1,4 @@ %p - = "You have been granted #{@membership.human_access} access to group" + = "You have been granted #{@group_member.human_access} access to group" = link_to group_url(@group) do = @group.name diff --git a/app/views/notify/group_access_granted_email.text.erb b/app/views/notify/group_access_granted_email.text.erb index 331bb98d5c..ef9617bfc1 100644 --- a/app/views/notify/group_access_granted_email.text.erb +++ b/app/views/notify/group_access_granted_email.text.erb @@ -1,4 +1,4 @@ -You have been granted <%= @membership.human_access %> access to group <%= @group.name %> +You have been granted <%= @group_member.human_access %> access to group <%= @group.name %> <%= url_for(group_url(@group)) %> diff --git a/app/views/profiles/notifications/show.html.haml b/app/views/profiles/notifications/show.html.haml index 6cf5c81c19..273e72f8a4 100644 --- a/app/views/profiles/notifications/show.html.haml +++ b/app/views/profiles/notifications/show.html.haml @@ -62,9 +62,9 @@ By default, all projects and groups will use the notification level set above. %h4 Groups: %ul.bordered-list - - @group_members.each do |users_group| - - notification = Notification.new(users_group) - = render 'settings', type: 'group', membership: users_group, notification: notification + - @group_members.each do |group_member| + - notification = Notification.new(group_member) + = render 'settings', type: 'group', membership: group_member, notification: notification .col-md-6 %p diff --git a/lib/api/group_members.rb b/lib/api/group_members.rb index c9c9ccbcb2..ed54c7f6ff 100644 --- a/lib/api/group_members.rb +++ b/lib/api/group_members.rb @@ -53,14 +53,14 @@ module API authorize! :manage_group, group required_attributes! [:access_level] - team_member = group.group_members.find_by(user_id: params[:user_id]) - not_found!('User can not be found') if team_member.nil? + group_member = group.group_members.find_by(user_id: params[:user_id]) + not_found!('User can not be found') if group_member.nil? - if team_member.update_attributes(access_level: params[:access_level]) - @member = team_member.user + if group_member.update_attributes(access_level: params[:access_level]) + @member = group_member.user present @member, with: Entities::GroupMember, group: group else - handle_member_errors team_member.errors + handle_member_errors group_member.errors end end diff --git a/spec/models/members/group_member_spec.rb b/spec/models/members/group_member_spec.rb index e04f1741b2..e206c11f33 100644 --- a/spec/models/members/group_member_spec.rb +++ b/spec/models/members/group_member_spec.rb @@ -28,18 +28,18 @@ describe GroupMember do describe "#after_update" do before do - @membership = create :group_member - @membership.stub(notification_service: double('NotificationService').as_null_object) + @group_member = create :group_member + @group_member.stub(notification_service: double('NotificationService').as_null_object) end it "should send email to user" do - expect(@membership).to receive(:notification_service) - @membership.update_attribute(:access_level, GroupMember::MASTER) + expect(@group_member).to receive(:notification_service) + @group_member.update_attribute(:access_level, GroupMember::MASTER) end it "does not send an email when the access level has not changed" do - expect(@membership).not_to receive(:notification_service) - @membership.update_attribute(:access_level, GroupMember::OWNER) + expect(@group_member).not_to receive(:notification_service) + @group_member.update_attribute(:access_level, GroupMember::OWNER) end end end diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb index 2074f8e7f7..34737348d4 100644 --- a/spec/services/notification_service_spec.rb +++ b/spec/services/notification_service_spec.rb @@ -69,9 +69,9 @@ describe NotificationService do user_project = note.project.project_members.find_by_user_id(@u_watcher.id) user_project.notification_level = Notification::N_PARTICIPATING user_project.save - user_group = note.project.group.group_members.find_by_user_id(@u_watcher.id) - user_group.notification_level = Notification::N_GLOBAL - user_group.save + group_member = note.project.group.group_members.find_by_user_id(@u_watcher.id) + group_member.notification_level = Notification::N_GLOBAL + group_member.save end it do From 31fc73f0a9b9225ba3737b9525fcf7a1695a45f2 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 13 Mar 2015 16:22:03 +0100 Subject: [PATCH 51/75] Use `project_member` instead of `team_member`. --- app/assets/javascripts/dispatcher.js.coffee | 2 +- app/assets/stylesheets/generic/common.scss | 2 +- app/assets/stylesheets/pages/projects.scss | 2 +- app/controllers/admin/groups_controller.rb | 4 +- .../projects/project_members_controller.rb | 88 +++++++++++++++++++ .../projects/team_members_controller.rb | 73 --------------- app/helpers/search_helper.rb | 2 +- app/helpers/tab_helper.rb | 2 +- app/models/ability.rb | 6 +- app/models/members/project_member.rb | 4 +- app/models/project.rb | 4 +- app/models/user.rb | 5 +- app/services/notification_service.rb | 12 +-- app/services/projects/participants_service.rb | 4 +- app/views/admin/groups/show.html.haml | 2 +- app/views/admin/projects/show.html.haml | 4 +- app/views/groups/projects.html.haml | 2 +- app/views/projects/_dropdown.html.haml | 2 +- app/views/projects/_settings_nav.html.haml | 2 +- config/routes.rb | 4 +- features/steps/admin/groups.rb | 2 +- lib/api/project_members.rb | 28 +++--- lib/gitlab/markdown.rb | 2 +- spec/helpers/gitlab_markdown_helper_spec.rb | 2 +- spec/routing/project_routing_spec.rb | 17 ++-- 25 files changed, 143 insertions(+), 134 deletions(-) create mode 100644 app/controllers/projects/project_members_controller.rb delete mode 100644 app/controllers/projects/team_members_controller.rb diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee index e1015a63d5..5da774cfb2 100644 --- a/app/assets/javascripts/dispatcher.js.coffee +++ b/app/assets/javascripts/dispatcher.js.coffee @@ -127,7 +127,7 @@ class Dispatcher new DropzoneInput($('.wiki-form')) when 'snippets', 'labels', 'graphs' shortcut_handler = new ShortcutsNavigation() - when 'team_members', 'deploy_keys', 'hooks', 'services', 'protected_branches' + when 'project_members', 'deploy_keys', 'hooks', 'services', 'protected_branches' shortcut_handler = new ShortcutsNavigation() new UsersSelect() diff --git a/app/assets/stylesheets/generic/common.scss b/app/assets/stylesheets/generic/common.scss index af8e90eb1a..876eea72e8 100644 --- a/app/assets/stylesheets/generic/common.scss +++ b/app/assets/stylesheets/generic/common.scss @@ -167,7 +167,7 @@ li.note { background-color: inherit; } -.team_member_show { +.project_member_show { td:first-child { color: #aaa; } diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index e359aa4502..7475595167 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -156,7 +156,7 @@ ul.nav.nav-projects-tabs { } } -.team_member_row form { +.project_member_row form { margin: 0px; } diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb index e338abeac4..9d9adaa467 100644 --- a/app/controllers/admin/groups_controller.rb +++ b/app/controllers/admin/groups_controller.rb @@ -1,5 +1,5 @@ class Admin::GroupsController < Admin::ApplicationController - before_filter :group, only: [:edit, :show, :update, :destroy, :project_update, :project_teams_update] + before_filter :group, only: [:edit, :show, :update, :destroy, :project_update, :members_update] def index @groups = Group.all @@ -40,7 +40,7 @@ class Admin::GroupsController < Admin::ApplicationController end end - def project_teams_update + def members_update @group.add_users(params[:user_ids].split(','), params[:access_level]) redirect_to [:admin, @group], notice: 'Users were successfully added.' diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb new file mode 100644 index 0000000000..4ab15db01f --- /dev/null +++ b/app/controllers/projects/project_members_controller.rb @@ -0,0 +1,88 @@ +class Projects::ProjectMembersController < Projects::ApplicationController + # Authorize + before_filter :authorize_admin_project!, except: :leave + + layout "project_settings" + + def index + @project_members = @project.project_members + + if params[:search].present? + users = @project.users.search(params[:search]).to_a + @project_members = @project_members.where(user_id: users) + end + + @project_members = @project_members.order('access_level DESC') + + @group = @project.group + if @group + @group_members = @group.group_members + + if params[:search].present? + users = @group.users.search(params[:search]).to_a + @group_members = @group_members.where(user_id: users) + end + + @group_members = @group_members.order('access_level DESC').limit(20) + end + + @project_member = @project.project_members.new + end + + def new + @project_member = @project.project_members.new + end + + def create + users = User.where(id: params[:user_ids].split(',')) + @project.team << [users, params[:access_level]] + + redirect_to namespace_project_project_members_path(@project.namespace, @project) + end + + def update + @project_member = @project.project_members.find_by(user_id: member) + @project_member.update_attributes(member_params) + end + + def destroy + @project_member = @project.project_members.find_by(user_id: member) + @project_member.destroy + + respond_to do |format| + format.html do + redirect_to namespace_project_project_members_path(@project.namespace, + @project) + end + format.js { render nothing: true } + end + end + + def leave + @project.project_members.find_by(user_id: current_user).destroy + + respond_to do |format| + format.html { redirect_to :back } + format.js { render nothing: true } + end + end + + def apply_import + giver = Project.find(params[:source_project_id]) + status = @project.team.import(giver) + notice = status ? "Successfully imported" : "Import failed" + + redirect_to(namespace_project_project_members_path(project.namespace, project), + notice: notice) + end + + protected + + def member + @member ||= User.find_by(username: params[:id]) + end + + def member_params + params.require(:project_member).permit(:user_id, :access_level) + end +end diff --git a/app/controllers/projects/team_members_controller.rb b/app/controllers/projects/team_members_controller.rb deleted file mode 100644 index f8a248ed72..0000000000 --- a/app/controllers/projects/team_members_controller.rb +++ /dev/null @@ -1,73 +0,0 @@ -class Projects::TeamMembersController < Projects::ApplicationController - # Authorize - before_filter :authorize_admin_project!, except: :leave - - layout "project_settings" - - def index - @group = @project.group - @project_members = @project.project_members.order('access_level DESC') - end - - def new - @user_project_relation = @project.project_members.new - end - - def create - users = User.where(id: params[:user_ids].split(',')) - @project.team << [users, params[:access_level]] - - redirect_to namespace_project_team_index_path(@project.namespace, @project) - end - - def update - @user_project_relation = @project.project_members.find_by(user_id: member) - @user_project_relation.update_attributes(member_params) - - unless @user_project_relation.valid? - flash[:alert] = "User should have at least one role" - end - redirect_to namespace_project_team_index_path(@project.namespace, @project) - end - - def destroy - @user_project_relation = @project.project_members.find_by(user_id: member) - @user_project_relation.destroy - - respond_to do |format| - format.html do - redirect_to namespace_project_team_index_path(@project.namespace, - @project) - end - format.js { render nothing: true } - end - end - - def leave - @project.project_members.find_by(user_id: current_user).destroy - - respond_to do |format| - format.html { redirect_to :back } - format.js { render nothing: true } - end - end - - def apply_import - giver = Project.find(params[:source_project_id]) - status = @project.team.import(giver) - notice = status ? "Successfully imported" : "Import failed" - - redirect_to(namespace_project_team_index_path(project.namespace, project), - notice: notice) - end - - protected - - def member - @member ||= User.find_by(username: params[:id]) - end - - def member_params - params.require(:project_member).permit(:user_id, :access_level) - end -end diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index cb82903769..7d3fcfa703 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -60,7 +60,7 @@ module SearchHelper { label: "#{prefix} - Merge Requests", url: namespace_project_merge_requests_path(@project.namespace, @project) }, { label: "#{prefix} - Milestones", url: namespace_project_milestones_path(@project.namespace, @project) }, { label: "#{prefix} - Snippets", url: namespace_project_snippets_path(@project.namespace, @project) }, - { label: "#{prefix} - Team", url: namespace_project_team_index_path(@project.namespace, @project) }, + { label: "#{prefix} - Members", url: namespace_project_project_members_path(@project.namespace, @project) }, { label: "#{prefix} - Wiki", url: namespace_project_wikis_path(@project.namespace, @project) }, ] else diff --git a/app/helpers/tab_helper.rb b/app/helpers/tab_helper.rb index 7a401a274d..a1d263d9d3 100644 --- a/app/helpers/tab_helper.rb +++ b/app/helpers/tab_helper.rb @@ -89,7 +89,7 @@ module TabHelper def project_tab_class return "active" if current_page?(controller: "/projects", action: :edit, id: @project) - if ['services', 'hooks', 'deploy_keys', 'team_members', 'protected_branches'].include? controller.controller_name + if ['services', 'hooks', 'deploy_keys', 'project_members', 'protected_branches'].include? controller.controller_name "active" end end diff --git a/app/models/ability.rb b/app/models/ability.rb index 773b51a7bc..855134dd39 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -37,7 +37,7 @@ class Ability :read_issue, :read_milestone, :read_project_snippet, - :read_team_member, + :read_project_member, :read_merge_request, :read_note, :download_code @@ -119,7 +119,7 @@ class Ability :read_issue, :read_milestone, :read_project_snippet, - :read_team_member, + :read_project_member, :read_merge_request, :read_note, :write_project, @@ -166,7 +166,7 @@ class Ability :admin_issue, :admin_milestone, :admin_project_snippet, - :admin_team_member, + :admin_project_member, :admin_merge_request, :admin_note, :admin_wiki, diff --git a/app/models/members/project_member.rb b/app/models/members/project_member.rb index e4791d0f0a..6b13e0ff30 100644 --- a/app/models/members/project_member.rb +++ b/app/models/members/project_member.rb @@ -116,14 +116,14 @@ class ProjectMember < Member def post_create_hook unless owner? event_service.join_project(self.project, self.user) - notification_service.new_team_member(self) + notification_service.new_project_member(self) end system_hook_service.execute_hooks_for(self, :create) end def post_update_hook - notification_service.update_team_member(self) if self.access_level_changed? + notification_service.update_project_member(self) if self.access_level_changed? end def post_destroy_hook diff --git a/app/models/project.rb b/app/models/project.rb index c45338bf4e..f0b416c8f4 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -445,13 +445,13 @@ class Project < ActiveRecord::Base end end - def team_member_by_name_or_email(name = nil, email = nil) + def project_member_by_name_or_email(name = nil, email = nil) user = users.where('name like ? or email like ?', name, email).first project_members.where(user: user) if user end # Get Team Member record by user id - def team_member_by_id(user_id) + def project_member_by_id(user_id) project_members.find_by(user_id: user_id) end diff --git a/app/models/user.rb b/app/models/user.rb index 0d40ac8309..ba325132df 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -169,11 +169,8 @@ class User < ActiveRecord::Base scope :admins, -> { where(admin: true) } scope :blocked, -> { with_state(:blocked) } scope :active, -> { with_state(:active) } - scope :in_team, ->(team){ where(id: team.member_ids) } - scope :not_in_team, ->(team){ where('users.id NOT IN (:ids)', ids: team.member_ids) } scope :not_in_project, ->(project) { project.users.present? ? where("id not in (:ids)", ids: project.users.map(&:id) ) : all } scope :without_projects, -> { where('id NOT IN (SELECT DISTINCT(user_id) FROM members)') } - scope :potential_team_members, ->(team) { team.members.any? ? active.not_in_team(team) : active } # # Class methods @@ -407,7 +404,7 @@ class User < ActiveRecord::Base end def tm_of(project) - project.team_member_by_id(self.id) + project.project_member_by_id(self.id) end def already_forked?(project) diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 843cb0c5ee..fb5baaf74b 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -162,20 +162,20 @@ class NotificationService end end - def new_team_member(project_member) + def new_project_member(project_member) mailer.project_access_granted_email(project_member.id) end - def update_team_member(project_member) + def update_project_member(project_member) mailer.project_access_granted_email(project_member.id) end - def new_group_member(users_group) - mailer.group_access_granted_email(users_group.id) + def new_group_member(group_member) + mailer.group_access_granted_email(group_member.id) end - def update_group_member(users_group) - mailer.group_access_granted_email(users_group.id) + def update_group_member(group_member) + mailer.group_access_granted_email(group_member.id) end def project_was_moved(project) diff --git a/app/services/projects/participants_service.rb b/app/services/projects/participants_service.rb index f6f9aceef9..bcbacbff56 100644 --- a/app/services/projects/participants_service.rb +++ b/app/services/projects/participants_service.rb @@ -12,8 +12,8 @@ module Projects else [] end - team_members = sorted(@project.team.members) - participants = all_members + groups + team_members + participating + project_members = sorted(@project.team.members) + participants = all_members + groups + project_members + participating participants.uniq end diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml index a28eae3892..7d29211807 100644 --- a/app/views/admin/groups/show.html.haml +++ b/app/views/admin/groups/show.html.haml @@ -58,7 +58,7 @@ Read more about project permissions %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink" - = form_tag project_teams_update_admin_group_path(@group), id: "new_team_member", class: "bulk_import", method: :put do + = 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) %div.prepend-top-10 diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml index ebb3b3a636..70ebc9561d 100644 --- a/app/views/admin/projects/show.html.haml +++ b/app/views/admin/projects/show.html.haml @@ -114,7 +114,7 @@ = link_to namespace_project_team_index_path(@project.namespace, @project), class: "btn btn-xs" do %i.fa.fa-pencil-square-o Manage Access - %ul.well-list.team_members + %ul.well-list.project_members - @project_members.each do |project_member| - user = project_member.user %li.project_member @@ -126,7 +126,7 @@ %span.light Owner - else %span.light= project_member.human_access - = link_to namespace_project_team_member_path(@project.namespace, @project, user), data: { confirm: remove_from_project_team_message(@project, user)}, method: :delete, remote: true, class: "btn btn-sm btn-remove" do + = link_to namespace_project_project_member_path(@project.namespace, @project, user), data: { confirm: remove_from_project_team_message(@project, user)}, method: :delete, remote: true, class: "btn btn-sm btn-remove" do %i.fa.fa-times .panel-footer = paginate @project_members, param_name: 'project_members_page', theme: 'gitlab' diff --git a/app/views/groups/projects.html.haml b/app/views/groups/projects.html.haml index 3b8c26ed39..dd1fa3840d 100644 --- a/app/views/groups/projects.html.haml +++ b/app/views/groups/projects.html.haml @@ -16,7 +16,7 @@ %span.label.label-gray = repository_size(project) .pull-right - = link_to 'Members', namespace_project_team_index_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn btn-sm" + = link_to 'Members', namespace_project_project_members_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn btn-sm" = link_to 'Edit', edit_namespace_project_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn btn-sm" = link_to 'Remove', project, data: { confirm: remove_project_message(project)}, method: :delete, class: "btn btn-sm btn-remove" - if @projects.blank? diff --git a/app/views/projects/_dropdown.html.haml b/app/views/projects/_dropdown.html.haml index 2d5120f283..3cdbbb7b04 100644 --- a/app/views/projects/_dropdown.html.haml +++ b/app/views/projects/_dropdown.html.haml @@ -15,7 +15,7 @@ %li = link_to new_namespace_project_snippet_path(@project.namespace, @project), title: "New Snippet" do New snippet - - if can?(current_user, :admin_team_member, @project) + - if can?(current_user, :admin_project_member, @project) %li = link_to new_namespace_project_team_member_path(@project.namespace, @project), title: "New project member" do New project member diff --git a/app/views/projects/_settings_nav.html.haml b/app/views/projects/_settings_nav.html.haml index 7fc3d44034..6f19206b17 100644 --- a/app/views/projects/_settings_nav.html.haml +++ b/app/views/projects/_settings_nav.html.haml @@ -4,8 +4,8 @@ %i.fa.fa-pencil-square-o %span Project - = nav_link(controller: [:team_members, :teams]) do = link_to namespace_project_team_index_path(@project.namespace, @project), title: 'Members', class: "team-tab tab" do + = nav_link(controller: [:project_members, :teams]) do %i.fa.fa-users %span Members diff --git a/config/routes.rb b/config/routes.rb index 889995e92a..547d1aa866 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -136,7 +136,7 @@ Gitlab::Application.routes.draw do resources :groups, constraints: { id: /[^\/]+/ } do member do - put :project_teams_update + put :members_update end end @@ -445,7 +445,7 @@ Gitlab::Application.routes.draw do end end - resources :team_members, except: [:index, :edit], constraints: { id: /[a-zA-Z.\/0-9_\-#%+]+/ } do + resources :project_members, except: [:new, :edit], constraints: { id: /[a-zA-Z.\/0-9_\-#%+]+/ } do collection do delete :leave diff --git a/features/steps/admin/groups.rb b/features/steps/admin/groups.rb index 6bcec48be8..721460b937 100644 --- a/features/steps/admin/groups.rb +++ b/features/steps/admin/groups.rb @@ -38,7 +38,7 @@ class Spinach::Features::AdminGroups < Spinach::FeatureSteps When 'I select user "John Doe" from user list as "Reporter"' do select2(user_john.id, from: "#user_ids", multiple: true) - within "#new_team_member" do + within "#new_project_member" do select "Reporter", from: "access_level" end click_button "Add users to group" diff --git a/lib/api/project_members.rb b/lib/api/project_members.rb index 73cf062155..c756bb479f 100644 --- a/lib/api/project_members.rb +++ b/lib/api/project_members.rb @@ -46,19 +46,19 @@ module API required_attributes! [:user_id, :access_level] # either the user is already a team member or a new one - team_member = user_project.team_member_by_id(params[:user_id]) - if team_member.nil? - team_member = user_project.project_members.new( + project_member = user_project.project_member_by_id(params[:user_id]) + if project_member.nil? + project_member = user_project.project_members.new( user_id: params[:user_id], access_level: params[:access_level] ) end - if team_member.save - @member = team_member.user + if project_member.save + @member = project_member.user present @member, with: Entities::ProjectMember, project: user_project else - handle_member_errors team_member.errors + handle_member_errors project_member.errors end end @@ -74,14 +74,14 @@ module API authorize! :admin_project, user_project required_attributes! [:access_level] - team_member = user_project.project_members.find_by(user_id: params[:user_id]) - not_found!("User can not be found") if team_member.nil? + project_member = user_project.project_members.find_by(user_id: params[:user_id]) + not_found!("User can not be found") if project_member.nil? - if team_member.update_attributes(access_level: params[:access_level]) - @member = team_member.user + if project_member.update_attributes(access_level: params[:access_level]) + @member = project_member.user present @member, with: Entities::ProjectMember, project: user_project else - handle_member_errors team_member.errors + handle_member_errors project_member.errors end end @@ -94,9 +94,9 @@ module API # DELETE /projects/:id/members/:user_id delete ":id/members/:user_id" do authorize! :admin_project, user_project - team_member = user_project.project_members.find_by(user_id: params[:user_id]) - unless team_member.nil? - team_member.destroy + project_member = user_project.project_members.find_by(user_id: params[:user_id]) + unless project_member.nil? + project_member.destroy else { message: "Access revoked", id: params[:user_id].to_i } end diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb index 2dfa18da48..c3a8d90ef5 100644 --- a/lib/gitlab/markdown.rb +++ b/lib/gitlab/markdown.rb @@ -200,7 +200,7 @@ module Gitlab def reference_user(identifier, project = @project, _ = nil) options = html_options.merge( - class: "gfm gfm-team_member #{html_options[:class]}" + class: "gfm gfm-project_member #{html_options[:class]}" ) if identifier == "all" diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb index fd80c61522..6ba27b536e 100644 --- a/spec/helpers/gitlab_markdown_helper_spec.rb +++ b/spec/helpers/gitlab_markdown_helper_spec.rb @@ -180,7 +180,7 @@ describe GitlabMarkdownHelper do end it "should include standard gfm classes" do - expect(gfm(actual)).to match(/class="\s?gfm gfm-team_member\s?"/) + expect(gfm(actual)).to match(/class="\s?gfm gfm-project_member\s?"/) end end diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb index 4308a765b5..d9bd91f599 100644 --- a/spec/routing/project_routing_spec.rb +++ b/spec/routing/project_routing_spec.rb @@ -338,17 +338,14 @@ describe Projects::CommitsController, 'routing' do end end -# project_team_members GET /:project_id/team_members(.:format) team_members#index -# POST /:project_id/team_members(.:format) team_members#create -# new_project_team_member GET /:project_id/team_members/new(.:format) team_members#new -# edit_project_team_member GET /:project_id/team_members/:id/edit(.:format) team_members#edit -# project_team_member GET /:project_id/team_members/:id(.:format) team_members#show -# PUT /:project_id/team_members/:id(.:format) team_members#update -# DELETE /:project_id/team_members/:id(.:format) team_members#destroy -describe Projects::TeamMembersController, 'routing' do +# project_project_members GET /:project_id/project_members(.:format) project_members#index +# POST /:project_id/project_members(.:format) project_members#create +# PUT /:project_id/project_members/:id(.:format) project_members#update +# DELETE /:project_id/project_members/:id(.:format) project_members#destroy +describe Projects::ProjectMembersController, 'routing' do it_behaves_like 'RESTful project resources' do - let(:actions) { [:new, :create, :update, :destroy] } - let(:controller) { 'team_members' } + let(:actions) { [:index, :create, :update, :destroy] } + let(:controller) { 'project_members' } end end From bbdf23261c00de58b18948381b0cc206e7d3501f Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 13 Mar 2015 16:23:45 +0100 Subject: [PATCH 52/75] Use `member` instead of `tm`. --- app/models/project_team.rb | 42 ++++++++++++++-------------- app/services/notification_service.rb | 24 ++++++++-------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/app/models/project_team.rb b/app/models/project_team.rb index bc9c3ce58f..d4a07caf9e 100644 --- a/app/models/project_team.rb +++ b/app/models/project_team.rb @@ -31,16 +31,16 @@ class ProjectTeam user end - def find_tm(user_id) - tm = project.project_members.find_by(user_id: user_id) + def find_member(user_id) + member = project.project_members.find_by(user_id: user_id) # If user is not in project members # we should check for group membership - if group && !tm - tm = group.group_members.find_by(user_id: user_id) + if group && !member + member = group.group_members.find_by(user_id: user_id) end - tm + member end def add_user(user, access) @@ -91,24 +91,24 @@ class ProjectTeam def import(source_project) target_project = project - source_team = source_project.project_members.to_a + source_members = source_project.project_members.to_a target_user_ids = target_project.project_members.pluck(:user_id) - source_team.reject! do |tm| + source_members.reject! do |member| # Skip if user already present in team - target_user_ids.include?(tm.user_id) + target_user_ids.include?(member.user_id) end - source_team.map! do |tm| - new_tm = tm.dup - new_tm.id = nil - new_tm.source = target_project - new_tm + source_members.map! do |member| + new_member = member.dup + new_member.id = nil + new_member.source = target_project + new_member end ProjectMember.transaction do - source_team.each do |tm| - tm.save + source_members.each do |member| + member.save end end @@ -118,26 +118,26 @@ class ProjectTeam end def guest?(user) - max_tm_access(user.id) == Gitlab::Access::GUEST + max_member_access(user.id) == Gitlab::Access::GUEST end def reporter?(user) - max_tm_access(user.id) == Gitlab::Access::REPORTER + max_member_access(user.id) == Gitlab::Access::REPORTER end def developer?(user) - max_tm_access(user.id) == Gitlab::Access::DEVELOPER + max_member_access(user.id) == Gitlab::Access::DEVELOPER end def master?(user) - max_tm_access(user.id) == Gitlab::Access::MASTER + max_member_access(user.id) == Gitlab::Access::MASTER end def member?(user_id) - !!find_tm(user_id) + !!find_member(user_id) end - def max_tm_access(user_id) + def max_member_access(user_id) access = [] access << project.project_members.find_by(user_id: user_id).try(:access_field) diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index fb5baaf74b..fb411c3e23 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -273,20 +273,20 @@ class NotificationService users.reject do |user| next user.notification.disabled? unless project - tm = project.project_members.find_by(user_id: user.id) + member = project.project_members.find_by(user_id: user.id) - if !tm && project.group - tm = project.group.group_members.find_by(user_id: user.id) + if !member && project.group + member = project.group.group_members.find_by(user_id: user.id) end # reject users who globally disabled notification and has no membership - next user.notification.disabled? unless tm + next user.notification.disabled? unless member # reject users who disabled notification in project - next true if tm.notification.disabled? + next true if member.notification.disabled? # reject users who have N_GLOBAL in project and disabled in global settings - tm.notification.global? && user.notification.disabled? + member.notification.global? && user.notification.disabled? end end @@ -297,20 +297,20 @@ class NotificationService users.reject do |user| next user.notification.mention? unless project - tm = project.project_members.find_by(user_id: user.id) + member = project.project_members.find_by(user_id: user.id) - if !tm && project.group - tm = project.group.group_members.find_by(user_id: user.id) + if !member && project.group + member = project.group.group_members.find_by(user_id: user.id) end # reject users who globally set mention notification and has no membership - next user.notification.mention? unless tm + next user.notification.mention? unless member # reject users who set mention notification in project - next true if tm.notification.mention? + next true if member.notification.mention? # reject users who have N_MENTION in project and disabled in global settings - tm.notification.global? && user.notification.mention? + member.notification.global? && user.notification.mention? end end From e97cdb042d941c989b303137c42e4c22f535f36b Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 13 Mar 2015 16:23:59 +0100 Subject: [PATCH 53/75] Remove old team scopes. --- app/models/issue.rb | 1 - app/models/merge_request.rb | 1 - app/models/project.rb | 1 - 3 files changed, 3 deletions(-) diff --git a/app/models/issue.rb b/app/models/issue.rb index 19e43ebd78..6e10205138 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -32,7 +32,6 @@ class Issue < ActiveRecord::Base validates :project, presence: true scope :of_group, ->(group) { where(project_id: group.project_ids) } - scope :of_user_team, ->(team) { where(project_id: team.project_ids, assignee_id: team.member_ids) } scope :cared, ->(user) { where(assignee_id: user) } scope :open_for, ->(user) { opened.assigned_to(user) } diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index f758126cfe..4cbdc61229 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -115,7 +115,6 @@ class MergeRequest < ActiveRecord::Base validate :validate_fork scope :of_group, ->(group) { where("source_project_id in (:group_project_ids) OR target_project_id in (:group_project_ids)", group_project_ids: group.project_ids) } - scope :of_user_team, ->(team) { where("(source_project_id in (:team_project_ids) OR target_project_id in (:team_project_ids) AND assignee_id in (:team_member_ids))", team_project_ids: team.project_ids, team_member_ids: team.member_ids) } scope :merged, -> { with_state(:merged) } scope :by_branch, ->(branch_name) { where("(source_branch LIKE :branch) OR (target_branch LIKE :branch)", branch: branch_name) } scope :cared, ->(user) { where('assignee_id = :user OR author_id = :user', user: user.id) } diff --git a/app/models/project.rb b/app/models/project.rb index f0b416c8f4..1d1ae569fc 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -157,7 +157,6 @@ class Project < ActiveRecord::Base scope :without_user, ->(user) { where('projects.id NOT IN (:ids)', ids: user.authorized_projects.map(&:id) ) } scope :without_team, ->(team) { team.projects.present? ? where('projects.id NOT IN (:ids)', ids: team.projects.map(&:id)) : scoped } scope :not_in_group, ->(group) { where('projects.id NOT IN (:ids)', ids: group.project_ids ) } - scope :in_team, ->(team) { where('projects.id IN (:ids)', ids: team.projects.map(&:id)) } scope :in_namespace, ->(namespace) { where(namespace_id: namespace.id) } scope :in_group_namespace, -> { joins(:group) } scope :personal, ->(user) { where(namespace_id: user.namespace_id) } From 75aff0f79c73ccc430a8c92b2317d114a5c8b24d Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 13 Mar 2015 16:25:54 +0100 Subject: [PATCH 54/75] Move project members index from `/team` to `/project_members` --- app/views/admin/projects/show.html.haml | 2 +- app/views/projects/_settings_nav.html.haml | 2 +- config/routes.rb | 1 - features/steps/shared/paths.rb | 2 +- spec/features/security/project/internal_access_spec.rb | 4 ++-- spec/features/security/project/private_access_spec.rb | 4 ++-- spec/features/security/project/public_access_spec.rb | 4 ++-- 7 files changed, 9 insertions(+), 10 deletions(-) diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml index 70ebc9561d..077ee56908 100644 --- a/app/views/admin/projects/show.html.haml +++ b/app/views/admin/projects/show.html.haml @@ -111,7 +111,7 @@ %small (#{@project.users.count}) .pull-right - = link_to namespace_project_team_index_path(@project.namespace, @project), class: "btn btn-xs" do + = link_to namespace_project_project_members_path(@project.namespace, @project), class: "btn btn-xs" do %i.fa.fa-pencil-square-o Manage Access %ul.well-list.project_members diff --git a/app/views/projects/_settings_nav.html.haml b/app/views/projects/_settings_nav.html.haml index 6f19206b17..281a84a3d3 100644 --- a/app/views/projects/_settings_nav.html.haml +++ b/app/views/projects/_settings_nav.html.haml @@ -4,8 +4,8 @@ %i.fa.fa-pencil-square-o %span Project - = link_to namespace_project_team_index_path(@project.namespace, @project), title: 'Members', class: "team-tab tab" do = nav_link(controller: [:project_members, :teams]) do + = link_to namespace_project_project_members_path(@project.namespace, @project), title: 'Members', class: "team-tab tab" do %i.fa.fa-users %span Members diff --git a/config/routes.rb b/config/routes.rb index 547d1aa866..1b7ae09c77 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -425,7 +425,6 @@ Gitlab::Application.routes.draw do end end - resources :team, controller: 'team_members', only: [:index] resources :milestones, except: [:destroy], constraints: { id: /\d+/ } do member do put :sort_issues diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index bb6c336d7c..77a90e80d1 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -386,7 +386,7 @@ module SharedPaths end step 'I visit project "Shop" team page' do - visit namespace_project_team_index_path(project.namespace, project) + visit namespace_project_project_members_path(project.namespace, project) end step 'I visit project wiki page' do diff --git a/spec/features/security/project/internal_access_spec.rb b/spec/features/security/project/internal_access_spec.rb index 322697bced..8d1bfd2522 100644 --- a/spec/features/security/project/internal_access_spec.rb +++ b/spec/features/security/project/internal_access_spec.rb @@ -79,8 +79,8 @@ describe "Internal Project Access", feature: true do it { is_expected.to be_denied_for :visitor } end - describe "GET /:project_path/team" do - subject { namespace_project_team_index_path(project.namespace, project) } + describe "GET /:project_path/project_members" do + subject { namespace_project_project_members_path(project.namespace, project) } it { is_expected.to be_allowed_for master } it { is_expected.to be_denied_for reporter } diff --git a/spec/features/security/project/private_access_spec.rb b/spec/features/security/project/private_access_spec.rb index ea146c3f0e..9021ff3318 100644 --- a/spec/features/security/project/private_access_spec.rb +++ b/spec/features/security/project/private_access_spec.rb @@ -79,8 +79,8 @@ describe "Private Project Access", feature: true do it { is_expected.to be_denied_for :visitor } end - describe "GET /:project_path/team" do - subject { namespace_project_team_index_path(project.namespace, project) } + describe "GET /:project_path/project_members" do + subject { namespace_project_project_members_path(project.namespace, project) } it { is_expected.to be_allowed_for master } it { is_expected.to be_denied_for reporter } diff --git a/spec/features/security/project/public_access_spec.rb b/spec/features/security/project/public_access_spec.rb index 8ee9199ff2..6ec190ed77 100644 --- a/spec/features/security/project/public_access_spec.rb +++ b/spec/features/security/project/public_access_spec.rb @@ -84,8 +84,8 @@ describe "Public Project Access", feature: true do it { is_expected.to be_allowed_for :visitor } end - describe "GET /:project_path/team" do - subject { namespace_project_team_index_path(project.namespace, project) } + describe "GET /:project_path/project_members" do + subject { namespace_project_project_members_path(project.namespace, project) } it { is_expected.to be_allowed_for master } it { is_expected.to be_denied_for reporter } From 224187ffb96283cbf42953a30c116931c03562a2 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 13 Mar 2015 16:27:51 +0100 Subject: [PATCH 55/75] Move group members index from `/members` to `/group_members`. --- app/assets/javascripts/dispatcher.js.coffee | 2 +- .../groups/application_controller.rb | 18 +++++++++++++++ .../groups/group_members_controller.rb | 23 +++++++++++++++---- app/controllers/groups_controller.rb | 15 +----------- .../_new_group_member.html.haml | 4 ++-- .../index.html.haml} | 4 +++- app/views/layouts/nav/_group.html.haml | 4 ++-- config/routes.rb | 5 ++-- features/steps/explore/groups.rb | 2 +- features/steps/shared/paths.rb | 4 ++-- .../security/group/group_access_spec.rb | 4 ++-- .../group/internal_group_access_spec.rb | 4 ++-- .../security/group/mixed_group_access_spec.rb | 4 ++-- .../group/public_group_access_spec.rb | 4 ++-- 14 files changed, 60 insertions(+), 37 deletions(-) rename app/views/groups/{ => group_members}/_new_group_member.html.haml (71%) rename app/views/groups/{members.html.haml => group_members/index.html.haml} (92%) diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee index 5da774cfb2..4dce6e66ce 100644 --- a/app/assets/javascripts/dispatcher.js.coffee +++ b/app/assets/javascripts/dispatcher.js.coffee @@ -73,7 +73,7 @@ class Dispatcher new Activities() shortcut_handler = new ShortcutsNavigation() new ProjectsList() - when 'groups:members' + when 'groups:group_members:index' new GroupMembers() new UsersSelect() when 'groups:new', 'groups:edit', 'admin:groups:edit' diff --git a/app/controllers/groups/application_controller.rb b/app/controllers/groups/application_controller.rb index 7f27f2bb73..a73b8fa212 100644 --- a/app/controllers/groups/application_controller.rb +++ b/app/controllers/groups/application_controller.rb @@ -2,9 +2,27 @@ class Groups::ApplicationController < ApplicationController private + def authorize_read_group! + unless @group and can?(current_user, :read_group, @group) + if current_user.nil? + return authenticate_user! + else + return render_404 + end + end + end + def authorize_admin_group! unless can?(current_user, :manage_group, group) return render_404 end end + + def determine_layout + if current_user + 'group' + else + 'public_group' + end + end end diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb index 132452d61c..d3d6ce1ca2 100644 --- a/app/controllers/groups/group_members_controller.rb +++ b/app/controllers/groups/group_members_controller.rb @@ -1,15 +1,30 @@ class Groups::GroupMembersController < Groups::ApplicationController + skip_before_filter :authenticate_user!, only: [:index] before_filter :group # Authorize - before_filter :authorize_admin_group! + before_filter :authorize_read_group! + before_filter :authorize_admin_group!, except: [:index, :leave] - layout 'group' + layout :determine_layout + + def index + @project = @group.projects.find(params[:project_id]) if params[:project_id] + @members = @group.group_members + + if params[:search].present? + users = @group.users.search(params[:search]).to_a + @members = @members.where(user_id: users) + end + + @members = @members.order('access_level DESC').page(params[:page]).per(50) + @group_member = GroupMember.new + end def create @group.add_users(params[:user_ids].split(','), params[:access_level]) - redirect_to members_group_path(@group), notice: 'Users were successfully added.' + redirect_to group_group_members_path(@group), notice: 'Users were successfully added.' end def update @@ -23,7 +38,7 @@ class Groups::GroupMembersController < Groups::ApplicationController if can?(current_user, :destroy_group_member, @group_member) # May fail if last owner. @group_member.destroy respond_to do |format| - format.html { redirect_to members_group_path(@group), notice: 'User was successfully removed from group.' } + format.html { redirect_to group_group_members_path(@group), notice: 'User was successfully removed from group.' } format.js { render nothing: true } end else diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 7e336803fb..7af3c07718 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -1,5 +1,5 @@ class GroupsController < Groups::ApplicationController - skip_before_filter :authenticate_user!, only: [:show, :issues, :members, :merge_requests] + skip_before_filter :authenticate_user!, only: [:show, :issues, :merge_requests] respond_to :html before_filter :group, except: [:new, :create] @@ -67,19 +67,6 @@ class GroupsController < Groups::ApplicationController end end - def members - @project = group.projects.find(params[:project_id]) if params[:project_id] - @members = group.group_members - - if params[:search].present? - users = group.users.search(params[:search]).to_a - @members = @members.where(user_id: users) - end - - @members = @members.order('access_level DESC').page(params[:page]).per(50) - @users_group = GroupMember.new - end - def edit end diff --git a/app/views/groups/_new_group_member.html.haml b/app/views/groups/group_members/_new_group_member.html.haml similarity index 71% rename from app/views/groups/_new_group_member.html.haml rename to app/views/groups/group_members/_new_group_member.html.haml index 345c0555a3..c4c29bb2e8 100644 --- a/app/views/groups/_new_group_member.html.haml +++ b/app/views/groups/group_members/_new_group_member.html.haml @@ -1,4 +1,4 @@ -= form_for @users_group, url: group_group_members_path(@group), html: { class: 'form-horizontal users-group-form' } do |f| += form_for @group_member, url: group_group_members_path(@group), html: { class: 'form-horizontal users-group-form' } do |f| .form-group = f.label :user_ids, "People", class: 'control-label' .col-sm-10= users_select_tag(:user_ids, multiple: true, class: 'input-large') @@ -6,7 +6,7 @@ .form-group = f.label :access_level, "Group Access", class: 'control-label' .col-sm-10 - = select_tag :access_level, options_for_select(GroupMember.access_level_roles, @users_group.access_level), class: "project-access-select select2" + = select_tag :access_level, options_for_select(GroupMember.access_level_roles, @group_member.access_level), class: "project-access-select select2" .help-block Read more about role permissions %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink" diff --git a/app/views/groups/members.html.haml b/app/views/groups/group_members/index.html.haml similarity index 92% rename from app/views/groups/members.html.haml rename to app/views/groups/group_members/index.html.haml index 688c22e962..0d501fe7bd 100644 --- a/app/views/groups/members.html.haml +++ b/app/views/groups/group_members/index.html.haml @@ -1,4 +1,5 @@ - show_roles = should_user_see_group_roles?(current_user, @group) + %h3.page-title Group members - if show_roles @@ -10,7 +11,7 @@ %hr .clearfix.js-toggle-container - = form_tag members_group_path(@group), method: :get, class: 'form-inline member-search-form' do + = form_tag group_group_members_path(@group), method: :get, class: 'form-inline member-search-form' do .form-group = search_field_tag :search, params[:search], { placeholder: 'Find existing member by name', class: 'form-control search-text-input input-mn-300' } = button_tag 'Search', class: 'btn' @@ -33,6 +34,7 @@ %ul.well-list - @members.each do |member| = render 'groups/group_members/group_member', member: member, show_roles: show_roles, show_controls: true + = paginate @members, theme: 'gitlab' :coffeescript diff --git a/app/views/layouts/nav/_group.html.haml b/app/views/layouts/nav/_group.html.haml index ddd3df19ee..32fe0e37df 100644 --- a/app/views/layouts/nav/_group.html.haml +++ b/app/views/layouts/nav/_group.html.haml @@ -24,8 +24,8 @@ Merge Requests - if current_user %span.count= MergeRequest.opened.of_group(@group).count - = nav_link(path: 'groups#members') do - = link_to members_group_path(@group), title: 'Members' do + = nav_link(controller: [:group_members]) do + = link_to group_group_members_path(@group), title: 'Members' do %i.fa.fa-users %span Members diff --git a/config/routes.rb b/config/routes.rb index 1b7ae09c77..459158dcb6 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -236,12 +236,13 @@ Gitlab::Application.routes.draw do member do get :issues get :merge_requests - get :members get :projects end scope module: :groups do - resources :group_members, only: [:create, :update, :destroy] + resources :group_members, only: [:index, :create, :update, :destroy] do + end + resource :avatar, only: [:destroy] resources :milestones, only: [:index, :show, :update] end diff --git a/features/steps/explore/groups.rb b/features/steps/explore/groups.rb index ccbf6cda07..0c2127d4c4 100644 --- a/features/steps/explore/groups.rb +++ b/features/steps/explore/groups.rb @@ -35,7 +35,7 @@ class Spinach::Features::ExploreGroups < Spinach::FeatureSteps end step 'I visit group "TestGroup" members page' do - visit members_group_path(Group.find_by(name: "TestGroup")) + visit group_group_members_path(Group.find_by(name: "TestGroup")) end step 'I should not see project "Enterprise" items' do diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index 77a90e80d1..e3cf1b92cd 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -32,7 +32,7 @@ module SharedPaths end step 'I visit group "Owned" members page' do - visit members_group_path(Group.find_by(name:"Owned")) + visit group_group_members_path(Group.find_by(name:"Owned")) end step 'I visit group "Owned" settings page' do @@ -52,7 +52,7 @@ module SharedPaths end step 'I visit group "Guest" members page' do - visit members_group_path(Group.find_by(name:"Guest")) + visit group_group_members_path(Group.find_by(name:"Guest")) end step 'I visit group "Guest" settings page' do diff --git a/spec/features/security/group/group_access_spec.rb b/spec/features/security/group/group_access_spec.rb index e0c5cbf4d3..6379314945 100644 --- a/spec/features/security/group/group_access_spec.rb +++ b/spec/features/security/group/group_access_spec.rb @@ -59,8 +59,8 @@ describe "Group access", feature: true do it { is_expected.to be_denied_for :visitor } end - describe "GET /groups/:path/members" do - subject { members_group_path(group) } + describe "GET /groups/:path/group_members" do + subject { group_group_members_path(group) } it { is_expected.to be_allowed_for owner } it { is_expected.to be_allowed_for master } diff --git a/spec/features/security/group/internal_group_access_spec.rb b/spec/features/security/group/internal_group_access_spec.rb index 5279a1bc13..d17a7412e4 100644 --- a/spec/features/security/group/internal_group_access_spec.rb +++ b/spec/features/security/group/internal_group_access_spec.rb @@ -55,8 +55,8 @@ describe "Group with internal project access", feature: true do it { is_expected.to be_denied_for :visitor } end - describe "GET /groups/:path/members" do - subject { members_group_path(group) } + describe "GET /groups/:path/group_members" do + subject { group_group_members_path(group) } it { is_expected.to be_allowed_for owner } it { is_expected.to be_allowed_for master } diff --git a/spec/features/security/group/mixed_group_access_spec.rb b/spec/features/security/group/mixed_group_access_spec.rb index efd14858b9..b3db7b5dea 100644 --- a/spec/features/security/group/mixed_group_access_spec.rb +++ b/spec/features/security/group/mixed_group_access_spec.rb @@ -56,8 +56,8 @@ describe "Group access", feature: true do it { is_expected.to be_allowed_for :visitor } end - describe "GET /groups/:path/members" do - subject { members_group_path(group) } + describe "GET /groups/:path/group_members" do + subject { group_group_members_path(group) } it { is_expected.to be_allowed_for owner } it { is_expected.to be_allowed_for master } diff --git a/spec/features/security/group/public_group_access_spec.rb b/spec/features/security/group/public_group_access_spec.rb index c7e3d0a8a4..c16f0c0d1e 100644 --- a/spec/features/security/group/public_group_access_spec.rb +++ b/spec/features/security/group/public_group_access_spec.rb @@ -55,8 +55,8 @@ describe "Group with public project access", feature: true do it { is_expected.to be_allowed_for :visitor } end - describe "GET /groups/:path/members" do - subject { members_group_path(group) } + describe "GET /groups/:path/group_members" do + subject { group_group_members_path(group) } it { is_expected.to be_allowed_for owner } it { is_expected.to be_allowed_for master } From 84371de01f3ce7bab334539a93734658528736ec Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 13 Mar 2015 16:28:33 +0100 Subject: [PATCH 56/75] Move group leave action from dashboard/groups to groups/group_members. --- app/controllers/dashboard/groups_controller.rb | 18 +----------------- .../groups/group_members_controller.rb | 11 +++++++++++ app/views/dashboard/groups/index.html.haml | 2 +- .../group_members/_group_member.html.haml | 5 +++-- config/routes.rb | 7 ++----- 5 files changed, 18 insertions(+), 25 deletions(-) diff --git a/app/controllers/dashboard/groups_controller.rb b/app/controllers/dashboard/groups_controller.rb index b827639978..ed14f4e1f3 100644 --- a/app/controllers/dashboard/groups_controller.rb +++ b/app/controllers/dashboard/groups_controller.rb @@ -1,21 +1,5 @@ class Dashboard::GroupsController < ApplicationController def index - @user_groups = current_user.group_members.page(params[:page]).per(PER_PAGE) - end - - def leave - @users_group = group.group_members.where(user_id: current_user.id).first - if can?(current_user, :destroy, @users_group) - @users_group.destroy - redirect_to(dashboard_groups_path, info: "You left #{group.name} group.") - else - return render_403 - end - end - - private - - def group - @group ||= Group.find_by(path: params[:id]) + @group_members = current_user.group_members.page(params[:page]).per(PER_PAGE) end end diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb index d3d6ce1ca2..2df51c97a2 100644 --- a/app/controllers/groups/group_members_controller.rb +++ b/app/controllers/groups/group_members_controller.rb @@ -46,6 +46,17 @@ class Groups::GroupMembersController < Groups::ApplicationController end end + def leave + @group_member = @group.group_members.where(user_id: current_user.id).first + + if can?(current_user, :destroy_group_member, @group_member) + @group_member.destroy + redirect_to(dashboard_groups_path, info: "You left #{group.name} group.") + else + return render_403 + end + end + protected def group diff --git a/app/views/dashboard/groups/index.html.haml b/app/views/dashboard/groups/index.html.haml index 76f7d660f3..165db214d7 100644 --- a/app/views/dashboard/groups/index.html.haml +++ b/app/views/dashboard/groups/index.html.haml @@ -23,7 +23,7 @@ Settings - if can?(current_user, :destroy_group_member, group_member) - = link_to leave_dashboard_group_path(group), data: { confirm: leave_group_message(group.name) }, method: :delete, class: "btn-sm btn btn-grouped", title: 'Remove user from group' do + = link_to leave_group_group_members_path(group), data: { confirm: leave_group_message(group.name) }, method: :delete, class: "btn-sm btn btn-grouped", title: 'Remove user from group' do %i.fa.fa-sign-out Leave diff --git a/app/views/groups/group_members/_group_member.html.haml b/app/views/groups/group_members/_group_member.html.haml index 2fc91df093..3d120c5cdd 100644 --- a/app/views/groups/group_members/_group_member.html.haml +++ b/app/views/groups/group_members/_group_member.html.haml @@ -1,6 +1,7 @@ - user = member.user - return unless user - show_roles = true if show_roles.nil? + %li{class: "#{dom_class(member)} js-toggle-container", id: dom_id(member)} %span{class: ("list-item-name" if show_controls)} = image_tag avatar_icon(user.email, 16), class: "avatar s16" @@ -21,8 +22,8 @@ title: 'Edit access level', type: 'button' do %i.fa.fa-pencil-square-o - if can?(current_user, :destroy_group_member, member) - - if current_user == member.user - = link_to leave_dashboard_group_path(@group), data: { confirm: leave_group_message(@group.name)}, method: :delete, class: "btn-xs btn btn-remove", title: 'Remove user from group' do + - if current_user == user + = link_to leave_group_group_members_path(@group), data: { confirm: leave_group_message(@group.name)}, method: :delete, class: "btn-xs btn btn-remove", title: 'Remove user from group' do %i.fa.fa-minus.fa-inverse - else = link_to group_group_member_path(@group, member), data: { confirm: remove_user_from_group_message(@group, user) }, method: :delete, remote: true, class: "btn-xs btn btn-remove", title: 'Remove user from group' do diff --git a/config/routes.rb b/config/routes.rb index 459158dcb6..dd70ad2fa0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -215,11 +215,7 @@ Gitlab::Application.routes.draw do scope module: :dashboard do resources :milestones, only: [:index, :show] - resources :groups, only: [:index] do - member do - delete :leave - end - end + resources :groups, only: [:index] resources :projects, only: [] do collection do @@ -241,6 +237,7 @@ Gitlab::Application.routes.draw do scope module: :groups do resources :group_members, only: [:index, :create, :update, :destroy] do + delete :leave, on: :collection end resource :avatar, only: [:destroy] From 5ad35bbe028c60c1281871b45619455a508f7b5b Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 13 Mar 2015 16:30:36 +0100 Subject: [PATCH 57/75] Use same layout and interactivity for project members as group members. --- app/assets/javascripts/dispatcher.js.coffee | 4 ++- .../javascripts/project_members.js.coffee | 4 +++ app/views/projects/_dropdown.html.haml | 2 +- .../project_members/_group_members.html.haml | 15 ++++++++ .../_new_project_member.html.haml | 15 ++++++++ .../project_members/_project_member.html.haml | 34 ++++++++++++++++++ .../projects/project_members/_team.html.haml | 11 ++++++ .../import.html.haml | 4 +-- .../projects/project_members/index.html.haml | 35 +++++++++++++++++++ .../projects/project_members/update.js.haml | 3 ++ .../projects/team_members/_form.html.haml | 29 --------------- .../team_members/_group_members.html.haml | 14 -------- .../projects/team_members/_team.html.haml | 9 ----- .../team_members/_team_member.html.haml | 18 ---------- .../projects/team_members/index.html.haml | 16 --------- app/views/projects/team_members/new.html.haml | 1 - .../projects/team_members/update.js.haml | 6 ---- features/project/team_management.feature | 2 +- features/steps/project/team_management.rb | 21 ++++++----- 19 files changed, 137 insertions(+), 106 deletions(-) create mode 100644 app/assets/javascripts/project_members.js.coffee create mode 100644 app/views/projects/project_members/_group_members.html.haml create mode 100644 app/views/projects/project_members/_new_project_member.html.haml create mode 100644 app/views/projects/project_members/_project_member.html.haml create mode 100644 app/views/projects/project_members/_team.html.haml rename app/views/projects/{team_members => project_members}/import.html.haml (66%) create mode 100644 app/views/projects/project_members/index.html.haml create mode 100644 app/views/projects/project_members/update.js.haml delete mode 100644 app/views/projects/team_members/_form.html.haml delete mode 100644 app/views/projects/team_members/_group_members.html.haml delete mode 100644 app/views/projects/team_members/_team.html.haml delete mode 100644 app/views/projects/team_members/_team_member.html.haml delete mode 100644 app/views/projects/team_members/index.html.haml delete mode 100644 app/views/projects/team_members/new.html.haml delete mode 100644 app/views/projects/team_members/update.js.haml diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee index 4dce6e66ce..edf482f33d 100644 --- a/app/assets/javascripts/dispatcher.js.coffee +++ b/app/assets/javascripts/dispatcher.js.coffee @@ -76,6 +76,9 @@ class Dispatcher when 'groups:group_members:index' new GroupMembers() new UsersSelect() + when 'projects:project_members:index' + new ProjectMembers() + new UsersSelect() when 'groups:new', 'groups:edit', 'admin:groups:edit' new GroupAvatar() when 'projects:tree:show' @@ -129,7 +132,6 @@ class Dispatcher shortcut_handler = new ShortcutsNavigation() when 'project_members', 'deploy_keys', 'hooks', 'services', 'protected_branches' shortcut_handler = new ShortcutsNavigation() - new UsersSelect() # If we haven't installed a custom shortcut handler, install the default one diff --git a/app/assets/javascripts/project_members.js.coffee b/app/assets/javascripts/project_members.js.coffee new file mode 100644 index 0000000000..896ba7e53e --- /dev/null +++ b/app/assets/javascripts/project_members.js.coffee @@ -0,0 +1,4 @@ +class @ProjectMembers + constructor: -> + $('li.project_member').bind 'ajax:success', -> + $(this).fadeOut() diff --git a/app/views/projects/_dropdown.html.haml b/app/views/projects/_dropdown.html.haml index 3cdbbb7b04..f4f4c2662c 100644 --- a/app/views/projects/_dropdown.html.haml +++ b/app/views/projects/_dropdown.html.haml @@ -17,7 +17,7 @@ New snippet - if can?(current_user, :admin_project_member, @project) %li - = link_to new_namespace_project_team_member_path(@project.namespace, @project), title: "New project member" do + = link_to namespace_project_project_members_path(@project.namespace, @project), title: "New project member" do New project member - if can? current_user, :push_code, @project %li.divider diff --git a/app/views/projects/project_members/_group_members.html.haml b/app/views/projects/project_members/_group_members.html.haml new file mode 100644 index 0000000000..b050be1d21 --- /dev/null +++ b/app/views/projects/project_members/_group_members.html.haml @@ -0,0 +1,15 @@ +.panel.panel-default + .panel-heading + %strong #{@group.name} + group members + %small + (#{members.count}) + .pull-right + = link_to group_group_members_path(@group), class: 'btn btn-sm' do + %i.fa.fa-pencil-square-o + %ul.well-list + - members.each do |member| + = render 'groups/group_members/group_member', member: member, show_controls: false + - if members.count > 20 + %li + and #{members.count - 20} more. For full list visit #{link_to 'group members page', group_group_members_path(@group)} diff --git a/app/views/projects/project_members/_new_project_member.html.haml b/app/views/projects/project_members/_new_project_member.html.haml new file mode 100644 index 0000000000..0f824bdabf --- /dev/null +++ b/app/views/projects/project_members/_new_project_member.html.haml @@ -0,0 +1,15 @@ += form_for @project_member, as: :project_member, url: namespace_project_project_members_path(@project.namespace, @project), html: { class: 'form-horizontal users-project-form' } do |f| + .form-group + = f.label :user_ids, "People", class: 'control-label' + .col-sm-10= users_select_tag(:user_ids, multiple: true, class: 'input-large') + + .form-group + = f.label :access_level, "Project Access", class: 'control-label' + .col-sm-10 + = select_tag :access_level, options_for_select(ProjectMember.access_roles, @project_member.access_level), class: "project-access-select select2" + .help-block + Read more about role permissions + %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink" + + .form-actions + = f.submit 'Add users to project', class: "btn btn-create" diff --git a/app/views/projects/project_members/_project_member.html.haml b/app/views/projects/project_members/_project_member.html.haml new file mode 100644 index 0000000000..57dcc322d8 --- /dev/null +++ b/app/views/projects/project_members/_project_member.html.haml @@ -0,0 +1,34 @@ +- user = member.user +- return unless user + +%li{class: "#{dom_class(member)} js-toggle-container project_member_row access-#{member.human_access.downcase}", id: dom_id(member)} + %span.list-item-name + = image_tag avatar_icon(user.email, 16), class: "avatar s16" + %strong= user.name + %span.cgray= user.username + - if user == current_user + %span.label.label-success It's you + - if user.blocked? + %label.label.label-danger + %strong Blocked + + - if current_user_can_admin_project + - unless @project.personal? && user == current_user + .pull-right + %strong= member.human_access + = button_tag class: "btn-xs btn js-toggle-button", + title: 'Edit access level', type: 'button' do + %i.fa.fa-pencil-square-o + + - if current_user == user + = link_to leave_namespace_project_project_members_path(@project.namespace, @project), data: { confirm: "Leave project?"}, method: :delete, class: "btn-xs btn btn-remove", title: 'Leave project' do + %i.fa.fa-minus.fa-inverse + - else + = link_to namespace_project_project_member_path(@project.namespace, @project, user), data: { confirm: remove_from_project_team_message(@project, user) }, method: :delete, remote: true, class: "btn-xs btn btn-remove", title: 'Remove user from team' do + %i.fa.fa-minus.fa-inverse + + .edit-member.hide.js-toggle-content + = form_for member, as: :project_member, url: namespace_project_project_member_path(@project.namespace, @project, member.user), remote: true do |f| + .alert.prepend-top-20 + = f.select :access_level, options_for_select(ProjectMember.access_roles, member.access_level) + = f.submit 'Save', class: 'btn btn-save btn-small' diff --git a/app/views/projects/project_members/_team.html.haml b/app/views/projects/project_members/_team.html.haml new file mode 100644 index 0000000000..615c425e59 --- /dev/null +++ b/app/views/projects/project_members/_team.html.haml @@ -0,0 +1,11 @@ +- can_admin_project = can?(current_user, :admin_project, @project) + +.panel.panel-default.prepend-top-20 + .panel-heading + %strong #{@project.name} + project members + %small + (#{members.count}) + %ul.well-list + - members.each do |project_member| + = render 'project_member', member: project_member, current_user_can_admin_project: can_admin_project diff --git a/app/views/projects/team_members/import.html.haml b/app/views/projects/project_members/import.html.haml similarity index 66% rename from app/views/projects/team_members/import.html.haml rename to app/views/projects/project_members/import.html.haml index 9e31d47117..293754cd0c 100644 --- a/app/views/projects/team_members/import.html.haml +++ b/app/views/projects/project_members/import.html.haml @@ -3,12 +3,12 @@ %p.light Only project members will be imported. Group members will be skipped. %hr -= form_tag apply_import_namespace_project_team_members_path(@project.namespace, @project), method: 'post', class: 'form-horizontal' do += form_tag apply_import_namespace_project_project_members_path(@project.namespace, @project), method: 'post', class: 'form-horizontal' do .form-group = label_tag :source_project_id, "Project", class: 'control-label' .col-sm-10= select_tag(:source_project_id, options_from_collection_for_select(current_user.authorized_projects, :id, :name_with_namespace), prompt: "Select project", class: "select2 lg", required: true) .form-actions = button_tag 'Import project members', class: "btn btn-create" - = link_to "Cancel", namespace_project_team_index_path(@project.namespace, @project), class: "btn btn-cancel" + = link_to "Cancel", namespace_project_project_members_path(@project.namespace, @project), class: "btn btn-cancel" diff --git a/app/views/projects/project_members/index.html.haml b/app/views/projects/project_members/index.html.haml new file mode 100644 index 0000000000..36a6f6a155 --- /dev/null +++ b/app/views/projects/project_members/index.html.haml @@ -0,0 +1,35 @@ +%h3.page-title + Users with access to this project + +%p.light + Read more about project permissions + %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink" + +%hr + +.clearfix.js-toggle-container + = form_tag namespace_project_project_members_path(@project.namespace, @project), method: :get, class: 'form-inline member-search-form' do + .form-group + = search_field_tag :search, params[:search], { placeholder: 'Find existing member by name', class: 'form-control search-text-input input-mn-300' } + = button_tag 'Search', class: 'btn' + + - if can?(current_user, :admin_project_member, @project) + %span.pull-right + = button_tag class: 'btn btn-new btn-grouped js-toggle-button', type: 'button' do + Add members + %i.fa.fa-chevron-down + = link_to import_namespace_project_project_members_path(@project.namespace, @project), class: "btn btn-grouped", title: "Import members from another project" do + Import members + + .js-toggle-content.hide.new-group-member-holder + = render "new_project_member" + += render "team", members: @project_members + +- if @group + = render "group_members", members: @group_members + +:coffeescript + $('form.member-search-form').on 'submit', (event) -> + event.preventDefault() + Turbolinks.visit @.action + '?' + $(@).serialize() diff --git a/app/views/projects/project_members/update.js.haml b/app/views/projects/project_members/update.js.haml new file mode 100644 index 0000000000..811b185882 --- /dev/null +++ b/app/views/projects/project_members/update.js.haml @@ -0,0 +1,3 @@ +- can_admin_project = can?(current_user, :admin_project, @project) +:plain + $("##{dom_id(@project_member)}").replaceWith('#{escape_javascript(render("project_member", member: @project_member, current_user_can_admin_project: can_admin_project))}'); diff --git a/app/views/projects/team_members/_form.html.haml b/app/views/projects/team_members/_form.html.haml deleted file mode 100644 index 166b6362a0..0000000000 --- a/app/views/projects/team_members/_form.html.haml +++ /dev/null @@ -1,29 +0,0 @@ -%h3.page-title - New project member(s) - -= form_for @user_project_relation, as: :project_member, url: namespace_project_team_members_path(@project.namespace, @project), html: { class: "form-horizontal users-project-form" } do |f| - -if @user_project_relation.errors.any? - .alert.alert-danger - %ul - - @user_project_relation.errors.full_messages.each do |msg| - %li= msg - - %p 1. Choose people you want in the project - .form-group - = f.label :user_ids, "People", class: 'control-label' - .col-sm-10 - = users_select_tag(:user_ids, multiple: true) - - %p 2. Set access level for them - .form-group - = f.label :access_level, "Project Access", class: 'control-label' - .col-sm-10 - = select_tag :access_level, options_for_select(Gitlab::Access.options, @user_project_relation.access_level), class: "project-access-select select2" - .help-block - Read more about role permissions - %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink" - - - .form-actions - = f.submit 'Add users', class: "btn btn-create" - = link_to "Cancel", namespace_project_team_index_path(@project.namespace, @project), class: "btn btn-cancel" diff --git a/app/views/projects/team_members/_group_members.html.haml b/app/views/projects/team_members/_group_members.html.haml deleted file mode 100644 index 12bd828a5e..0000000000 --- a/app/views/projects/team_members/_group_members.html.haml +++ /dev/null @@ -1,14 +0,0 @@ -- group_users_count = @group.group_members.count -.panel.panel-default - .panel-heading - %strong #{@group.name} - group members (#{group_users_count}) - .pull-right - = link_to members_group_path(@group), class: 'btn btn-sm' do - %i.fa.fa-pencil-square-o - %ul.well-list - - @group.group_members.order('access_level DESC').limit(20).each do |member| - = render 'groups/group_members/group_member', member: member, show_controls: false - - if group_users_count > 20 - %li - and #{group_users_count - 20} more. For full list visit #{link_to 'group members page', members_group_path(@group)} diff --git a/app/views/projects/team_members/_team.html.haml b/app/views/projects/team_members/_team.html.haml deleted file mode 100644 index 0e5b817613..0000000000 --- a/app/views/projects/team_members/_team.html.haml +++ /dev/null @@ -1,9 +0,0 @@ -.team-table - - can_admin_project = (can? current_user, :admin_project, @project) - .panel.panel-default - .panel-heading - %strong #{@project.name} - project members (#{members.count}) - %ul.well-list - - members.each do |team_member| - = render 'team_member', member: team_member, current_user_can_admin_project: can_admin_project diff --git a/app/views/projects/team_members/_team_member.html.haml b/app/views/projects/team_members/_team_member.html.haml deleted file mode 100644 index 1a755bbd56..0000000000 --- a/app/views/projects/team_members/_team_member.html.haml +++ /dev/null @@ -1,18 +0,0 @@ -- user = member.user -%li{id: dom_id(user), class: "team_member_row access-#{member.human_access.downcase}"} - .pull-right - - if current_user_can_admin_project - - unless @project.personal? && user == current_user - .pull-left - = form_for(member, as: :project_member, url: namespace_project_team_member_path(@project.namespace, @project, member.user)) do |f| - = f.select :access_level, options_for_select(ProjectMember.access_roles, member.access_level), {}, class: "trigger-submit" -   - = link_to namespace_project_team_member_path(@project.namespace, @project, user), data: { confirm: remove_from_project_team_message(@project, user)}, method: :delete, class: "btn-xs btn btn-remove", title: 'Remove user from team' do - %i.fa.fa-minus.fa-inverse - = image_tag avatar_icon(user.email, 32), class: "avatar s32" - %p - %strong= user.name - - if user.blocked? - %label.label.label-danger - %strong Blocked - %span.cgray= user.username diff --git a/app/views/projects/team_members/index.html.haml b/app/views/projects/team_members/index.html.haml deleted file mode 100644 index fcc879a58d..0000000000 --- a/app/views/projects/team_members/index.html.haml +++ /dev/null @@ -1,16 +0,0 @@ -%h3.page-title - Users with access to this project - - - if can? current_user, :admin_team_member, @project - %span.pull-right - = link_to new_namespace_project_team_member_path(@project.namespace, @project), class: "btn btn-new btn-grouped", title: "New project member" do - New project member - = link_to import_namespace_project_team_members_path(@project.namespace, @project), class: "btn btn-grouped", title: "Import members from another project" do - Import members - -%p.light - Read more about project permissions - %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink" -= render "team", members: @project_members -- if @group - = render "group_members" diff --git a/app/views/projects/team_members/new.html.haml b/app/views/projects/team_members/new.html.haml deleted file mode 100644 index b1bc3ba0eb..0000000000 --- a/app/views/projects/team_members/new.html.haml +++ /dev/null @@ -1 +0,0 @@ -= render "form" diff --git a/app/views/projects/team_members/update.js.haml b/app/views/projects/team_members/update.js.haml deleted file mode 100644 index c68fe9574a..0000000000 --- a/app/views/projects/team_members/update.js.haml +++ /dev/null @@ -1,6 +0,0 @@ -- if @user_project_relation.valid? - :plain - $("##{dom_id(@user_project_relation)}").effect("highlight", {color: "#529214"}, 1000);; -- else - :plain - $("##{dom_id(@user_project_relation)}").effect("highlight", {color: "#D12F19"}, 1000);; diff --git a/features/project/team_management.feature b/features/project/team_management.feature index 86ea6cd6e9..22393622bb 100644 --- a/features/project/team_management.feature +++ b/features/project/team_management.feature @@ -13,7 +13,7 @@ Feature: Project Team Management @javascript Scenario: Add user to project - Given I click link "New Team Member" + Given I click link "Add members" And I select "Mike" as "Reporter" Then I should see "Mike" in team list as "Reporter" diff --git a/features/steps/project/team_management.rb b/features/steps/project/team_management.rb index 7907f2a6fe..304df17d6f 100644 --- a/features/steps/project/team_management.rb +++ b/features/steps/project/team_management.rb @@ -15,18 +15,18 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps page.should have_content(user.username) end - step 'I click link "New Team Member"' do - click_link "New project member" + step 'I click link "Add members"' do + find(:css, 'a.btn-add').click end step 'I select "Mike" as "Reporter"' do user = User.find_by(name: "Mike") - select2(user.id, from: "#user_ids", multiple: true) - within "#new_project_member" do + within ".users-project-form" do + select2(user.id, from: "#user_ids", multiple: true) select "Reporter", from: "access_level" end - click_button "Add users" + click_button "Add users to project" end step 'I should see "Mike" in team list as "Reporter"' do @@ -42,8 +42,10 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps end step 'I change "Sam" role to "Reporter"' do - user = User.find_by(name: "Sam") - within "#user_#{user.id}" do + project = Project.find_by(name: "Shop") + user = User.find_by(name: 'Sam') + project_member = project.project_members.find_by(user_id: user.id) + within "#project_member_#{project_member.id}" do select "Reporter", from: "project_member_access_level" end end @@ -100,7 +102,10 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps end step 'I click cancel link for "Sam"' do - within "#user_#{User.find_by(name: 'Sam').id}" do + project = Project.find_by(name: "Shop") + user = User.find_by(name: 'Sam') + project_member = project.project_members.find_by(user_id: user.id) + within "#project_member_#{project_member.id}" do click_link('Remove user from team') end end From f66b77e6317acaaf382f2632325afc8b1413a9c7 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 13 Mar 2015 22:20:14 +0100 Subject: [PATCH 58/75] Fix failing specs. --- features/steps/project/team_management.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/features/steps/project/team_management.rb b/features/steps/project/team_management.rb index 304df17d6f..0eefe2b568 100644 --- a/features/steps/project/team_management.rb +++ b/features/steps/project/team_management.rb @@ -16,7 +16,7 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps end step 'I click link "Add members"' do - find(:css, 'a.btn-add').click + find(:css, 'button.btn-new').click end step 'I select "Mike" as "Reporter"' do @@ -46,7 +46,9 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps user = User.find_by(name: 'Sam') project_member = project.project_members.find_by(user_id: user.id) within "#project_member_#{project_member.id}" do + click_button "Edit access level" select "Reporter", from: "project_member_access_level" + click_button "Save" end end From e88d06c892eed5c50fb98eeb90d47380f47e6194 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Sun, 15 Mar 2015 13:56:32 +0100 Subject: [PATCH 59/75] Update button class. --- app/views/projects/project_members/_project_member.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/projects/project_members/_project_member.html.haml b/app/views/projects/project_members/_project_member.html.haml index 57dcc322d8..368d9419de 100644 --- a/app/views/projects/project_members/_project_member.html.haml +++ b/app/views/projects/project_members/_project_member.html.haml @@ -31,4 +31,4 @@ = form_for member, as: :project_member, url: namespace_project_project_member_path(@project.namespace, @project, member.user), remote: true do |f| .alert.prepend-top-20 = f.select :access_level, options_for_select(ProjectMember.access_roles, member.access_level) - = f.submit 'Save', class: 'btn btn-save btn-small' + = f.submit 'Save', class: 'btn btn-save btn-sm' From 584580e5156020e639b2a578c332ae92e38b3a5c Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Sun, 15 Mar 2015 13:56:56 +0100 Subject: [PATCH 60/75] Add changelog item. --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 7bc561b6e0..dd37ab0c1c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -68,6 +68,7 @@ v 7.9.0 (unreleased) - Execute hooks and services when branch or tag is created or deleted through web interface. - Block and unblock user if he/she was blocked/unblocked in Active Directory - Raise recommended number of unicorn workers from 2 to 3 + - Use same layout and interactivity for project members as group members. v 7.8.4 - Fix issue_tracker_id substitution in custom issue trackers From 3b1d5a1dffa35746d3619b90f3e82f8437e38c91 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Sun, 15 Mar 2015 15:42:31 +0100 Subject: [PATCH 61/75] Prevent gitlab-shell character encoding issues by receiving its changes as raw data. --- CHANGELOG | 1 + Gemfile | 3 +++ Gemfile.lock | 1 + app/workers/post_receive.rb | 17 ++++++++++++++++- spec/workers/post_receive_spec.rb | 18 +++++++++--------- 5 files changed, 30 insertions(+), 10 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 7bc561b6e0..6efa5f8743 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -68,6 +68,7 @@ v 7.9.0 (unreleased) - Execute hooks and services when branch or tag is created or deleted through web interface. - Block and unblock user if he/she was blocked/unblocked in Active Directory - Raise recommended number of unicorn workers from 2 to 3 + - Prevent gitlab-shell character encoding issues by receiving its changes as raw data. v 7.8.4 - Fix issue_tracker_id substitution in custom issue trackers diff --git a/Gemfile b/Gemfile index 44f024a4b8..b7b7b0a1c2 100644 --- a/Gemfile +++ b/Gemfile @@ -177,6 +177,9 @@ gem 'ace-rails-ap' # Keyboard shortcuts gem 'mousetrap-rails' +# Detect and convert string character encoding +gem 'charlock_holmes' + # Shutting down requests that take too long gem "slowpoke" diff --git a/Gemfile.lock b/Gemfile.lock index b331c29f7e..d3209ede86 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -684,6 +684,7 @@ DEPENDENCIES cal-heatmap-rails (~> 0.0.1) capybara (~> 2.2.1) carrierwave + charlock_holmes coffee-rails colored coveralls diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb index ecc6c8e53a..0c3ee6ba4f 100644 --- a/app/workers/post_receive.rb +++ b/app/workers/post_receive.rb @@ -21,7 +21,9 @@ class PostReceive return false end - changes = changes.lines if changes.kind_of?(String) + changes = Base64.decode64(changes) unless changes.include?(" ") + changes = utf8_encode_changes(changes) + changes = changes.lines changes.each do |change| oldrev, newrev, ref = change.strip.split(' ') @@ -41,6 +43,19 @@ class PostReceive end end + def utf8_encode_changes(changes) + changes = changes.dup + + changes.force_encoding("UTF-8") + return changes if changes.valid_encoding? + + # Convert non-UTF-8 branch/tag names to UTF-8 so they can be dumped as JSON. + detection = CharlockHolmes::EncodingDetector.detect(changes) + return changes unless detection && detection[:encoding] + + CharlockHolmes::Converter.convert(changes, detection[:encoding], 'UTF-8') + end + def log(message) Gitlab::GitLogger.error("POST-RECEIVE: #{message}") end diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb index 8eabc46112..df1a2b84a5 100644 --- a/spec/workers/post_receive_spec.rb +++ b/spec/workers/post_receive_spec.rb @@ -1,6 +1,10 @@ require 'spec_helper' describe PostReceive do + let(:changes) { "123456 789012 refs/heads/tést\n654321 210987 refs/tags/tag" } + let(:wrongly_encoded_changes) { changes.encode("ISO-8859-1").force_encoding("UTF-8") } + let(:base64_changes) { Base64.encode64(wrongly_encoded_changes) } + context "as a resque worker" do it "reponds to #perform" do expect(PostReceive.new).to respond_to(:perform) @@ -14,7 +18,7 @@ describe PostReceive do it "fetches the correct project" do expect(Project).to receive(:find_with_namespace).with(project.path_with_namespace).and_return(project) - PostReceive.new.perform(pwd(project), key_id, changes) + PostReceive.new.perform(pwd(project), key_id, base64_changes) end it "does not run if the author is not in the project" do @@ -22,24 +26,20 @@ describe PostReceive do expect(project).not_to receive(:execute_hooks) - expect(PostReceive.new.perform(pwd(project), key_id, changes)).to be_falsey + expect(PostReceive.new.perform(pwd(project), key_id, base64_changes)).to be_falsey end it "asks the project to trigger all hooks" do Project.stub(find_with_namespace: project) - expect(project).to receive(:execute_hooks) - expect(project).to receive(:execute_services) + expect(project).to receive(:execute_hooks).twice + expect(project).to receive(:execute_services).twice expect(project).to receive(:update_merge_requests) - PostReceive.new.perform(pwd(project), key_id, changes) + PostReceive.new.perform(pwd(project), key_id, base64_changes) end end def pwd(project) File.join(Gitlab.config.gitlab_shell.repos_path, project.path_with_namespace) end - - def changes - 'd14d6c0abdd253381df51a723d58691b2ee1ab08 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/master' - end end From 8587a2937020eca2fda3efbcf31862697e7f5b3f Mon Sep 17 00:00:00 2001 From: Vinnie Okada Date: Sun, 15 Mar 2015 12:54:36 -0600 Subject: [PATCH 62/75] Change permissions on backup files Use more restrictive permissions for backup tar files and for the db, uploads, and repositories directories inside the tar files. --- CHANGELOG | 1 + lib/backup/manager.rb | 4 +++ spec/tasks/gitlab/backup_rake_spec.rb | 50 +++++++++++++++++++++++---- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 7bc561b6e0..6eddab758e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -28,6 +28,7 @@ v 7.9.0 (unreleased) - Add a service to send updates to an Irker gateway (Romain Coltel) - Add brakeman (security scanner for Ruby on Rails) - Slack username and channel options + - Restrict permissions on backup files - Add grouped milestones from all projects to dashboard. - Web hook sends pusher email as well as commiter - Add Bitbucket omniauth provider. diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb index ab8db4e983..b499e5755b 100644 --- a/lib/backup/manager.rb +++ b/lib/backup/manager.rb @@ -17,14 +17,18 @@ module Backup file << s.to_yaml.gsub(/^---\n/,'') end + FileUtils.chmod_R(0700, %w{db uploads repositories}) + # create archive $progress.print "Creating backup archive: #{tar_file} ... " + orig_umask = File.umask(0077) if Kernel.system('tar', '-cf', tar_file, *BACKUP_CONTENTS) $progress.puts "done".green else puts "creating archive #{tar_file} failed".red abort 'Backup failed' end + File.umask(orig_umask) upload(tar_file) end diff --git a/spec/tasks/gitlab/backup_rake_spec.rb b/spec/tasks/gitlab/backup_rake_spec.rb index 60942cc95f..e6763be7b8 100644 --- a/spec/tasks/gitlab/backup_rake_spec.rb +++ b/spec/tasks/gitlab/backup_rake_spec.rb @@ -10,17 +10,17 @@ describe 'gitlab:app namespace rake task' do Rake::Task.define_task :environment end + def run_rake_task(task_name) + Rake::Task[task_name].reenable + Rake.application.invoke_task task_name + end + describe 'backup_restore' do before do # avoid writing task output to spec progress allow($stdout).to receive :write end - let :run_rake_task do - Rake::Task["gitlab:backup:restore"].reenable - Rake.application.invoke_task "gitlab:backup:restore" - end - context 'gitlab version' do before do Dir.stub glob: [] @@ -36,7 +36,9 @@ describe 'gitlab:app namespace rake task' do it 'should fail on mismatch' do YAML.stub load_file: {gitlab_version: "not #{gitlab_version}" } - expect { run_rake_task }.to raise_error SystemExit + expect { run_rake_task('gitlab:backup:restore') }.to( + raise_error SystemExit + ) end it 'should invoke restoration on mach' do @@ -44,9 +46,43 @@ describe 'gitlab:app namespace rake task' do expect(Rake::Task["gitlab:backup:db:restore"]).to receive :invoke expect(Rake::Task["gitlab:backup:repo:restore"]).to receive :invoke expect(Rake::Task["gitlab:shell:setup"]).to receive :invoke - expect { run_rake_task }.to_not raise_error + expect { run_rake_task('gitlab:backup:restore') }.to_not raise_error end end end # backup_restore task + + describe 'backup_create' do + def tars_glob + Dir.glob(File.join(Gitlab.config.backup.path, '*_gitlab_backup.tar')) + end + + before :all do + FileUtils.rm(tars_glob) + orig_stdout = $stdout + $stdout = StringIO.new + run_rake_task('gitlab:backup:create') + $stdout = orig_stdout + + @backup_tar = tars_glob.first + end + + before do + backup_path = File.join(Gitlab.config.backup.path, 'test') + allow(Gitlab.config.backup).to receive(:path).and_return(backup_path) + end + + it 'should set correct permissions on the tar file' do + expect(File.exist?(@backup_tar)).to be_truthy + expect(File::Stat.new(@backup_tar).mode.to_s(8)).to eq('100600') + end + + it 'should set correct permissions on the tar contents' do + tar_contents, exit_status = Gitlab::Popen.popen( + %W{tar -tvf #{@backup_tar} db uploads repositories} + ) + expect(exit_status).to eq(0) + expect(tar_contents).not_to match(/^.{4,9}[rwx]/) + end + end # backup_create task end # gitlab:app namespace From bacb05c554dfa8781c53c1db7a4f9a706e33fd50 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Sun, 15 Mar 2015 23:50:55 -0700 Subject: [PATCH 63/75] Small improvements to group/project member rows --- app/views/groups/group_members/_group_member.html.haml | 1 + app/views/projects/project_members/_group_members.html.haml | 3 ++- app/views/projects/project_members/_project_member.html.haml | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/views/groups/group_members/_group_member.html.haml b/app/views/groups/group_members/_group_member.html.haml index 3d120c5cdd..003025221b 100644 --- a/app/views/groups/group_members/_group_member.html.haml +++ b/app/views/groups/group_members/_group_member.html.haml @@ -22,6 +22,7 @@ title: 'Edit access level', type: 'button' do %i.fa.fa-pencil-square-o - if can?(current_user, :destroy_group_member, member) +   - if current_user == user = link_to leave_group_group_members_path(@group), data: { confirm: leave_group_message(@group.name)}, method: :delete, class: "btn-xs btn btn-remove", title: 'Remove user from group' do %i.fa.fa-minus.fa-inverse diff --git a/app/views/projects/project_members/_group_members.html.haml b/app/views/projects/project_members/_group_members.html.haml index b050be1d21..43e92437cf 100644 --- a/app/views/projects/project_members/_group_members.html.haml +++ b/app/views/projects/project_members/_group_members.html.haml @@ -4,9 +4,10 @@ group members %small (#{members.count}) - .pull-right + .panel-head-actions = link_to group_group_members_path(@group), class: 'btn btn-sm' do %i.fa.fa-pencil-square-o + Edit group members %ul.well-list - members.each do |member| = render 'groups/group_members/group_member', member: member, show_controls: false diff --git a/app/views/projects/project_members/_project_member.html.haml b/app/views/projects/project_members/_project_member.html.haml index 368d9419de..1f31d84dd1 100644 --- a/app/views/projects/project_members/_project_member.html.haml +++ b/app/views/projects/project_members/_project_member.html.haml @@ -20,13 +20,14 @@ title: 'Edit access level', type: 'button' do %i.fa.fa-pencil-square-o +   - if current_user == user = link_to leave_namespace_project_project_members_path(@project.namespace, @project), data: { confirm: "Leave project?"}, method: :delete, class: "btn-xs btn btn-remove", title: 'Leave project' do %i.fa.fa-minus.fa-inverse - else = link_to namespace_project_project_member_path(@project.namespace, @project, user), data: { confirm: remove_from_project_team_message(@project, user) }, method: :delete, remote: true, class: "btn-xs btn btn-remove", title: 'Remove user from team' do %i.fa.fa-minus.fa-inverse - + .edit-member.hide.js-toggle-content = form_for member, as: :project_member, url: namespace_project_project_member_path(@project.namespace, @project, member.user), remote: true do |f| .alert.prepend-top-20 From 67f55d9b25b079f2123284b73a525013286ea588 Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Thu, 12 Mar 2015 11:30:46 +0100 Subject: [PATCH 64/75] Let the server fix unconfigured git --- CHANGELOG | 1 + lib/tasks/gitlab/check.rake | 25 +++++++++++++++---------- lib/tasks/gitlab/task_helpers.rake | 16 ++++++++++++++++ 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index dd37ab0c1c..ad757cd28f 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.9.0 (unreleased) - Update documentation for object_kind field in Webhook push and tag push Webhooks (Stan Hu) - Fix broken email images (Hannes Rosenögger) + - Automaticly config git if user forgot, where possible - Fix mass SQL statements on initial push (Hannes Rosenögger) - Add tag push notifications and normalize HipChat and Slack messages to be consistent (Stan Hu) - Add comment notification events to HipChat and Slack services (Stan Hu) diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index 976c4b5f22..d791b7155f 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -329,16 +329,20 @@ namespace :gitlab do if correct_options.all? puts "yes".green else - puts "no".red - try_fixing_it( - sudo_gitlab("\"#{Gitlab.config.git.bin_path}\" config --global user.name \"#{options["user.name"]}\""), - sudo_gitlab("\"#{Gitlab.config.git.bin_path}\" config --global user.email \"#{options["user.email"]}\""), - sudo_gitlab("\"#{Gitlab.config.git.bin_path}\" config --global core.autocrlf \"#{options["core.autocrlf"]}\"") - ) - for_more_information( - see_installation_guide_section "GitLab" - ) - fix_and_rerun + print "Trying to fix Git error automatically. ..." + if auto_fix_git_config(options) + puts "Success".green + else + puts "Failed".red + try_fixing_it( + sudo_gitlab("\"#{Gitlab.config.git.bin_path}\" config --global user.name \"#{options["user.name"]}\""), + sudo_gitlab("\"#{Gitlab.config.git.bin_path}\" config --global user.email \"#{options["user.email"]}\""), + sudo_gitlab("\"#{Gitlab.config.git.bin_path}\" config --global core.autocrlf \"#{options["core.autocrlf"]}\"") + ) + for_more_information( + see_installation_guide_section "GitLab" + ) + end end end end @@ -806,3 +810,4 @@ namespace :gitlab do end end end + diff --git a/lib/tasks/gitlab/task_helpers.rake b/lib/tasks/gitlab/task_helpers.rake index da61c6e007..14a130be2c 100644 --- a/lib/tasks/gitlab/task_helpers.rake +++ b/lib/tasks/gitlab/task_helpers.rake @@ -112,4 +112,20 @@ namespace :gitlab do @warned_user_not_gitlab = true end end + + # Tries to configure git itself + # + # Returns true if all subcommands were successfull (according to their exit code) + # Returns false if any or all subcommands failed. + def auto_fix_git_config(options) + if !@warned_user_not_gitlab && options['user.email'] != 'example@example.com' # default email should be overridden? + command_success = options.map do |name, value| + system(%W(#{Gitlab.config.git.bin_path} config --global #{name} #{value})) + end + + command_success.all? + else + false + end + end end From 055457360c6316e9a10dfc8ee18ef8c87655d8ad Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Mon, 16 Mar 2015 08:09:31 -0700 Subject: [PATCH 65/75] Add HipChat integration documentation as this was a source of confusion --- CHANGELOG | 1 + doc/project_services/hipchat.md | 54 ++++++++++++++++++++++++ doc/project_services/project_services.md | 2 +- 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 doc/project_services/hipchat.md diff --git a/CHANGELOG b/CHANGELOG index dd37ab0c1c..e04f24d18e 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.9.0 (unreleased) + - Add HipChat integration documentation (Stan Hu) - Update documentation for object_kind field in Webhook push and tag push Webhooks (Stan Hu) - Fix broken email images (Hannes Rosenögger) - Fix mass SQL statements on initial push (Hannes Rosenögger) diff --git a/doc/project_services/hipchat.md b/doc/project_services/hipchat.md new file mode 100644 index 0000000000..021a93a288 --- /dev/null +++ b/doc/project_services/hipchat.md @@ -0,0 +1,54 @@ +# Atlassian HipChat + +GitLab provides a way to send HipChat notifications upon a number of events, +such as when a user pushes code, creates a branch or tag, adds a comment, and +creates a merge request. + +## Setup + +GitLab requires the use of a HipChat v2 API token to work. v1 tokens are +not supported at this time. Note the differences between v1 and v2 tokens: + +HipChat v1 API (legacy) supports "API Auth Tokens" in the Group API menu. A v1 +token is allowed to send messages to *any* room. + +HipChat v2 API has tokens that are can be created using the Integrations tab +in the Group or Room admin page. By design, these are lightweight tokens that +allow GitLab to send messages only to *one* room. + +### Complete these steps in HipChat: + +1. Go to: https://admin.hipchat.com/admin +1. Click on "Group Admin" -> "Integrations". +1. Find "Build Your Own!" and click "Create". +1. Select the desired room, name the integration "GitLab", and click "Create". +1. In the "Send messages to this room by posting this URL" column, you should +see a URL in the format: + +``` + https://api.hipchat.com/v2/room//notification?auth_token= +``` + +HipChat is now ready to accept messages from GitLab. Next, set up the HipChat +service in GitLab. + +### Complete these steps in GitLab: + +1. Navigate to the project you want to configure for notifications. +1. Select "Settings" in the top navigation. +1. Select "Services" in the left navigation. +1. Click "HipChat". +1. Select the "Active" checkbox. +1. Insert the `token` field from the URL into the `Token` field on the Web page. +1. Insert the `room` field from the URL into the `Room` field on the Web page. +1. Save or optionally click "Test Settings". + +## Troubleshooting + +If you do not see notifications, make sure you are using a HipChat v2 API +token, not a v1 token. + +Note that the v2 token is tied to a specific room. If you want to be able to +specify arbitrary rooms, you can create an API token for a specific user in +HipChat under "Account settings" and "API access". Use the `XXX` value under +`auth_token=XXX`. diff --git a/doc/project_services/project_services.md b/doc/project_services/project_services.md index 86eda341d6..8510fcf031 100644 --- a/doc/project_services/project_services.md +++ b/doc/project_services/project_services.md @@ -12,7 +12,7 @@ __Project integrations with external services for continuous integration and mor - Flowdock - Gemnasium - GitLab CI -- HipChat +- [HipChat](hipchat.md) An Atlassian product for private group chat and instant message. - [Irker](irker.md) An IRC gateway to receive messages on repository updates. - Pivotal Tracker - Pushover From 37973ef61b9c4dc8624bce79441113b35fa28e8e Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Mon, 16 Mar 2015 09:39:43 -0700 Subject: [PATCH 66/75] Fix typo for HipChat doc: messaging, not message --- doc/project_services/project_services.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/project_services/project_services.md b/doc/project_services/project_services.md index 8510fcf031..03937d2072 100644 --- a/doc/project_services/project_services.md +++ b/doc/project_services/project_services.md @@ -12,7 +12,7 @@ __Project integrations with external services for continuous integration and mor - Flowdock - Gemnasium - GitLab CI -- [HipChat](hipchat.md) An Atlassian product for private group chat and instant message. +- [HipChat](hipchat.md) An Atlassian product for private group chat and instant messaging. - [Irker](irker.md) An IRC gateway to receive messages on repository updates. - Pivotal Tracker - Pushover From 93e321e7c8e6c83f2b58098c514e148d8d70f79f Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Mon, 16 Mar 2015 09:46:23 -0700 Subject: [PATCH 67/75] Fix typo in CHANGELOG and add credit --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index fc56a6af13..4bb7b29948 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,7 +4,7 @@ v 7.9.0 (unreleased) - Add HipChat integration documentation (Stan Hu) - Update documentation for object_kind field in Webhook push and tag push Webhooks (Stan Hu) - Fix broken email images (Hannes Rosenögger) - - Automaticly config git if user forgot, where possible + - Automatically config git if user forgot, where possible (Zeger-Jan van de Weg) - Fix mass SQL statements on initial push (Hannes Rosenögger) - Add tag push notifications and normalize HipChat and Slack messages to be consistent (Stan Hu) - Add comment notification events to HipChat and Slack services (Stan Hu) From 7dedbfb097d1fae7a7d698ab0d3f981f8291b21e Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 16 Mar 2015 10:56:54 -0700 Subject: [PATCH 68/75] Bump gitlab-shell version --- GITLAB_SHELL_VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION index fe16b348d9..e70b4523ae 100644 --- a/GITLAB_SHELL_VERSION +++ b/GITLAB_SHELL_VERSION @@ -1 +1 @@ -2.5.4 +2.6.0 From cba6d797d756e6cc3cf976610d5d21f55e6460b5 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 16 Mar 2015 11:12:44 -0700 Subject: [PATCH 69/75] Remove ugly highlight styles --- app/assets/stylesheets/generic/forms.scss | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/assets/stylesheets/generic/forms.scss b/app/assets/stylesheets/generic/forms.scss index 5aa6f4cb66..19bc11086e 100644 --- a/app/assets/stylesheets/generic/forms.scss +++ b/app/assets/stylesheets/generic/forms.scss @@ -97,8 +97,3 @@ label { .wiki-content { margin-top: 35px; } - -.btn-group .btn.active { - text-shadow: 0 0 0.2em #D9534F, 0 0 0.2em #D9534F, 0 0 0.2em #D9534F; - background-color: #5487bf; -} From 9269606c94853c8cc0f9c850582dae09d809cdab Mon Sep 17 00:00:00 2001 From: Sytse Sijbrandij Date: Mon, 16 Mar 2015 12:09:53 -0700 Subject: [PATCH 70/75] Documentation about unicorn settings. --- doc/install/requirements.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/install/requirements.md b/doc/install/requirements.md index 65ddb3e3cf..f42af65796 100644 --- a/doc/install/requirements.md +++ b/doc/install/requirements.md @@ -76,7 +76,8 @@ Notice: The 25 workers of Sidekiq will show up as separate processes in your pro ## Unicorn Workers -It's possible to increase the amount of unicorn workers and tis will usually help for to reduce the response time of the applications. +It's possible to increase the amount of unicorn workers and tis will usually help for to reduce the response time of the applications and increase the ability to handle parallel requests. + For most instances we recommend using: CPU cores + 1 = unicorn workers. So for a machine with 2 cores, 3 unicorn workers is ideal. @@ -85,6 +86,8 @@ If you have a 512MB machine with a magnetic (non-SSD) swap drive we recommend to With one Unicorn worker only git over ssh access will work because the git over HTTP access requires two running workers (one worker to receive the user request and one worker for the authorization check). If you have a 512MB machine with a SSD drive you can use two Unicorn workers, this will allow HTTP access although it will be slow due to swapping. +To change the Unicorn workers when you have the Omnibus package please see [the Unicorn settings in the Omnibus GitLab documentation](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/unicorn.md#unicorn-settings). + ## Database If you want to run the database separately, the **recommended** database size is **1 MB per user**. From 7c3c836d3b62c72d1adf5431c0fedc91d92a8907 Mon Sep 17 00:00:00 2001 From: Vinnie Okada Date: Mon, 16 Mar 2015 13:29:27 -0600 Subject: [PATCH 71/75] Handle null restricted_visibility_levels setting Fix a 500 error when the `restricted_visibility_levels` setting is null in the database. --- app/helpers/visibility_level_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/visibility_level_helper.rb b/app/helpers/visibility_level_helper.rb index 7c090dc594..0d573e72a8 100644 --- a/app/helpers/visibility_level_helper.rb +++ b/app/helpers/visibility_level_helper.rb @@ -62,6 +62,6 @@ module VisibilityLevelHelper def restricted_visibility_levels(show_all = false) return [] if current_user.is_admin? && !show_all - current_application_settings.restricted_visibility_levels + current_application_settings.restricted_visibility_levels || [] end end From 2e672c39a09577a0a16e75a10a249c923d8ee863 Mon Sep 17 00:00:00 2001 From: Vinnie Okada Date: Mon, 16 Mar 2015 13:59:50 -0600 Subject: [PATCH 72/75] Fix restricted visibility bugs Check for nil values in the restricted_visibility_level validation method, and set the restricted visibility request parameter to `[]` when it's missing from the request. --- app/controllers/admin/application_settings_controller.rb | 4 +++- app/models/application_setting.rb | 8 +++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index 8f7d5e8006..9a5685877f 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -21,7 +21,9 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController def application_setting_params restricted_levels = params[:application_setting][:restricted_visibility_levels] - unless restricted_levels.nil? + if restricted_levels.nil? + params[:application_setting][:restricted_visibility_levels] = [] + else restricted_levels.map! do |level| level.to_i end diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 6abdf0c755..1c87db613a 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -27,9 +27,11 @@ class ApplicationSetting < ActiveRecord::Base if: :home_page_url_column_exist validates_each :restricted_visibility_levels do |record, attr, value| - value.each do |level| - unless Gitlab::VisibilityLevel.options.has_value?(level) - record.errors.add(attr, "'#{level}' is not a valid visibility level") + unless value.nil? + value.each do |level| + unless Gitlab::VisibilityLevel.options.has_value?(level) + record.errors.add(attr, "'#{level}' is not a valid visibility level") + end end end end From 8eebb6e56601738027d8c5e65c9c3bd77911e3a8 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 16 Mar 2015 13:13:02 -0700 Subject: [PATCH 73/75] Fix editor UI bug --- app/assets/stylesheets/pages/editor.scss | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/assets/stylesheets/pages/editor.scss b/app/assets/stylesheets/pages/editor.scss index 88aa256e56..851f126318 100644 --- a/app/assets/stylesheets/pages/editor.scss +++ b/app/assets/stylesheets/pages/editor.scss @@ -16,8 +16,6 @@ } } .commit-button-annotation { - @extend .alert; - @extend .alert-info; display: inline-block; margin: 0; padding: 2px; From 5c9a924fe7172f62ed359277e467c8570bda718c Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Mon, 16 Mar 2015 13:45:27 -0700 Subject: [PATCH 74/75] Add nodejs to installation doc. --- doc/install/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/install/installation.md b/doc/install/installation.md index 2b204c7247..5170f6dc0d 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -56,7 +56,7 @@ up-to-date and install it. Install the required packages (needed to compile Ruby and native extensions to Ruby gems): - sudo apt-get install -y build-essential zlib1g-dev libyaml-dev libssl-dev libgdbm-dev libreadline-dev libncurses5-dev libffi-dev curl openssh-server redis-server checkinstall libxml2-dev libxslt-dev libcurl4-openssl-dev libicu-dev logrotate python-docutils pkg-config cmake libkrb5-dev + sudo apt-get install -y build-essential zlib1g-dev libyaml-dev libssl-dev libgdbm-dev libreadline-dev libncurses5-dev libffi-dev curl openssh-server redis-server checkinstall libxml2-dev libxslt-dev libcurl4-openssl-dev libicu-dev logrotate python-docutils pkg-config cmake libkrb5-dev nodejs Make sure you have the right version of Git installed From b70e5c57c31d4cc0970c01921322d647d01e3a8b Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Mon, 16 Mar 2015 13:47:21 -0700 Subject: [PATCH 75/75] Add nodejs dependency to upgrader and upgrade from 7.7 docs --- doc/update/7.8-to-7.9.md | 120 +++++++++++++++++++++++++++++++++++++++ doc/update/upgrader.md | 2 +- 2 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 doc/update/7.8-to-7.9.md diff --git a/doc/update/7.8-to-7.9.md b/doc/update/7.8-to-7.9.md new file mode 100644 index 0000000000..28fd433e1c --- /dev/null +++ b/doc/update/7.8-to-7.9.md @@ -0,0 +1,120 @@ +# From 7.8 to 7.9 + +### 0. Stop server + + sudo service gitlab stop + +### 1. Backup + +```bash +cd /home/git/gitlab +sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production +``` + +### 2. Get latest code + +```bash +sudo -u git -H git fetch --all +sudo -u git -H git checkout -- db/schema.rb # local changes will be restored automatically +``` + +For GitLab Community Edition: + +```bash +sudo -u git -H git checkout 7-9-stable +``` + +OR + +For GitLab Enterprise Edition: + +```bash +sudo -u git -H git checkout 7-9-stable-ee +``` + +### 3. Update gitlab-shell + +```bash +cd /home/git/gitlab-shell +sudo -u git -H git fetch +sudo -u git -H git checkout v2.6.0 +``` + +### 4. Install libs, migrations, etc. + +```bash +sudo apt-get install nodejs + +cd /home/git/gitlab + +# MySQL installations (note: the line below states '--without ... postgres') +sudo -u git -H bundle install --without development test postgres --deployment + +# PostgreSQL installations (note: the line below states '--without ... mysql') +sudo -u git -H bundle install --without development test mysql --deployment + +# Run database migrations +sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production + +# Clean up assets and cache +sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production + +# Update init.d script +sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab +``` + +### 5. Update config files + +#### New configuration options for `gitlab.yml` + +There are new configuration options available for [`gitlab.yml`](config/gitlab.yml.example). View them with the command below and apply them to your current `gitlab.yml`. + +``` +git diff origin/7-8-stable:config/gitlab.yml.example origin/7-9-stable:config/gitlab.yml.example +``` + +#### Change Nginx settings + +* HTTP setups: Make `/etc/nginx/sites-available/gitlab` the same as [`lib/support/nginx/gitlab`](/lib/support/nginx/gitlab) but with your settings. +* HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as [`lib/support/nginx/gitlab-ssl`](/lib/support/nginx/gitlab-ssl) but with your settings. +* A new `location /uploads/` section has been added that needs to have the same content as the existing `location @gitlab` section. + +#### Setup time zone (optional) + +Consider setting the time zone in `gitlab.yml` otherwise GitLab will default to UTC. If you set a time zone previously in [`application.rb`](config/application.rb) (unlikely), unset it. + +### 6. Start application + + sudo service gitlab start + sudo service nginx restart + +### 7. Check application status + +Check if GitLab and its environment are configured correctly: + + sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production + +To make sure you didn't miss anything run a more thorough check with: + + sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production + +If all items are green, then congratulations upgrade is complete! + +### 8. GitHub settings (if applicable) + +If you are using GitHub as an OAuth provider for authentication, you should change the callback URL so that it +only contains a root URL (ex. `https://gitlab.example.com/`) + +## Things went south? Revert to previous version (7.8) + +### 1. Revert the code to the previous version +Follow the [upgrade guide from 7.7 to 7.8](7.7-to-7.8.md), except for the database migration +(The backup is already migrated to the previous version) + +### 2. Restore from the backup: + +```bash +cd /home/git/gitlab +sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production +``` +If you have more than one backup *.tar file(s) please add `BACKUP=timestamp_of_backup` to the command above. diff --git a/doc/update/upgrader.md b/doc/update/upgrader.md index 4ed35b2b56..d8476fb345 100644 --- a/doc/update/upgrader.md +++ b/doc/update/upgrader.md @@ -24,7 +24,7 @@ If you have local changes to your GitLab repository the script will stash them a ## 2. Run GitLab upgrade tool -Note: GitLab 7.6 adds `libkrb5-dev` as a dependency (installed by default on Ubuntu and OSX) while 7.2 adds `pkg-config` and `cmake` as dependency. Please check the dependencies in the [installation guide.](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/installation.md#1-packages-dependencies) +Note: GitLab 7.9 adds nodejs as a dependency. GitLab 7.6 adds `libkrb5-dev` as a dependency (installed by default on Ubuntu and OSX). GitLab 7.2 adds `pkg-config` and `cmake` as dependency. Please check the dependencies in the [installation guide.](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/installation.md#1-packages-dependencies) # Starting with GitLab version 7.0 upgrader script has been moved to bin directory cd /home/git/gitlab