summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamil Trzcinski <ayufan@ayufan.eu>2016-12-16 17:39:20 +0100
committerKamil Trzcinski <ayufan@ayufan.eu>2016-12-16 17:39:20 +0100
commit3f0c46a4fc7044855042ee0679d8c6eda4a3baec (patch)
tree709de66535b541f965e12545ce826e5d2f62328d
parent2577a71cc6129da00363717fd283886e0878751f (diff)
parentecd0c1757da536c5b522dad563b6621d0d5634b1 (diff)
downloadgitlab-ce-zj-kamil-slack-slash-commands-2.tar.gz
Merge remote-tracking branch 'origin/master' into zj-kamil-slack-slash-commandszj-kamil-slack-slash-commands-2
-rw-r--r--app/assets/javascripts/dispatcher.js.es62
-rw-r--r--app/assets/javascripts/issues_bulk_assignment.js.es614
-rw-r--r--app/assets/javascripts/labels_select.js2
-rw-r--r--app/assets/javascripts/render_math.js2
-rw-r--r--app/helpers/groups_helper.rb11
-rw-r--r--app/helpers/projects_helper.rb4
-rw-r--r--app/models/group.rb2
-rw-r--r--app/models/namespace.rb13
-rw-r--r--app/views/admin/groups/_group.html.haml2
-rw-r--r--app/views/admin/groups/show.html.haml2
-rw-r--r--app/views/shared/groups/_group.html.haml2
-rw-r--r--doc/administration/auth/README.md3
-rw-r--r--doc/administration/auth/img/okta_admin_panel.pngbin0 -> 26164 bytes
-rw-r--r--doc/administration/auth/img/okta_saml_settings.pngbin0 -> 25470 bytes
-rw-r--r--doc/administration/auth/okta.md160
-rw-r--r--doc/administration/high_availability/database.md6
-rw-r--r--doc/administration/high_availability/redis.md8
-rw-r--r--lib/gitlab/asciidoc.rb4
-rw-r--r--spec/features/admin/admin_active_tab_spec.rb2
-rw-r--r--spec/models/namespace_spec.rb22
20 files changed, 230 insertions, 31 deletions
diff --git a/app/assets/javascripts/dispatcher.js.es6 b/app/assets/javascripts/dispatcher.js.es6
index 1ec950494ff..1e259a16f06 100644
--- a/app/assets/javascripts/dispatcher.js.es6
+++ b/app/assets/javascripts/dispatcher.js.es6
@@ -75,7 +75,7 @@
case 'projects:issues:index':
Issuable.init();
new gl.IssuableBulkActions({
- prefixId: page === 'projects:merge_requests:index' ? 'merge_request_' : 'issue_'
+ prefixId: page === 'projects:merge_requests:index' ? 'merge_request_' : 'issue_',
});
shortcut_handler = new ShortcutsNavigation();
break;
diff --git a/app/assets/javascripts/issues_bulk_assignment.js.es6 b/app/assets/javascripts/issues_bulk_assignment.js.es6
index 1c8e5dede6f..52fd5d71b18 100644
--- a/app/assets/javascripts/issues_bulk_assignment.js.es6
+++ b/app/assets/javascripts/issues_bulk_assignment.js.es6
@@ -6,7 +6,7 @@
class IssuableBulkActions {
constructor({ container, form, issues, prefixId } = {}) {
- this.prefixId = prefixId || 'issue_';
+ this.prefixId = prefixId || 'issue_';
this.form = form || this.getElement('.bulk-update');
this.$labelDropdown = this.form.find('.js-label-select');
this.issues = issues || this.getElement('.issues-list .issue');
@@ -107,7 +107,7 @@
}
setOriginalDropdownData() {
- let $labelSelect = $('.bulk-update .js-label-select');
+ const $labelSelect = $('.bulk-update .js-label-select');
$labelSelect.data('common', this.getOriginalCommonIds());
$labelSelect.data('marked', this.getOriginalMarkedIds());
$labelSelect.data('indeterminate', this.getOriginalIndeterminateIds());
@@ -115,7 +115,7 @@
// From issuable's initial bulk selection
getOriginalCommonIds() {
- let labelIds = [];
+ const labelIds = [];
this.getElement('.selected_issue:checked').each((i, el) => {
labelIds.push(this.getElement(`#${this.prefixId}${el.dataset.id}`).data('labels'));
@@ -125,17 +125,17 @@
// From issuable's initial bulk selection
getOriginalMarkedIds() {
- var labelIds = [];
+ const labelIds = [];
this.getElement('.selected_issue:checked').each((i, el) => {
labelIds.push(this.getElement(`#${this.prefixId}${el.dataset.id}`).data('labels'));
});
- return _.intersection.apply(_, labelIds);
+ return _.intersection.apply(this, labelIds);
}
// From issuable's initial bulk selection
getOriginalIndeterminateIds() {
- let uniqueIds = [];
- let labelIds = [];
+ const uniqueIds = [];
+ const labelIds = [];
let issuableLabels = [];
// Collect unique label IDs for all checked issues
diff --git a/app/assets/javascripts/labels_select.js b/app/assets/javascripts/labels_select.js
index 6853d6b9db2..ec2fc87bece 100644
--- a/app/assets/javascripts/labels_select.js
+++ b/app/assets/javascripts/labels_select.js
@@ -8,7 +8,7 @@
var _this;
_this = this;
$('.js-label-select').each(function(i, dropdown) {
- var $block, $colorPreview, $dropdown, $form, $loading, $selectbox, $sidebarCollapsedValue, $value, abilityName, defaultLabel, enableLabelCreateButton, issueURLSplit, issueUpdateURL, labelHTMLTemplate, labelNoneHTMLTemplate, labelUrl, namespacePath, projectPath, saveLabelData, selectedLabel, showAny, showNo, $sidebarLabelTooltip, initialSelected, $toggleText, fieldName, useId, propertyName, showMenuAbove, $container;
+ var $block, $colorPreview, $dropdown, $form, $loading, $selectbox, $sidebarCollapsedValue, $value, abilityName, defaultLabel, enableLabelCreateButton, issueURLSplit, issueUpdateURL, labelHTMLTemplate, labelNoneHTMLTemplate, labelUrl, namespacePath, projectPath, saveLabelData, selectedLabel, showAny, showNo, $sidebarLabelTooltip, initialSelected, $toggleText, fieldName, useId, propertyName, showMenuAbove, $container, $dropdownContainer;
$dropdown = $(dropdown);
$dropdownContainer = $dropdown.closest('.labels-filter');
$toggleText = $dropdown.find('.dropdown-toggle-text');
diff --git a/app/assets/javascripts/render_math.js b/app/assets/javascripts/render_math.js
index a8a56430f88..209e7a8661d 100644
--- a/app/assets/javascripts/render_math.js
+++ b/app/assets/javascripts/render_math.js
@@ -1,4 +1,4 @@
-/* eslint-disable func-names, space-before-function-paren, consistent-return, no-var, no-undef, no-else-return, prefer-arrow-callback, padded-blocks, max-len */
+/* eslint-disable func-names, space-before-function-paren, consistent-return, no-var, no-undef, no-else-return, prefer-arrow-callback, padded-blocks, max-len, no-console */
// Renders math using KaTeX in any element with the
// `js-render-math` class
//
diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb
index f6d4ea4659a..77dc9e7d538 100644
--- a/app/helpers/groups_helper.rb
+++ b/app/helpers/groups_helper.rb
@@ -12,11 +12,18 @@ module GroupsHelper
end
def group_title(group, name = nil, url = nil)
- full_title = link_to(simple_sanitize(group.name), group_path(group))
+ full_title = ''
+
+ group.parents.each do |parent|
+ full_title += link_to(simple_sanitize(parent.name), group_path(parent))
+ full_title += ' / '.html_safe
+ end
+
+ full_title += link_to(simple_sanitize(group.name), group_path(group))
full_title += ' &middot; '.html_safe + link_to(simple_sanitize(name), url) if name
content_tag :span do
- full_title
+ full_title.html_safe
end
end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 9cda3b78761..d2177f683a1 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -52,7 +52,7 @@ module ProjectsHelper
def project_title(project)
namespace_link =
if project.group
- link_to(simple_sanitize(project.group.name), group_path(project.group))
+ group_title(project.group)
else
owner = project.namespace.owner
link_to(simple_sanitize(owner.name), user_path(owner))
@@ -390,7 +390,7 @@ module ProjectsHelper
"success"
end
end
-
+
def readme_cache_key
sha = @project.commit.try(:sha) || 'nil'
[@project.path_with_namespace, sha, "readme"].join('-')
diff --git a/app/models/group.rb b/app/models/group.rb
index 4248e1162d8..ac8a82c8c1e 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -83,7 +83,7 @@ class Group < Namespace
end
def human_name
- name
+ full_name
end
def visibility_level_field
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index f0479d94986..fd42f2328d8 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -161,6 +161,19 @@ class Namespace < ActiveRecord::Base
end
end
+ def full_name
+ @full_name ||=
+ if parent
+ parent.full_name + ' / ' + name
+ else
+ name
+ end
+ end
+
+ def parents
+ @parents ||= parent ? parent.parents + [parent] : []
+ end
+
private
def repository_storage_paths
diff --git a/app/views/admin/groups/_group.html.haml b/app/views/admin/groups/_group.html.haml
index 4efeec0ea4e..cf28f92853e 100644
--- a/app/views/admin/groups/_group.html.haml
+++ b/app/views/admin/groups/_group.html.haml
@@ -20,7 +20,7 @@
= image_tag group_icon(group), class: "avatar s40 hidden-xs"
.title
= link_to [:admin, group], class: 'group-name' do
- = group.name
+ = group.full_name
- if group.description.present?
.description
diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml
index 71a605f33b1..7b0175af214 100644
--- a/app/views/admin/groups/show.html.haml
+++ b/app/views/admin/groups/show.html.haml
@@ -1,6 +1,6 @@
- page_title @group.name, "Groups"
%h3.page-title
- Group: #{@group.name}
+ Group: #{@group.full_name}
= link_to admin_group_edit_path(@group), class: "btn pull-right" do
%i.fa.fa-pencil-square-o
diff --git a/app/views/shared/groups/_group.html.haml b/app/views/shared/groups/_group.html.haml
index 19221e3391f..8164f61797c 100644
--- a/app/views/shared/groups/_group.html.haml
+++ b/app/views/shared/groups/_group.html.haml
@@ -28,7 +28,7 @@
= image_tag group_icon(group), class: "avatar s40 hidden-xs"
.title
= link_to group, class: 'group-name' do
- = group.name
+ = group.full_name
- if group_member
as
diff --git a/doc/administration/auth/README.md b/doc/administration/auth/README.md
index 07e548aaabe..2fc5d0355b5 100644
--- a/doc/administration/auth/README.md
+++ b/doc/administration/auth/README.md
@@ -7,5 +7,6 @@ providers.
and 389 Server
- [OmniAuth](../../integration/omniauth.md) Sign in via Twitter, GitHub, GitLab.com, Google,
Bitbucket, Facebook, Shibboleth, Crowd and Azure
-- [SAML](../../integration/saml.md) Configure GitLab as a SAML 2.0 Service Provider
- [CAS](../../integration/cas.md) Configure GitLab to sign in using CAS
+- [SAML](../../integration/saml.md) Configure GitLab as a SAML 2.0 Service Provider
+- [Okta](okta.md) Configure GitLab to sign in using Okta
diff --git a/doc/administration/auth/img/okta_admin_panel.png b/doc/administration/auth/img/okta_admin_panel.png
new file mode 100644
index 00000000000..12e21956715
--- /dev/null
+++ b/doc/administration/auth/img/okta_admin_panel.png
Binary files differ
diff --git a/doc/administration/auth/img/okta_saml_settings.png b/doc/administration/auth/img/okta_saml_settings.png
new file mode 100644
index 00000000000..ee275ece369
--- /dev/null
+++ b/doc/administration/auth/img/okta_saml_settings.png
Binary files differ
diff --git a/doc/administration/auth/okta.md b/doc/administration/auth/okta.md
new file mode 100644
index 00000000000..cb42b7743c5
--- /dev/null
+++ b/doc/administration/auth/okta.md
@@ -0,0 +1,160 @@
+# Okta SSO provider
+
+Okta is a [Single Sign-on provider][okta-sso] that can be used to authenticate
+with GitLab.
+
+The following documentation enables Okta as a SAML provider.
+
+## Configure the Okta application
+
+1. On Okta go to the admin section and choose to **Add an App**.
+1. When the app screen comes up you see another button to **Create an App** and
+ choose SAML 2.0 on the next screen.
+1. Now, very important, add a logo
+ (you can choose it from https://about.gitlab.com/press/). You'll have to
+ crop and resize it.
+1. Next, you'll need the to fill in the SAML general config. Here's an example
+ image.
+
+ ![Okta admin panel view](img/okta_admin_panel.png)
+
+1. The last part of the configuration is the feedback section where you can
+ just say you're a customer and creating an app for internal use.
+1. When you have your app you'll have a few tabs on the top of the app's
+ profile. Click on the SAML 2.0 config instructions button which should
+ look like the following:
+
+ ![Okta SAML settings](img/okta_saml_settings.png)
+
+1. On the screen that comes up take note of the
+ **Identity Provider Single Sign-On URL** which you'll use for the
+ `idp_sso_target_url` on your GitLab config file.
+
+1. **Before you leave Okta make sure you add your user and groups if any.**
+
+---
+
+Now that the Okta app is configured, it's time to enable it in GitLab.
+
+## Configure GitLab
+
+1. On your GitLab server, open the configuration file:
+
+ **For Omnibus GitLab installations**
+
+ ```sh
+ sudo editor /etc/gitlab/gitlab.rb
+ ```
+
+ **For installations from source**
+
+ ```sh
+ cd /home/git/gitlab
+ sudo -u git -H editor config/gitlab.yml
+ ```
+
+1. See [Initial OmniAuth Configuration](../../integration/omniauth.md#initial-omniauth-configuration)
+ for initial settings.
+
+1. To allow your users to use Okta to sign up without having to manually create
+ an account first, don't forget to add the following values to your
+ configuration:
+
+ **For Omnibus GitLab installations**
+
+ ```ruby
+ gitlab_rails['omniauth_allow_single_sign_on'] = ['saml']
+ gitlab_rails['omniauth_block_auto_created_users'] = false
+ ```
+
+ **For installations from source**
+
+ ```yaml
+ allow_single_sign_on: ["saml"]
+ block_auto_created_users: false
+ ```
+
+1. You can also automatically link Okta users with existing GitLab users if
+ their email addresses match by adding the following setting:
+
+ **For Omnibus GitLab installations**
+
+ ```ruby
+ gitlab_rails['omniauth_auto_link_saml_user'] = true
+ ```
+
+ **For installations from source**
+
+ ```yaml
+ auto_link_saml_user: true
+ ```
+
+1. Add the provider configuration.
+
+ >**Notes:**
+ >- Change the value for `assertion_consumer_service_url` to match the HTTPS endpoint
+ of GitLab (append `users/auth/saml/callback` to the HTTPS URL of your GitLab
+ installation to generate the correct value).
+ >- To get the `idp_cert_fingerprint` fingerprint, first download the
+ certificate from the Okta app you registered and then run:
+ `openssl x509 -in okta.cert -noout -fingerprint`. Substitute `okta.cert`
+ with the location of your certificate.
+ >- Change the value of `idp_sso_target_url`, with the value of the
+ **Identity Provider Single Sign-On URL** from the step when you
+ configured the Okta app.
+ >- Change the value of `issuer` to a unique name, which will identify the application
+ to the IdP.
+ >- Leave `name_identifier_format` as-is.
+
+ **For Omnibus GitLab installations**
+
+ ```ruby
+ gitlab_rails['omniauth_providers'] = [
+ {
+ name: 'saml',
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://gitlab.oktapreview.com/app/gitlabdev773716_gitlabsaml_1/exk8odl81tBrjpD4B0h7/sso/saml',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'
+ },
+ label: 'Okta' # optional label for SAML login button, defaults to "Saml"
+ }
+ ]
+ ```
+
+ **For installations from source**
+
+ ```yaml
+ - {
+ name: 'saml',
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://gitlab.oktapreview.com/app/gitlabdev773716_gitlabsaml_1/exk8odl81tBrjpD4B0h7/sso/saml',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'
+ },
+ label: 'Okta' # optional label for SAML login button, defaults to "Saml"
+ }
+ ```
+
+
+1. [Reconfigure][reconf] or [restart] GitLab for Omnibus and installations
+ from source respectively for the changes to take effect.
+
+You might want to try this out on a incognito browser window.
+
+## Configuring groups
+
+>**Note:**
+Make sure the groups exist and are assigned to the Okta app.
+
+You can take a look of the [SAML documentation][saml] on external groups since
+it works the same.
+
+[okta-sso]: https://www.okta.com/products/single-sign-on/
+[saml]: ../../integration/saml.md#external-groups
+[reconf]: ../restart_gitlab.md#omnibus-gitlab-reconfigure
+[restart]: ../restart_gitlab.md#installations-from-source
diff --git a/doc/administration/high_availability/database.md b/doc/administration/high_availability/database.md
index b36cf18d459..e4f94eb7cb6 100644
--- a/doc/administration/high_availability/database.md
+++ b/doc/administration/high_availability/database.md
@@ -44,6 +44,9 @@ If you use a cloud-managed service, or provide your own PostgreSQL:
gitlab_rails['db_password'] = 'DB password'
postgresql['md5_auth_cidr_addresses'] = ['0.0.0.0/0']
postgresql['listen_address'] = '0.0.0.0'
+
+ # Disable automatic database migrations
+ gitlab_rails['auto_migrate'] = false
```
1. Run `sudo gitlab-ctl reconfigure` to install and configure PostgreSQL.
@@ -102,9 +105,6 @@ If you use a cloud-managed service, or provide your own PostgreSQL:
1. Exit the database prompt by typing `\q` and Enter.
1. Exit the `gitlab-psql` user by running `exit` twice.
1. Run `sudo gitlab-ctl reconfigure` a final time.
-1. Run `sudo touch /etc/gitlab/skip-auto-migrations` to prevent database migrations
- from running on upgrade. Only the primary GitLab application server should
- handle migrations.
---
diff --git a/doc/administration/high_availability/redis.md b/doc/administration/high_availability/redis.md
index f532a106bc6..b4e7bf21e35 100644
--- a/doc/administration/high_availability/redis.md
+++ b/doc/administration/high_availability/redis.md
@@ -287,14 +287,14 @@ The prerequisites for a HA Redis setup are the following:
redis['password'] = 'redis-password-goes-here'
```
-1. To prevent database migrations from running on upgrade, run:
+1. Only the primary GitLab application server should handle migrations. To
+ prevent database migrations from running on upgrade, add the following
+ configuration to your `/etc/gitlab/gitlab.rb` file:
```
- sudo touch /etc/gitlab/skip-auto-migrations
+ gitlab_rails['auto_migrate'] = false
```
- Only the primary GitLab application server should handle migrations.
-
1. [Reconfigure Omnibus GitLab][reconfigure] for the changes to take effect.
### Step 2. Configuring the slave Redis instances
diff --git a/lib/gitlab/asciidoc.rb b/lib/gitlab/asciidoc.rb
index f77f412da56..fa234284361 100644
--- a/lib/gitlab/asciidoc.rb
+++ b/lib/gitlab/asciidoc.rb
@@ -35,11 +35,7 @@ module Gitlab
html.html_safe
end
- end
-end
-module Gitlab
- module Asciidoc
class Html5Converter < Asciidoctor::Converter::Html5Converter
extend Asciidoctor::Converter::Config
diff --git a/spec/features/admin/admin_active_tab_spec.rb b/spec/features/admin/admin_active_tab_spec.rb
index f2eecc5b552..16064d60ce2 100644
--- a/spec/features/admin/admin_active_tab_spec.rb
+++ b/spec/features/admin/admin_active_tab_spec.rb
@@ -29,7 +29,7 @@ RSpec.describe 'admin active tab' do
context 'on projects' do
before do
- visit admin_namespaces_projects_path
+ visit admin_projects_path
end
it_behaves_like 'page has active tab', 'Overview'
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index 069c59fb5ca..9fd06bb6b23 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -128,4 +128,26 @@ describe Namespace, models: true do
it { expect(group.full_path).to eq(group.path) }
it { expect(nested_group.full_path).to eq("#{group.path}/#{nested_group.path}") }
end
+
+ describe '#full_name' do
+ let(:group) { create(:group) }
+ let(:nested_group) { create(:group, parent: group) }
+
+ it { expect(group.full_name).to eq(group.name) }
+ it { expect(nested_group.full_name).to eq("#{group.name} / #{nested_group.name}") }
+ end
+
+ describe '#parents' do
+ let(:group) { create(:group) }
+ let(:nested_group) { create(:group, parent: group) }
+ let(:deep_nested_group) { create(:group, parent: nested_group) }
+ let(:very_deep_nested_group) { create(:group, parent: deep_nested_group) }
+
+ it 'returns the correct parents' do
+ expect(very_deep_nested_group.parents).to eq([group, nested_group, deep_nested_group])
+ expect(deep_nested_group.parents).to eq([group, nested_group])
+ expect(nested_group.parents).to eq([group])
+ expect(group.parents).to eq([])
+ end
+ end
end