From 02160c6c79943e8ab2358bda4ab0899ef4e23817 Mon Sep 17 00:00:00 2001 From: Evan Read Date: Thu, 4 Apr 2019 00:55:35 +0000 Subject: [PATCH 1/7] Merge branch 'docs-google_secure_ldap' into 'master' Add documentation for Google Secure LDAP See merge request gitlab-org/gitlab-ce!26064 (cherry picked from commit 13ace389787f21b847ca09eccc194c3b08a7ea86) 1a0856ea Add documentation for Google Secure LDAP --- doc/administration/auth/google_secure_ldap.md | 207 ++++++++++++++++++ .../img/google_secure_ldap_add_step_1.png | Bin 0 -> 28849 bytes .../img/google_secure_ldap_add_step_2.png | Bin 0 -> 82115 bytes .../google_secure_ldap_client_settings.png | Bin 0 -> 63959 bytes doc/administration/auth/ldap.md | 8 + 5 files changed, 215 insertions(+) create mode 100644 doc/administration/auth/google_secure_ldap.md create mode 100644 doc/administration/auth/img/google_secure_ldap_add_step_1.png create mode 100644 doc/administration/auth/img/google_secure_ldap_add_step_2.png create mode 100644 doc/administration/auth/img/google_secure_ldap_client_settings.png diff --git a/doc/administration/auth/google_secure_ldap.md b/doc/administration/auth/google_secure_ldap.md new file mode 100644 index 00000000000..65a51fc4aa0 --- /dev/null +++ b/doc/administration/auth/google_secure_ldap.md @@ -0,0 +1,207 @@ +# Google Secure LDAP **[CORE ONLY]** + +> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/46391) in GitLab 11.9. + +[Google Cloud Identity](https://cloud.google.com/identity/) provides a Secure +LDAP service that can be configured with GitLab for authentication and group sync. + +Secure LDAP requires a slightly different configuration than standard LDAP servers. +The steps below cover: + +- Configuring the Secure LDAP Client in the Google Admin console. +- Required GitLab configuration. + +## Configuring Google LDAP client + +1. Navigate to https://admin.google.com and sign in as a GSuite domain administrator. + +1. Go to **Apps > LDAP > Add Client**. + +1. Provide an `LDAP client name` and an optional `Description`. Any descriptive + values are acceptable. For example, the name could be 'GitLab' and the + description could be 'GitLab LDAP Client'. Click the **Continue** button. + + ![Add LDAP Client Step 1](img/google_secure_ldap_add_step_1.png) + +1. Set **Access Permission** according to your needs. You must choose either + 'Entire domain (GitLab)' or 'Selected organizational units' for both 'Verify user + credentials' and 'Read user information'. Select 'Add LDAP Client' + + TIP: **Tip:** If you plan to use GitLab [LDAP Group Sync](https://docs.gitlab.com/ee/administration/auth/ldap-ee.html#group-sync) + , turn on 'Read group information'. + + ![Add LDAP Client Step 2](img/google_secure_ldap_add_step_2.png) + +1. Download the generated certificate. This is required for GitLab to + communicate with the Google Secure LDAP service. Save the downloaded certificates + for later use. After downloading, click the **Continue to Client Details** button. + +1. Expand the **Service Status** section and turn the LDAP client 'ON for everyone'. + After selecting 'Save', click on the 'Service Status' bar again to collapse + and return to the rest of the settings. + +1. Expand the **Authentication** section and choose 'Generate New Credentials'. + Copy/note these credentials for later use. After selecting 'Close', click + on the 'Authentication' bar again to collapse and return to the rest of the settings. + +Now the Google Secure LDAP Client configuration is finished. The screenshot below +shows an example of the final settings. Continue on to configure GitLab. + +![LDAP Client Settings](img/google_secure_ldap_client_settings.png) + +## Configuring GitLab + +Edit GitLab configuration, inserting the access credentials and certificate +obtained earlier. + +The following are the configuration keys that need to be modified using the +values obtained during the LDAP client configuration earlier: + +- `bind_dn`: The access credentials username +- `password`: The access credentials password +- `cert`: The `.crt` file text from the downloaded certificate bundle +- `key`: The `.key` file text from the downloaded certificate bundle + +**For Omnibus installations** + +1. Edit `/etc/gitlab/gitlab.rb`: + + ```ruby + gitlab_rails['ldap_enabled'] = true + gitlab_rails['ldap_servers'] = YAML.load <<-EOS # remember to close this block with 'EOS' below + main: # 'main' is the GitLab 'provider ID' of this LDAP server + label: 'Google Secure LDAP' + + host: 'ldap.google.com' + port: 636 + uid: 'uid' + bind_dn: 'DizzyHorse' + password: 'd6V5H8nhMUW9AuDP25abXeLd' + encryption: 'simple_tls' + verify_certificates: true + + tls_options: + cert: | + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIGAWlzxiIfMA0GCSqGSIb3DQEBCwUAMHcxFDASBgNVBAoTC0dvb2dsZSBJ + bmMuMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQDEwtMREFQIENsaWVudDEPMA0GA1UE + CxMGR1N1aXRlMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTAeFw0xOTAzMTIyMTE5 + MThaFw0yMjAzMTEyMTE5MThaMHcxFDASBgNVBAoTC0dvb2dsZSBJbmMuMRYwFAYDVQQHEw1Nb3Vu + dGFpbiBWaWV3MRQwEgYDVQQDEwtMREFQIENsaWVudDEPMA0GA1UECxMGR1N1aXRlMQswCQYDVQQG + EwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB + ALOTy4aC38dyjESk6N8fRsKk8DN23ZX/GaNFL5OUmmA1KWzrvVC881OzNdtGm3vNOIxr9clteEG/ + tQwsmsJvQT5U+GkBt+tGKF/zm7zueHUYqTP7Pg5pxAnAei90qkIRFi17ulObyRHPYv1BbCt8pxNB + 4fG/gAXkFbCNxwh1eiQXXRTfruasCZ4/mHfX7MVm8JmWU9uAVIOLW+DSWOFhrDQduJdGBXJOyC2r + Gqoeg9+tkBmNH/jjxpnEkFW8q7io9DdOUqqNgoidA1h9vpKTs3084sy2DOgUvKN9uXWx14uxIyYU + Y1DnDy0wczcsuRt7l+EgtCEgpsLiLJQbKW+JS1UCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAf60J + yazhbHkDKIH2gFxfm7QLhhnqsmafvl4WP7JqZt0u0KdnvbDPfokdkM87yfbKJU1MTI86M36wEC+1 + P6bzklKz7kXbzAD4GggksAzxsEE64OWHC+Y64Tkxq2NiZTw/76POkcg9StiIXjG0ZcebHub9+Ux/ + rTncip92nDuvgEM7lbPFKRIS/YMhLCk09B/U0F6XLsf1yYjyf5miUTDikPkov23b/YGfpc8kh6hq + 1kqdi6a1cYPP34eAhtRhMqcZU9qezpJF6s9EeN/3YFfKzLODFSsVToBRAdZgGHzj//SAtLyQTD4n + KCSvK1UmaMxNaZyTHg8JnMf0ZuRpv26iSg== + -----END CERTIFICATE----- + + key: | + -----BEGIN PRIVATE KEY----- + MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCzk8uGgt/HcoxEpOjfH0bCpPAz + dt2V/xmjRS+TlJpgNSls671QvPNTszXbRpt7zTiMa/XJbXhBv7UMLJrCb0E+VPhpAbfrRihf85u8 + 7nh1GKkz+z4OacQJwHovdKpCERYte7pTm8kRz2L9QWwrfKcTQeHxv4AF5BWwjccIdXokF10U367m + rAmeP5h31+zFZvCZllPbgFSDi1vg0ljhYaw0HbiXRgVyTsgtqxqqHoPfrZAZjR/448aZxJBVvKu4 + qPQ3TlKqjYKInQNYfb6Sk7N9POLMtgzoFLyjfbl1sdeLsSMmFGNQ5w8tMHM3LLkbe5fhILQhIKbC + 4iyUGylviUtVAgMBAAECggEAIPb0CQy0RJoX+q/lGbRVmnyJpYDf+115WNnl+mrwjdGkeZyqw4v0 + BPzkWYzUFP1esJRO6buBNFybQRFdFW0z5lvVv/zzRKq71aVUBPInxaMRyHuJ8D5lIL8nDtgVOwyE + 7DOGyDtURUMzMjdUwoTe7K+O6QBU4X/1pVPZYgmissYSMmt68LiP8k0p601F4+r5xOi/QEy44aVp + aOJZBUOisKB8BmUXZqmQ4Cy05vU9Xi1rLyzkn9s7fxnZ+JO6Sd1r0Thm1mE0yuPgxkDBh/b4f3/2 + GsQNKKKCiij/6TfkjnBi8ZvWR44LnKpu760g/K7psVNrKwqJG6C/8RAcgISWQQKBgQDop7BaKGhK + 1QMJJ/vnlyYFTucfGLn6bM//pzTys5Gop0tpcfX/Hf6a6Dd+zBhmC3tBmhr80XOX/PiyAIbc0lOI + 31rafZuD/oVx5mlIySWX35EqS14LXmdVs/5vOhsInNgNiE+EPFf1L9YZgG/zA7OUBmqtTeYIPDVC + 7ViJcydItQKBgQDFmK0H0IA6W4opGQo+zQKhefooqZ+RDk9IIZMPOAtnvOM7y3rSVrfsSjzYVuMS + w/RP/vs7rwhaZejnCZ8/7uIqwg4sdUBRzZYR3PRNFeheW+BPZvb+2keRCGzOs7xkbF1mu54qtYTa + HZGZj1OsD83AoMwVLcdLDgO1kw32dkS8IQKBgFRdgoifAHqqVah7VFB9se7Y1tyi5cXWsXI+Wufr + j9U9nQ4GojK52LqpnH4hWnOelDqMvF6TQTyLIk/B+yWWK26Ft/dk9wDdSdystd8L+dLh4k0Y+Whb + +lLMq2YABw+PeJUnqdYE38xsZVHoDjBsVjFGRmbDybeQxauYT7PACy3FAoGBAK2+k9bdNQMbXp7I + j8OszHVkJdz/WXlY1cmdDAxDwXOUGVKIlxTAf7TbiijILZ5gg0Cb+hj+zR9/oI0WXtr+mAv02jWp + W8cSOLS4TnBBpTLjIpdu+BwbnvYeLF6MmEjNKEufCXKQbaLEgTQ/XNlchBSuzwSIXkbWqdhM1+gx + EjtBAoGARAdMIiDMPWIIZg3nNnFebbmtBP0qiBsYohQZ+6i/8s/vautEHBEN6Q0brIU/goo+nTHc + t9VaOkzjCmAJSLPUanuBC8pdYgLu5J20NXUZLD9AE/2bBT3OpezKcdYeI2jqoc1qlWHlNtVtdqQ2 + AcZSFJQjdg5BTyvdEDhaYUKGdRw= + -----END PRIVATE KEY----- + EOS + ``` + +1. Save the file and [reconfigure] GitLab for the changes to take effect. + +--- + +**For installations from source** + +1. Edit `config/gitlab.yml`: + + ```yaml + ldap: + enabled: true + servers: + main: # 'main' is the GitLab 'provider ID' of this LDAP server + label: 'Google Secure LDAP' + + host: 'ldap.google.com' + port: 636 + uid: 'uid' + bind_dn: 'DizzyHorse' + password: 'd6V5H8nhMUW9AuDP25abXeLd' + encryption: 'simple_tls' + verify_certificates: true + + tls_options: + cert: | + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIGAWlzxiIfMA0GCSqGSIb3DQEBCwUAMHcxFDASBgNVBAoTC0dvb2dsZSBJ + bmMuMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQDEwtMREFQIENsaWVudDEPMA0GA1UE + CxMGR1N1aXRlMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTAeFw0xOTAzMTIyMTE5 + MThaFw0yMjAzMTEyMTE5MThaMHcxFDASBgNVBAoTC0dvb2dsZSBJbmMuMRYwFAYDVQQHEw1Nb3Vu + dGFpbiBWaWV3MRQwEgYDVQQDEwtMREFQIENsaWVudDEPMA0GA1UECxMGR1N1aXRlMQswCQYDVQQG + EwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB + ALOTy4aC38dyjESk6N8fRsKk8DN23ZX/GaNFL5OUmmA1KWzrvVC881OzNdtGm3vNOIxr9clteEG/ + tQwsmsJvQT5U+GkBt+tGKF/zm7zueHUYqTP7Pg5pxAnAei90qkIRFi17ulObyRHPYv1BbCt8pxNB + 4fG/gAXkFbCNxwh1eiQXXRTfruasCZ4/mHfX7MVm8JmWU9uAVIOLW+DSWOFhrDQduJdGBXJOyC2r + Gqoeg9+tkBmNH/jjxpnEkFW8q7io9DdOUqqNgoidA1h9vpKTs3084sy2DOgUvKN9uXWx14uxIyYU + Y1DnDy0wczcsuRt7l+EgtCEgpsLiLJQbKW+JS1UCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAf60J + yazhbHkDKIH2gFxfm7QLhhnqsmafvl4WP7JqZt0u0KdnvbDPfokdkM87yfbKJU1MTI86M36wEC+1 + P6bzklKz7kXbzAD4GggksAzxsEE64OWHC+Y64Tkxq2NiZTw/76POkcg9StiIXjG0ZcebHub9+Ux/ + rTncip92nDuvgEM7lbPFKRIS/YMhLCk09B/U0F6XLsf1yYjyf5miUTDikPkov23b/YGfpc8kh6hq + 1kqdi6a1cYPP34eAhtRhMqcZU9qezpJF6s9EeN/3YFfKzLODFSsVToBRAdZgGHzj//SAtLyQTD4n + KCSvK1UmaMxNaZyTHg8JnMf0ZuRpv26iSg== + -----END CERTIFICATE----- + + key: | + -----BEGIN PRIVATE KEY----- + MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCzk8uGgt/HcoxEpOjfH0bCpPAz + dt2V/xmjRS+TlJpgNSls671QvPNTszXbRpt7zTiMa/XJbXhBv7UMLJrCb0E+VPhpAbfrRihf85u8 + 7nh1GKkz+z4OacQJwHovdKpCERYte7pTm8kRz2L9QWwrfKcTQeHxv4AF5BWwjccIdXokF10U367m + rAmeP5h31+zFZvCZllPbgFSDi1vg0ljhYaw0HbiXRgVyTsgtqxqqHoPfrZAZjR/448aZxJBVvKu4 + qPQ3TlKqjYKInQNYfb6Sk7N9POLMtgzoFLyjfbl1sdeLsSMmFGNQ5w8tMHM3LLkbe5fhILQhIKbC + 4iyUGylviUtVAgMBAAECggEAIPb0CQy0RJoX+q/lGbRVmnyJpYDf+115WNnl+mrwjdGkeZyqw4v0 + BPzkWYzUFP1esJRO6buBNFybQRFdFW0z5lvVv/zzRKq71aVUBPInxaMRyHuJ8D5lIL8nDtgVOwyE + 7DOGyDtURUMzMjdUwoTe7K+O6QBU4X/1pVPZYgmissYSMmt68LiP8k0p601F4+r5xOi/QEy44aVp + aOJZBUOisKB8BmUXZqmQ4Cy05vU9Xi1rLyzkn9s7fxnZ+JO6Sd1r0Thm1mE0yuPgxkDBh/b4f3/2 + GsQNKKKCiij/6TfkjnBi8ZvWR44LnKpu760g/K7psVNrKwqJG6C/8RAcgISWQQKBgQDop7BaKGhK + 1QMJJ/vnlyYFTucfGLn6bM//pzTys5Gop0tpcfX/Hf6a6Dd+zBhmC3tBmhr80XOX/PiyAIbc0lOI + 31rafZuD/oVx5mlIySWX35EqS14LXmdVs/5vOhsInNgNiE+EPFf1L9YZgG/zA7OUBmqtTeYIPDVC + 7ViJcydItQKBgQDFmK0H0IA6W4opGQo+zQKhefooqZ+RDk9IIZMPOAtnvOM7y3rSVrfsSjzYVuMS + w/RP/vs7rwhaZejnCZ8/7uIqwg4sdUBRzZYR3PRNFeheW+BPZvb+2keRCGzOs7xkbF1mu54qtYTa + HZGZj1OsD83AoMwVLcdLDgO1kw32dkS8IQKBgFRdgoifAHqqVah7VFB9se7Y1tyi5cXWsXI+Wufr + j9U9nQ4GojK52LqpnH4hWnOelDqMvF6TQTyLIk/B+yWWK26Ft/dk9wDdSdystd8L+dLh4k0Y+Whb + +lLMq2YABw+PeJUnqdYE38xsZVHoDjBsVjFGRmbDybeQxauYT7PACy3FAoGBAK2+k9bdNQMbXp7I + j8OszHVkJdz/WXlY1cmdDAxDwXOUGVKIlxTAf7TbiijILZ5gg0Cb+hj+zR9/oI0WXtr+mAv02jWp + W8cSOLS4TnBBpTLjIpdu+BwbnvYeLF6MmEjNKEufCXKQbaLEgTQ/XNlchBSuzwSIXkbWqdhM1+gx + EjtBAoGARAdMIiDMPWIIZg3nNnFebbmtBP0qiBsYohQZ+6i/8s/vautEHBEN6Q0brIU/goo+nTHc + t9VaOkzjCmAJSLPUanuBC8pdYgLu5J20NXUZLD9AE/2bBT3OpezKcdYeI2jqoc1qlWHlNtVtdqQ2 + AcZSFJQjdg5BTyvdEDhaYUKGdRw= + -----END PRIVATE KEY----- + ``` + +1. Save the file and [restart] GitLab for the changes to take effect. + + +[reconfigure]: ../restart_gitlab.md#omnibus-gitlab-reconfigure +[restart]: ../restart_gitlab.md#installations-from-source diff --git a/doc/administration/auth/img/google_secure_ldap_add_step_1.png b/doc/administration/auth/img/google_secure_ldap_add_step_1.png new file mode 100644 index 0000000000000000000000000000000000000000..fd254443d75ad41a3119e1c571495476bda60a89 GIT binary patch literal 28849 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

>m8@lt7zNf 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 literal 0 HcmV?d00001 diff --git a/doc/administration/auth/img/google_secure_ldap_client_settings.png b/doc/administration/auth/img/google_secure_ldap_client_settings.png new file mode 100644 index 0000000000000000000000000000000000000000..3c0b3f3d4bdc7acb362b77c627f46d9bca248bbd GIT binary patch literal 63959 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 literal 0 HcmV?d00001 diff --git a/doc/administration/auth/ldap.md b/doc/administration/auth/ldap.md index 440c2b1285a..2d057dc7509 100644 --- a/doc/administration/auth/ldap.md +++ b/doc/administration/auth/ldap.md @@ -48,6 +48,14 @@ LDAP-enabled users can always authenticate with Git using their GitLab username or email and LDAP password, even if password authentication for Git is disabled in the application settings. +## Google Secure LDAP **[CORE ONLY]** + +> Introduced in GitLab 11.9. + +[Google Cloud Identity](https://cloud.google.com/identity/) provides a Secure +LDAP service that can be configured with GitLab for authentication and group sync. +See [Google Secure LDAP](google_secure_ldap.md) for detailed configuration instructions. + ## Configuration NOTE: **Note**: -- GitLab From c044bfe84aa69af65dd2923ecd8e49573974f354 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Thu, 4 Apr 2019 14:54:25 +0000 Subject: [PATCH 2/7] Merge branch 'id-mr-list-when-filtered-by-approvers-only' into 'master' Consider array params on rendering MR list on dashboard See merge request gitlab-org/gitlab-ce!26623 (cherry picked from commit 7926384ff32b9ad8833dcfffc9bb87d036c4bd21) b3f5413a Consider array params on rendering MR list on dashboard --- app/controllers/dashboard_controller.rb | 5 ++- app/finders/issuable_finder.rb | 1 - .../concerns/issuable_collections_spec.rb | 4 +-- spec/controllers/dashboard_controller_spec.rb | 33 +++++++++++++++++++ .../features/dashboard/merge_requests_spec.rb | 25 ++++++++++++++ 5 files changed, 64 insertions(+), 4 deletions(-) diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 75329b05a6f..1a97b39d3ae 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -46,7 +46,10 @@ class DashboardController < Dashboard::ApplicationController end def check_filters_presence! - @no_filters_set = finder_type.scalar_params.none? { |k| params.key?(k) } + no_scalar_filters_set = finder_type.scalar_params.none? { |k| params.key?(k) } + no_array_filters_set = finder_type.array_params.none? { |k, _| params.key?(k) } + + @no_filters_set = no_scalar_filters_set && no_array_filters_set return unless @no_filters_set diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb index 072d07e0ed2..fa434a3b4e8 100644 --- a/app/finders/issuable_finder.rb +++ b/app/finders/issuable_finder.rb @@ -53,7 +53,6 @@ class IssuableFinder assignee_username author_id author_username - label_name milestone_title my_reaction_emoji search diff --git a/spec/controllers/concerns/issuable_collections_spec.rb b/spec/controllers/concerns/issuable_collections_spec.rb index 8580900215c..a82b66361ca 100644 --- a/spec/controllers/concerns/issuable_collections_spec.rb +++ b/spec/controllers/concerns/issuable_collections_spec.rb @@ -117,7 +117,7 @@ describe IssuableCollections do due_date: '2017-01-01', group_id: '3', iids: '4', - label_name: 'foo', + label_name: ['foo'], milestone_title: 'bar', my_reaction_emoji: 'thumbsup', non_archived: 'true', @@ -142,7 +142,7 @@ describe IssuableCollections do 'author_id' => '2', 'author_username' => 'user2', 'confidential' => true, - 'label_name' => 'foo', + 'label_name' => ['foo'], 'milestone_title' => 'bar', 'my_reaction_emoji' => 'thumbsup', 'due_date' => '2017-01-01', diff --git a/spec/controllers/dashboard_controller_spec.rb b/spec/controllers/dashboard_controller_spec.rb index c857a78d5e8..b039ec2906c 100644 --- a/spec/controllers/dashboard_controller_spec.rb +++ b/spec/controllers/dashboard_controller_spec.rb @@ -23,4 +23,37 @@ describe DashboardController do it_behaves_like 'authenticates sessionless user', :issues, :atom, author_id: User.first it_behaves_like 'authenticates sessionless user', :issues_calendar, :ics + + describe "#check_filters_presence!" do + let(:user) { create(:user) } + + before do + sign_in(user) + get :merge_requests, params: params + end + + context "no filters" do + let(:params) { {} } + + it 'sets @no_filters_set to false' do + expect(assigns[:no_filters_set]).to eq(true) + end + end + + context "scalar filters" do + let(:params) { { author_id: user.id } } + + it 'sets @no_filters_set to false' do + expect(assigns[:no_filters_set]).to eq(false) + end + end + + context "array filters" do + let(:params) { { label_name: ['bug'] } } + + it 'sets @no_filters_set to false' do + expect(assigns[:no_filters_set]).to eq(false) + end + end + end end diff --git a/spec/features/dashboard/merge_requests_spec.rb b/spec/features/dashboard/merge_requests_spec.rb index 9ffa75aee47..4965770605a 100644 --- a/spec/features/dashboard/merge_requests_spec.rb +++ b/spec/features/dashboard/merge_requests_spec.rb @@ -44,6 +44,8 @@ describe 'Dashboard Merge Requests' do end context 'merge requests exist' do + let(:label) { create(:label) } + let!(:assigned_merge_request) do create(:merge_request, assignee: current_user, @@ -72,6 +74,14 @@ describe 'Dashboard Merge Requests' do target_project: public_project, source_project: forked_project) end + let!(:labeled_merge_request) do + create(:labeled_merge_request, + source_branch: 'labeled', + labels: [label], + author: current_user, + source_project: project) + end + let!(:other_merge_request) do create(:merge_request, source_branch: 'fix', @@ -90,6 +100,7 @@ describe 'Dashboard Merge Requests' do expect(page).not_to have_content(authored_merge_request.title) expect(page).not_to have_content(authored_merge_request_from_fork.title) expect(page).not_to have_content(other_merge_request.title) + expect(page).not_to have_content(labeled_merge_request.title) end it 'shows authored merge requests', :js do @@ -98,7 +109,21 @@ describe 'Dashboard Merge Requests' do expect(page).to have_content(authored_merge_request.title) expect(page).to have_content(authored_merge_request_from_fork.title) + expect(page).to have_content(labeled_merge_request.title) + + expect(page).not_to have_content(assigned_merge_request.title) + expect(page).not_to have_content(assigned_merge_request_from_fork.title) + expect(page).not_to have_content(other_merge_request.title) + end + + it 'shows labeled merge requests', :js do + reset_filters + input_filtered_search("label:#{label.name}") + expect(page).to have_content(labeled_merge_request.title) + + expect(page).not_to have_content(authored_merge_request.title) + expect(page).not_to have_content(authored_merge_request_from_fork.title) expect(page).not_to have_content(assigned_merge_request.title) expect(page).not_to have_content(assigned_merge_request_from_fork.title) expect(page).not_to have_content(other_merge_request.title) -- GitLab From 52778632c1fbd55400faa1e8308280cd727d8153 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Mon, 1 Apr 2019 15:13:23 +0000 Subject: [PATCH 3/7] Merge branch 'fj-59547-fix-has-commits' into 'master' Fix MergeRequest#has_commits? nil comparison Closes #59547 See merge request gitlab-org/gitlab-ce!26828 (cherry picked from commit b224efe767e4f8e24b51b87753f55bf6d3129f68) 6645b825 Fix MergeRequest#commits_count nil comparison --- app/models/merge_request.rb | 2 +- spec/models/merge_request_spec.rb | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index acf80addc6a..06a86a1f36f 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -1301,7 +1301,7 @@ class MergeRequest < ActiveRecord::Base end def has_commits? - merge_request_diff && commits_count > 0 + merge_request_diff && commits_count.to_i > 0 end def has_no_commits? diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 07cb4c9c1e3..87db9e574cf 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -2613,14 +2613,21 @@ describe MergeRequest do end describe '#has_commits?' do - before do + it 'returns true when merge request diff has commits' do allow(subject.merge_request_diff).to receive(:commits_count) .and_return(2) - end - it 'returns true when merge request diff has commits' do expect(subject.has_commits?).to be_truthy end + + context 'when commits_count is nil' do + it 'returns false' do + allow(subject.merge_request_diff).to receive(:commits_count) + .and_return(nil) + + expect(subject.has_commits?).to be_falsey + end + end end describe '#has_no_commits?' do -- GitLab From 3fec9fd3f546fc080fab2d58de580edf30798726 Mon Sep 17 00:00:00 2001 From: Sean McGivern Date: Thu, 4 Apr 2019 15:00:56 +0000 Subject: [PATCH 4/7] Merge branch 'allow-to-use-untrusted-ruby-syntax' into 'master' Allow to use untrusted ruby syntax See merge request gitlab-org/gitlab-ce!26905 (cherry picked from commit 7dcc3003119666c75a35c27d73ffb297c696fcc8) 9bc4fbf1 Allow to use untrusted Regexp via feature flag --- .../allow-to-use-untrusted-ruby-syntax.yml | 5 ++ doc/ci/yaml/README.md | 21 ++++++ lib/gitlab/ci/build/policy/refs.rb | 2 +- lib/gitlab/ci/config/entry/policy.rb | 4 +- lib/gitlab/config/entry/validators.rb | 16 ++++- lib/gitlab/untrusted_regexp/ruby_syntax.rb | 39 ++++++++--- spec/lib/gitlab/ci/build/policy/refs_spec.rb | 26 +++++++ .../lib/gitlab/ci/config/entry/policy_spec.rb | 67 ++++++++++++++++++ .../untrusted_regexp/ruby_syntax_spec.rb | 68 ++++++++++++++++--- 9 files changed, 223 insertions(+), 25 deletions(-) create mode 100644 changelogs/unreleased/allow-to-use-untrusted-ruby-syntax.yml diff --git a/changelogs/unreleased/allow-to-use-untrusted-ruby-syntax.yml b/changelogs/unreleased/allow-to-use-untrusted-ruby-syntax.yml new file mode 100644 index 00000000000..731c9c10b00 --- /dev/null +++ b/changelogs/unreleased/allow-to-use-untrusted-ruby-syntax.yml @@ -0,0 +1,5 @@ +--- +title: Allow to use untrusted Regexp via feature flag +merge_request: 26905 +author: +type: deprecated diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index 816d12a8dd4..bc498939522 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -397,6 +397,27 @@ job: only: ['branches', 'tags'] ``` +### Supported `only`/`except` regexp syntax + +CAUTION: **Warning:** +This is a breaking change that was introduced with GitLab 11.9.4. + +In GitLab 11.9.4, GitLab begun internally converting regexp used +in `only` and `except` parameters to [RE2](https://github.com/google/re2/wiki/Syntax). + +This means that only subset of features provided by [Ruby Regexp](https://ruby-doc.org/core/Regexp.html) +is supported. [RE2](https://github.com/google/re2/wiki/Syntax) limits the set of features +provided due to computational complexity, which means some features became unavailable in GitLab 11.9.4. +For example, negative lookaheads. + +For GitLab versions from 11.9.7 and up to GitLab 12.0, GitLab provides a feature flag that can be +enabled by administrators that allows users to use unsafe regexp syntax. This brings compatibility +with previously allowed syntax version and allows users to gracefully migrate to the new syntax. + +```ruby +Feature.enable(:allow_unsafe_ruby_regexp) +``` + ### `only`/`except` (advanced) > - `refs` and `kubernetes` policies introduced in GitLab 10.0. diff --git a/lib/gitlab/ci/build/policy/refs.rb b/lib/gitlab/ci/build/policy/refs.rb index 360424bec11..c3005303fd8 100644 --- a/lib/gitlab/ci/build/policy/refs.rb +++ b/lib/gitlab/ci/build/policy/refs.rb @@ -35,7 +35,7 @@ module Gitlab # patterns can be matched only when branch or tag is used # the pattern matching does not work for merge requests pipelines if pipeline.branch? || pipeline.tag? - if regexp = Gitlab::UntrustedRegexp::RubySyntax.fabricate(pattern) + if regexp = Gitlab::UntrustedRegexp::RubySyntax.fabricate(pattern, fallback: true) regexp.match?(pipeline.ref) else pattern == pipeline.ref diff --git a/lib/gitlab/ci/config/entry/policy.rb b/lib/gitlab/ci/config/entry/policy.rb index adc3660d950..7b14218d3ea 100644 --- a/lib/gitlab/ci/config/entry/policy.rb +++ b/lib/gitlab/ci/config/entry/policy.rb @@ -17,7 +17,7 @@ module Gitlab include ::Gitlab::Config::Entry::Validatable validations do - validates :config, array_of_strings_or_regexps: true + validates :config, array_of_strings_or_regexps_with_fallback: true end def value @@ -38,7 +38,7 @@ module Gitlab validate :variables_expressions_syntax with_options allow_nil: true do - validates :refs, array_of_strings_or_regexps: true + validates :refs, array_of_strings_or_regexps_with_fallback: true validates :kubernetes, allowed_values: %w[active] validates :variables, array_of_strings: true validates :changes, array_of_strings: true diff --git a/lib/gitlab/config/entry/validators.rb b/lib/gitlab/config/entry/validators.rb index d348e11b753..9b2ace382ef 100644 --- a/lib/gitlab/config/entry/validators.rb +++ b/lib/gitlab/config/entry/validators.rb @@ -118,6 +118,12 @@ module Gitlab end end + protected + + def fallback + false + end + private def matches_syntax?(value) @@ -126,7 +132,7 @@ module Gitlab def validate_regexp(value) matches_syntax?(value) && - Gitlab::UntrustedRegexp::RubySyntax.valid?(value) + Gitlab::UntrustedRegexp::RubySyntax.valid?(value, fallback: fallback) end end @@ -151,6 +157,14 @@ module Gitlab end end + class ArrayOfStringsOrRegexpsWithFallbackValidator < ArrayOfStringsOrRegexpsValidator + protected + + def fallback + true + end + end + class ArrayOfStringsOrStringValidator < RegexpValidator def validate_each(record, attribute, value) unless validate_array_of_strings_or_string(value) diff --git a/lib/gitlab/untrusted_regexp/ruby_syntax.rb b/lib/gitlab/untrusted_regexp/ruby_syntax.rb index 91f300f97d0..6adf119aa75 100644 --- a/lib/gitlab/untrusted_regexp/ruby_syntax.rb +++ b/lib/gitlab/untrusted_regexp/ruby_syntax.rb @@ -6,7 +6,7 @@ module Gitlab # and converts that to RE2 representation: # // class RubySyntax - PATTERN = %r{^/(?.+)/(?[ismU]*)$}.freeze + PATTERN = %r{^/(?.*)/(?[ismU]*)$}.freeze # Checks if pattern matches a regexp pattern # but does not enforce it's validity @@ -16,28 +16,47 @@ module Gitlab # The regexp can match the pattern `/.../`, but may not be fabricatable: # it can be invalid or incomplete: `/match ( string/` - def self.valid?(pattern) - !!self.fabricate(pattern) + def self.valid?(pattern, fallback: false) + !!self.fabricate(pattern, fallback: fallback) end - def self.fabricate(pattern) - self.fabricate!(pattern) + def self.fabricate(pattern, fallback: false) + self.fabricate!(pattern, fallback: fallback) rescue RegexpError nil end - def self.fabricate!(pattern) + def self.fabricate!(pattern, fallback: false) raise RegexpError, 'Pattern is not string!' unless pattern.is_a?(String) matches = pattern.match(PATTERN) raise RegexpError, 'Invalid regular expression!' if matches.nil? - expression = matches[:regexp] - flags = matches[:flags] - expression.prepend("(?#{flags})") if flags.present? + begin + create_untrusted_regexp(matches[:regexp], matches[:flags]) + rescue RegexpError + raise unless fallback && + Feature.enabled?(:allow_unsafe_ruby_regexp, default_enabled: false) - UntrustedRegexp.new(expression, multiline: false) + create_ruby_regexp(matches[:regexp], matches[:flags]) + end end + + def self.create_untrusted_regexp(pattern, flags) + pattern.prepend("(?#{flags})") if flags.present? + + UntrustedRegexp.new(pattern, multiline: false) + end + private_class_method :create_untrusted_regexp + + def self.create_ruby_regexp(pattern, flags) + options = 0 + options += Regexp::IGNORECASE if flags&.include?('i') + options += Regexp::MULTILINE if flags&.include?('m') + + Regexp.new(pattern, options) + end + private_class_method :create_ruby_regexp end end end diff --git a/spec/lib/gitlab/ci/build/policy/refs_spec.rb b/spec/lib/gitlab/ci/build/policy/refs_spec.rb index ec0450643c3..22ca681cfd3 100644 --- a/spec/lib/gitlab/ci/build/policy/refs_spec.rb +++ b/spec/lib/gitlab/ci/build/policy/refs_spec.rb @@ -101,6 +101,32 @@ describe Gitlab::Ci::Build::Policy::Refs do expect(described_class.new(['/fix-.*/'])) .not_to be_satisfied_by(pipeline) end + + context 'when unsafe regexp is used' do + let(:subject) { described_class.new(['/^(?!master).+/']) } + + context 'when allow_unsafe_ruby_regexp is disabled' do + before do + stub_feature_flags(allow_unsafe_ruby_regexp: false) + end + + it 'ignores invalid regexp' do + expect(subject) + .not_to be_satisfied_by(pipeline) + end + end + + context 'when allow_unsafe_ruby_regexp is enabled' do + before do + stub_feature_flags(allow_unsafe_ruby_regexp: true) + end + + it 'is satisfied by regexp' do + expect(subject) + .to be_satisfied_by(pipeline) + end + end + end end context 'malicious regexp' do diff --git a/spec/lib/gitlab/ci/config/entry/policy_spec.rb b/spec/lib/gitlab/ci/config/entry/policy_spec.rb index 1c987e13a9a..fba5671594d 100644 --- a/spec/lib/gitlab/ci/config/entry/policy_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/policy_spec.rb @@ -1,4 +1,5 @@ require 'fast_spec_helper' +require 'support/helpers/stub_feature_flags' require_dependency 'active_model' describe Gitlab::Ci::Config::Entry::Policy do @@ -33,6 +34,44 @@ describe Gitlab::Ci::Config::Entry::Policy do end end + context 'when config is an empty regexp' do + let(:config) { ['//'] } + + describe '#valid?' do + it 'is valid' do + expect(entry).to be_valid + end + end + end + + context 'when using unsafe regexp' do + include StubFeatureFlags + + let(:config) { ['/^(?!master).+/'] } + + subject { described_class.new([regexp]) } + + context 'when allow_unsafe_ruby_regexp is disabled' do + before do + stub_feature_flags(allow_unsafe_ruby_regexp: false) + end + + it 'is not valid' do + expect(entry).not_to be_valid + end + end + + context 'when allow_unsafe_ruby_regexp is enabled' do + before do + stub_feature_flags(allow_unsafe_ruby_regexp: true) + end + + it 'is valid' do + expect(entry).to be_valid + end + end + end + context 'when config is a special keyword' do let(:config) { %w[tags triggers branches] } @@ -67,6 +106,34 @@ describe Gitlab::Ci::Config::Entry::Policy do end end + context 'when using unsafe regexp' do + include StubFeatureFlags + + let(:config) { { refs: ['/^(?!master).+/'] } } + + subject { described_class.new([regexp]) } + + context 'when allow_unsafe_ruby_regexp is disabled' do + before do + stub_feature_flags(allow_unsafe_ruby_regexp: false) + end + + it 'is not valid' do + expect(entry).not_to be_valid + end + end + + context 'when allow_unsafe_ruby_regexp is enabled' do + before do + stub_feature_flags(allow_unsafe_ruby_regexp: true) + end + + it 'is valid' do + expect(entry).to be_valid + end + end + end + context 'when specifying kubernetes policy' do let(:config) { { kubernetes: 'active' } } diff --git a/spec/lib/gitlab/untrusted_regexp/ruby_syntax_spec.rb b/spec/lib/gitlab/untrusted_regexp/ruby_syntax_spec.rb index 005d41580de..f1882e03581 100644 --- a/spec/lib/gitlab/untrusted_regexp/ruby_syntax_spec.rb +++ b/spec/lib/gitlab/untrusted_regexp/ruby_syntax_spec.rb @@ -1,5 +1,6 @@ require 'fast_spec_helper' require 'support/shared_examples/malicious_regexp_shared_examples' +require 'support/helpers/stub_feature_flags' describe Gitlab::UntrustedRegexp::RubySyntax do describe '.matches_syntax?' do @@ -33,6 +34,12 @@ describe Gitlab::UntrustedRegexp::RubySyntax do end end + context 'when regexp is empty' do + it 'fabricates regexp correctly' do + expect(described_class.fabricate('//')).not_to be_nil + end + end + context 'when regexp is a raw pattern' do it 'returns error' do expect(described_class.fabricate('some .* thing')).to be_nil @@ -41,24 +48,63 @@ describe Gitlab::UntrustedRegexp::RubySyntax do end describe '.fabricate!' do - context 'when regexp is using /regexp/ scheme with flags' do - it 'fabricates regexp with a single flag' do - regexp = described_class.fabricate!('/something/i') + context 'safe regexp is used' do + context 'when regexp is using /regexp/ scheme with flags' do + it 'fabricates regexp with a single flag' do + regexp = described_class.fabricate!('/something/i') + + expect(regexp).to eq Gitlab::UntrustedRegexp.new('(?i)something') + expect(regexp.scan('SOMETHING')).to be_one + end - expect(regexp).to eq Gitlab::UntrustedRegexp.new('(?i)something') - expect(regexp.scan('SOMETHING')).to be_one + it 'fabricates regexp with multiple flags' do + regexp = described_class.fabricate!('/something/im') + + expect(regexp).to eq Gitlab::UntrustedRegexp.new('(?im)something') + end + + it 'fabricates regexp without flags' do + regexp = described_class.fabricate!('/something/') + + expect(regexp).to eq Gitlab::UntrustedRegexp.new('something') + end end + end - it 'fabricates regexp with multiple flags' do - regexp = described_class.fabricate!('/something/im') + context 'when unsafe regexp is used' do + include StubFeatureFlags - expect(regexp).to eq Gitlab::UntrustedRegexp.new('(?im)something') + before do + stub_feature_flags(allow_unsafe_ruby_regexp: true) + + allow(Gitlab::UntrustedRegexp).to receive(:new).and_raise(RegexpError) end - it 'fabricates regexp without flags' do - regexp = described_class.fabricate!('/something/') + context 'when no fallback is enabled' do + it 'raises an exception' do + expect { described_class.fabricate!('/something/') } + .to raise_error(RegexpError) + end + end + + context 'when fallback is used' do + it 'fabricates regexp with a single flag' do + regexp = described_class.fabricate!('/something/i', fallback: true) + + expect(regexp).to eq Regexp.new('something', Regexp::IGNORECASE) + end + + it 'fabricates regexp with multiple flags' do + regexp = described_class.fabricate!('/something/im', fallback: true) + + expect(regexp).to eq Regexp.new('something', Regexp::IGNORECASE | Regexp::MULTILINE) + end + + it 'fabricates regexp without flags' do + regexp = described_class.fabricate!('/something/', fallback: true) - expect(regexp).to eq Gitlab::UntrustedRegexp.new('something') + expect(regexp).to eq Regexp.new('something') + end end end -- GitLab From bd8f532d80e5b220f552a492cb0beca7e6b725d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Trzci=C5=84ski?= Date: Mon, 8 Apr 2019 16:20:23 +0000 Subject: [PATCH 5/7] Merge branch 'fix-pull-request-importer' into 'master' Improve performance of PR import See merge request gitlab-org/gitlab-ce!27121 (cherry picked from commit f15caf0109998308e7f960baaa541d73be8bcacb) f3ad51f8 Improve performance of PR import --- .../unreleased/fix-pull-request-importer.yml | 5 ++ lib/gitlab/import/merge_request_helpers.rb | 2 +- .../import/merge_request_helpers_spec.rb | 73 +++++++++++++++++++ 3 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/fix-pull-request-importer.yml create mode 100644 spec/lib/gitlab/import/merge_request_helpers_spec.rb diff --git a/changelogs/unreleased/fix-pull-request-importer.yml b/changelogs/unreleased/fix-pull-request-importer.yml new file mode 100644 index 00000000000..5f642a0710b --- /dev/null +++ b/changelogs/unreleased/fix-pull-request-importer.yml @@ -0,0 +1,5 @@ +--- +title: Improve performance of PR import +merge_request: 27121 +author: +type: performance diff --git a/lib/gitlab/import/merge_request_helpers.rb b/lib/gitlab/import/merge_request_helpers.rb index b3fe1fc0685..4bc39868389 100644 --- a/lib/gitlab/import/merge_request_helpers.rb +++ b/lib/gitlab/import/merge_request_helpers.rb @@ -22,7 +22,7 @@ module Gitlab # additional work that is strictly necessary. merge_request_id = insert_and_return_id(attributes, project.merge_requests) - merge_request = project.merge_requests.reload.find(merge_request_id) + merge_request = project.merge_requests.reset.find(merge_request_id) [merge_request, false] end diff --git a/spec/lib/gitlab/import/merge_request_helpers_spec.rb b/spec/lib/gitlab/import/merge_request_helpers_spec.rb new file mode 100644 index 00000000000..cc0f2baf905 --- /dev/null +++ b/spec/lib/gitlab/import/merge_request_helpers_spec.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Import::MergeRequestHelpers, type: :helper do + set(:project) { create(:project, :repository) } + set(:user) { create(:user) } + + describe '.create_merge_request_without_hooks' do + let(:iid) { 42 } + + let(:attributes) do + { + iid: iid, + title: 'My Pull Request', + description: 'This is my pull request', + source_project_id: project.id, + target_project_id: project.id, + source_branch: 'master-42', + target_branch: 'master', + state: :merged, + author_id: user.id, + assignee_id: user.id + } + end + + subject { helper.create_merge_request_without_hooks(project, attributes, iid) } + + context 'when merge request does not exist' do + it 'returns a new object' do + expect(subject.first).not_to be_nil + expect(subject.second).to eq(false) + end + + it 'does load all existing objects' do + 5.times do |iid| + MergeRequest.create!( + attributes.merge(iid: iid, source_branch: iid.to_s)) + end + + # does ensure that we only load object twice + # 1. by #insert_and_return_id + # 2. by project.merge_requests.find + expect_any_instance_of(MergeRequest).to receive(:attributes) + .twice.times.and_call_original + + expect(subject.first).not_to be_nil + expect(subject.second).to eq(false) + end + end + + context 'when merge request does exist' do + before do + MergeRequest.create!(attributes) + end + + it 'returns an existing object' do + expect(subject.first).not_to be_nil + expect(subject.second).to eq(true) + end + end + + context 'when project is deleted' do + before do + project.delete + end + + it 'returns an existing object' do + expect(subject.first).to be_nil + end + end + end +end -- GitLab From e476b49d5ab2c02328787c211e832e886e3cde1d Mon Sep 17 00:00:00 2001 From: Michael Kozono Date: Wed, 10 Apr 2019 21:11:55 +0000 Subject: [PATCH 6/7] Merge branch 'sh-disable-diff-instrumentation' into 'master' Disable method instrumentation for diffs Closes #52898 See merge request gitlab-org/gitlab-ce!27235 (cherry picked from commit b9e6e72501173c29a30ee1b4a2afb9ee9d3b1117) b397ad8a Disable method instrumentation for diffs --- changelogs/unreleased/sh-disable-diff-instrumentation.yml | 5 +++++ config/initializers/zz_metrics.rb | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/sh-disable-diff-instrumentation.yml diff --git a/changelogs/unreleased/sh-disable-diff-instrumentation.yml b/changelogs/unreleased/sh-disable-diff-instrumentation.yml new file mode 100644 index 00000000000..55f4c2a8510 --- /dev/null +++ b/changelogs/unreleased/sh-disable-diff-instrumentation.yml @@ -0,0 +1,5 @@ +--- +title: Disable method instrumentation for diffs +merge_request: 27235 +author: +type: performance diff --git a/config/initializers/zz_metrics.rb b/config/initializers/zz_metrics.rb index 151cad3ef9a..5aa6f73c5c5 100644 --- a/config/initializers/zz_metrics.rb +++ b/config/initializers/zz_metrics.rb @@ -30,7 +30,6 @@ def instrument_classes(instrumentation) # are included. %w(app services [^concerns]**) => %w(app services), %w(lib gitlab conflicts) => ['lib'], - %w(lib gitlab diff) => ['lib'], %w(lib gitlab email message) => ['lib'], %w(lib gitlab checks) => ['lib'] } -- GitLab From 05dbf8e048a8e0b98e1dce95e714bd54a3955f0d Mon Sep 17 00:00:00 2001 From: John Jarvis Date: Thu, 11 Apr 2019 12:46:53 +0000 Subject: [PATCH 7/7] Merge branch 'restore-hipchat-11-9' into '11-9-stable' [11.9] Revert "Remove HipChat integration from GitLab" See merge request gitlab-org/gitlab-ce!27257 --- .rubocop_todo.yml | 1 + Gemfile | 3 + Gemfile.lock | 4 + app/models/project.rb | 1 + .../project_services/hipchat_service.rb | 311 +++++++++++++ app/models/service.rb | 1 + changelogs/unreleased/restore-hipchat.yml | 5 + config/initializers/hipchat_client_patch.rb | 15 + .../20190107151029_remove_hipchat_services.rb | 16 - doc/api/services.md | 39 ++ doc/integration/README.md | 4 +- doc/project_services/hipchat.md | 1 + doc/university/glossary/README.md | 2 +- doc/user/index.md | 4 +- doc/user/project/integrations/hipchat.md | 53 +++ .../project/integrations/project_services.md | 1 + lib/api/services.rb | 40 ++ spec/factories/services.rb | 6 + .../services/disable_triggers_spec.rb | 5 +- .../services/user_activates_hipchat_spec.rb | 40 ++ .../services/user_views_services_spec.rb | 3 +- spec/lib/gitlab/import_export/all_models.yml | 1 + spec/lib/gitlab/import_export/project.json | 22 + .../project_services/hipchat_service_spec.rb | 410 ++++++++++++++++++ spec/models/project_spec.rb | 1 + vendor/licenses.csv | 1 + 26 files changed, 963 insertions(+), 27 deletions(-) create mode 100644 app/models/project_services/hipchat_service.rb create mode 100644 changelogs/unreleased/restore-hipchat.yml create mode 100644 config/initializers/hipchat_client_patch.rb delete mode 100644 db/migrate/20190107151029_remove_hipchat_services.rb create mode 100644 doc/project_services/hipchat.md create mode 100644 doc/user/project/integrations/hipchat.md create mode 100644 spec/features/projects/services/user_activates_hipchat_spec.rb create mode 100644 spec/models/project_services/hipchat_service_spec.rb diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 97e39ce99cb..77ad4753c84 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -268,6 +268,7 @@ Rails/Presence: - 'app/models/clusters/platforms/kubernetes.rb' - 'app/models/concerns/mentionable.rb' - 'app/models/concerns/token_authenticatable.rb' + - 'app/models/project_services/hipchat_service.rb' - 'app/models/project_services/irker_service.rb' - 'app/models/project_services/jira_service.rb' - 'app/models/project_services/kubernetes_service.rb' diff --git a/Gemfile b/Gemfile index f36e2e38d6b..da005d40499 100644 --- a/Gemfile +++ b/Gemfile @@ -204,6 +204,9 @@ gem 'connection_pool', '~> 2.0' # Discord integration gem 'discordrb-webhooks-blackst0ne', '~> 3.3', require: false +# HipChat integration +gem 'hipchat', '~> 1.5.0' + # JIRA integration gem 'jira-ruby', '~> 1.4' diff --git a/Gemfile.lock b/Gemfile.lock index 1be6f228954..5de32fba5d9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -364,6 +364,9 @@ GEM hashie (>= 3.0) health_check (2.6.0) rails (>= 4.0) + hipchat (1.5.2) + httparty + mimemagic html-pipeline (2.8.4) activesupport (>= 2) nokogiri (>= 1.4) @@ -1041,6 +1044,7 @@ DEPENDENCIES hangouts-chat (~> 0.0.5) hashie-forbidden_attributes health_check (~> 2.6.0) + hipchat (~> 1.5.0) html-pipeline (~> 2.8) html2text httparty (~> 0.13.3) diff --git a/app/models/project.rb b/app/models/project.rb index 4039af7a330..56bc77a9686 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -147,6 +147,7 @@ class Project < ActiveRecord::Base has_one :pipelines_email_service has_one :irker_service has_one :pivotaltracker_service + has_one :hipchat_service has_one :flowdock_service has_one :assembla_service has_one :asana_service diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb new file mode 100644 index 00000000000..a69b7b4c4b6 --- /dev/null +++ b/app/models/project_services/hipchat_service.rb @@ -0,0 +1,311 @@ +# frozen_string_literal: true + +class HipchatService < Service + include ActionView::Helpers::SanitizeHelper + + MAX_COMMITS = 3 + HIPCHAT_ALLOWED_TAGS = %w[ + a b i strong em br img pre code + table th tr td caption colgroup col thead tbody tfoot + ul ol li dl dt dd + ].freeze + + prop_accessor :token, :room, :server, :color, :api_version + boolean_accessor :notify_only_broken_pipelines, :notify + validates :token, presence: true, if: :activated? + + def initialize_properties + if properties.nil? + self.properties = {} + self.notify_only_broken_pipelines = true + end + end + + def title + 'HipChat' + end + + def description + 'Private group chat and IM' + end + + def self.to_param + 'hipchat' + end + + def fields + [ + { type: 'text', name: 'token', placeholder: 'Room token', required: true }, + { type: 'text', name: 'room', placeholder: 'Room name or ID' }, + { type: 'checkbox', name: 'notify' }, + { type: 'select', name: 'color', choices: %w(yellow red green purple gray random) }, + { type: 'text', name: 'api_version', + placeholder: 'Leave blank for default (v2)' }, + { type: 'text', name: 'server', + placeholder: 'Leave blank for default. https://hipchat.example.com' }, + { type: 'checkbox', name: 'notify_only_broken_pipelines' } + ] + end + + def self.supported_events + %w(push issue confidential_issue merge_request note confidential_note tag_push pipeline) + end + + def execute(data) + return unless supported_events.include?(data[:object_kind]) + + message = create_message(data) + return unless message.present? + + gate[room].send('GitLab', message, message_options(data)) # rubocop:disable GitlabSecurity/PublicSend + end + + def test(data) + begin + result = execute(data) + rescue StandardError => error + return { success: false, result: error } + end + + { success: true, result: result } + end + + private + + def gate + options = { api_version: api_version.present? ? api_version : 'v2' } + options[:server_url] = server unless server.blank? + @gate ||= HipChat::Client.new(token, options) + end + + def message_options(data = nil) + { notify: notify.present? && Gitlab::Utils.to_boolean(notify), color: message_color(data) } + end + + def create_message(data) + object_kind = data[:object_kind] + + case object_kind + when "push", "tag_push" + create_push_message(data) + when "issue" + create_issue_message(data) unless update?(data) + when "merge_request" + create_merge_request_message(data) unless update?(data) + when "note" + create_note_message(data) + when "pipeline" + create_pipeline_message(data) if should_pipeline_be_notified?(data) + end + end + + def render_line(text) + markdown(text.lines.first.chomp, pipeline: :single_line) if text + end + + def create_push_message(push) + ref_type = Gitlab::Git.tag_ref?(push[:ref]) ? 'tag' : 'branch' + ref = Gitlab::Git.ref_name(push[:ref]) + + before = push[:before] + after = push[:after] + + message = [] + message << "#{push[:user_name]} " + + if Gitlab::Git.blank_ref?(before) + message << "pushed new #{ref_type} #{ref}"\ + " to #{project_link}\n" + elsif Gitlab::Git.blank_ref?(after) + message << "removed #{ref_type} #{ref} from #{project_name} \n" + else + message << "pushed to #{ref_type} #{ref} " + message << "of #{project.full_name.gsub!(/\s/, '')} " + message << "(Compare changes)" + + push[:commits].take(MAX_COMMITS).each do |commit| + message << "
- #{render_line(commit[:message])} (#{commit[:id][0..5]})" + end + + if push[:commits].count > MAX_COMMITS + message << "
... #{push[:commits].count - MAX_COMMITS} more commits" + end + end + + message.join + end + + def markdown(text, options = {}) + return "" unless text + + context = { + project: project, + pipeline: :email + } + + Banzai.render(text, context) + + context.merge!(options) + + html = Banzai.render_and_post_process(text, context) + sanitized_html = sanitize(html, tags: HIPCHAT_ALLOWED_TAGS, attributes: %w[href title alt]) + + sanitized_html.truncate(200, separator: ' ', omission: '...') + end + + def create_issue_message(data) + user_name = data[:user][:name] + + obj_attr = data[:object_attributes] + obj_attr = HashWithIndifferentAccess.new(obj_attr) + title = render_line(obj_attr[:title]) + state = obj_attr[:state] + issue_iid = obj_attr[:iid] + issue_url = obj_attr[:url] + description = obj_attr[:description] + + issue_link = "issue ##{issue_iid}" + + message = ["#{user_name} #{state} #{issue_link} in #{project_link}: #{title}"] + message << "

#{markdown(description)}
" + + message.join + end + + def create_merge_request_message(data) + user_name = data[:user][:name] + + obj_attr = data[:object_attributes] + obj_attr = HashWithIndifferentAccess.new(obj_attr) + merge_request_id = obj_attr[:iid] + state = obj_attr[:state] + description = obj_attr[:description] + title = render_line(obj_attr[:title]) + + merge_request_url = "#{project_url}/merge_requests/#{merge_request_id}" + merge_request_link = "merge request !#{merge_request_id}" + message = ["#{user_name} #{state} #{merge_request_link} in " \ + "#{project_link}: #{title}"] + + message << "
#{markdown(description)}
" + message.join + end + + def format_title(title) + "#{render_line(title)}" + end + + def create_note_message(data) + data = HashWithIndifferentAccess.new(data) + user_name = data[:user][:name] + + obj_attr = HashWithIndifferentAccess.new(data[:object_attributes]) + note = obj_attr[:note] + note_url = obj_attr[:url] + noteable_type = obj_attr[:noteable_type] + commit_id = nil + + case noteable_type + when "Commit" + commit_attr = HashWithIndifferentAccess.new(data[:commit]) + commit_id = commit_attr[:id] + subject_desc = commit_id + subject_desc = Commit.truncate_sha(subject_desc) + subject_type = "commit" + title = format_title(commit_attr[:message]) + when "Issue" + subj_attr = HashWithIndifferentAccess.new(data[:issue]) + subject_id = subj_attr[:iid] + subject_desc = "##{subject_id}" + subject_type = "issue" + title = format_title(subj_attr[:title]) + when "MergeRequest" + subj_attr = HashWithIndifferentAccess.new(data[:merge_request]) + subject_id = subj_attr[:iid] + subject_desc = "!#{subject_id}" + subject_type = "merge request" + title = format_title(subj_attr[:title]) + when "Snippet" + subj_attr = HashWithIndifferentAccess.new(data[:snippet]) + subject_id = subj_attr[:id] + subject_desc = "##{subject_id}" + subject_type = "snippet" + title = format_title(subj_attr[:title]) + end + + subject_html = "#{subject_type} #{subject_desc}" + message = ["#{user_name} commented on #{subject_html} in #{project_link}: "] + message << title + + message << "
#{markdown(note, ref: commit_id)}
" + message.join + end + + def create_pipeline_message(data) + pipeline_attributes = data[:object_attributes] + pipeline_id = pipeline_attributes[:id] + ref_type = pipeline_attributes[:tag] ? 'tag' : 'branch' + ref = pipeline_attributes[:ref] + user_name = (data[:user] && data[:user][:name]) || 'API' + status = pipeline_attributes[:status] + duration = pipeline_attributes[:duration] + + branch_link = "#{ref}" + pipeline_url = "##{pipeline_id}" + + "#{project_link}: Pipeline #{pipeline_url} of #{branch_link} #{ref_type} by #{user_name} #{humanized_status(status)} in #{duration} second(s)" + end + + def message_color(data) + pipeline_status_color(data) || color || 'yellow' + end + + def pipeline_status_color(data) + return unless data && data[:object_kind] == 'pipeline' + + case data[:object_attributes][:status] + when 'success' + 'green' + else + 'red' + end + end + + def project_name + project.full_name.gsub(/\s/, '') + end + + def project_url + project.web_url + end + + def project_link + "#{project_name}" + end + + def update?(data) + data[:object_attributes][:action] == 'update' + end + + def humanized_status(status) + case status + when 'success' + 'passed' + else + status + end + end + + def should_pipeline_be_notified?(data) + case data[:object_attributes][:status] + when 'success' + !notify_only_broken_pipelines? + when 'failed' + true + else + false + end + end +end diff --git a/app/models/service.rb b/app/models/service.rb index da523bfa426..cdae99d7727 100644 --- a/app/models/service.rb +++ b/app/models/service.rb @@ -255,6 +255,7 @@ class Service < ActiveRecord::Base external_wiki flowdock hangouts_chat + hipchat irker jira kubernetes diff --git a/changelogs/unreleased/restore-hipchat.yml b/changelogs/unreleased/restore-hipchat.yml new file mode 100644 index 00000000000..a4605a313cc --- /dev/null +++ b/changelogs/unreleased/restore-hipchat.yml @@ -0,0 +1,5 @@ +--- +title: Restore HipChat project service +merge_request: 27172 +author: +type: change diff --git a/config/initializers/hipchat_client_patch.rb b/config/initializers/hipchat_client_patch.rb new file mode 100644 index 00000000000..1879ecb15fb --- /dev/null +++ b/config/initializers/hipchat_client_patch.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true +# This monkey patches the HTTParty used in https://github.com/hipchat/hipchat-rb. +module HipChat + class Client + connection_adapter ::Gitlab::ProxyHTTPConnectionAdapter + end + + class Room + connection_adapter ::Gitlab::ProxyHTTPConnectionAdapter + end + + class User + connection_adapter ::Gitlab::ProxyHTTPConnectionAdapter + end +end diff --git a/db/migrate/20190107151029_remove_hipchat_services.rb b/db/migrate/20190107151029_remove_hipchat_services.rb deleted file mode 100644 index 4741ec88907..00000000000 --- a/db/migrate/20190107151029_remove_hipchat_services.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -# See http://doc.gitlab.com/ce/development/migration_style_guide.html -# for more information on how to write migrations for GitLab. - -class RemoveHipchatServices < ActiveRecord::Migration[5.0] - DOWNTIME = false - - def up - execute "DELETE FROM services WHERE type = 'HipchatService'" - end - - def down - # no-op - end -end diff --git a/doc/api/services.md b/doc/api/services.md index dcc168af8d0..f4e7e72e05d 100644 --- a/doc/api/services.md +++ b/doc/api/services.md @@ -449,6 +449,45 @@ Get Hangouts Chat service settings for a project. GET /projects/:id/services/hangouts-chat ``` +## HipChat + +Private group chat and IM + +### Create/Edit HipChat service + +Set HipChat service for a project. + +``` +PUT /projects/:id/services/hipchat +``` + +Parameters: + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `token` | string | true | Room token | +| `color` | string | false | The room color | +| `notify` | boolean | false | Enable notifications | +| `room` | string | false |Room name or ID | +| `api_version` | string | false | Leave blank for default (v2) | +| `server` | string | false | Leave blank for default. For example, `https://hipchat.example.com`. | + +### Delete HipChat service + +Delete HipChat service for a project. + +``` +DELETE /projects/:id/services/hipchat +``` + +### Get HipChat service settings + +Get HipChat service settings for a project. + +``` +GET /projects/:id/services/hipchat +``` + ## Irker (IRC gateway) Send IRC messages, on update, to a list of recipients through an Irker gateway. diff --git a/doc/integration/README.md b/doc/integration/README.md index f5bc0693b84..a539933f223 100644 --- a/doc/integration/README.md +++ b/doc/integration/README.md @@ -29,8 +29,8 @@ See the documentation below for details on how to configure these services. ## Project services -Integration with services such as Campfire, Flowdock, Pivotal Tracker, and Slack -are available in the form of a [Project Service][]. +Integration with services such as Campfire, Flowdock, HipChat, +Pivotal Tracker, and Slack are available in the form of a [Project Service][]. [Project Service]: ../user/project/integrations/project_services.md diff --git a/doc/project_services/hipchat.md b/doc/project_services/hipchat.md new file mode 100644 index 00000000000..4ae9f6c6b2e --- /dev/null +++ b/doc/project_services/hipchat.md @@ -0,0 +1 @@ +This document was moved to [user/project/integrations/hipchat.md](../user/project/integrations/hipchat.md). diff --git a/doc/university/glossary/README.md b/doc/university/glossary/README.md index 254e234a22c..0af2f8d2f54 100644 --- a/doc/university/glossary/README.md +++ b/doc/university/glossary/README.md @@ -41,7 +41,7 @@ Objects (usually binary and large) created by a build process. These can include ### Atlassian -A [company](https://www.atlassian.com) that develops software products for developers and project managers including Bitbucket, Jira, Confluence, Bamboo. +A [company](https://www.atlassian.com) that develops software products for developers and project managers including Bitbucket, Jira, Hipchat, Confluence, Bamboo. ### Audit Log diff --git a/doc/user/index.md b/doc/user/index.md index b84879601ff..aec314c7784 100644 --- a/doc/user/index.md +++ b/doc/user/index.md @@ -65,9 +65,7 @@ With GitLab Enterprise Edition, you can also: - View the current health and status of each CI environment running on Kubernetes with [Deploy Boards](https://docs.gitlab.com/ee/user/project/deploy_boards.html) - Leverage continuous delivery method with [Canary Deployments](https://docs.gitlab.com/ee/user/project/canary_deployments.html) -You can also [integrate](project/integrations/project_services.md) GitLab with -numerous third-party applications, such as Mattermost, Microsoft Teams, Trello, -Slack, Bamboo CI, JIRA, and a lot more. +You can also [integrate](project/integrations/project_services.md) GitLab with numerous third-party applications, such as Mattermost, Microsoft Teams, HipChat, Trello, Slack, Bamboo CI, JIRA, and a lot more. ## Projects diff --git a/doc/user/project/integrations/hipchat.md b/doc/user/project/integrations/hipchat.md new file mode 100644 index 00000000000..0fd847d415f --- /dev/null +++ b/doc/user/project/integrations/hipchat.md @@ -0,0 +1,53 @@ +# 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: +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. Navigate to the [Integrations page](project_services.md#accessing-the-project-services) +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/user/project/integrations/project_services.md b/doc/user/project/integrations/project_services.md index e2f23827360..42c7824a125 100644 --- a/doc/user/project/integrations/project_services.md +++ b/doc/user/project/integrations/project_services.md @@ -36,6 +36,7 @@ Click on the service links to see further configuration instructions and details | External Wiki | Replaces the link to the internal wiki with a link to an external wiki | | Flowdock | Flowdock is a collaboration web app for technical teams | | [Hangouts Chat](hangouts_chat.md) | Receive events notifications in Google Hangouts Chat | +| [HipChat](hipchat.md) | Private group chat and IM | | [Irker (IRC gateway)](irker.md) | Send IRC messages, on update, to a list of recipients through an Irker gateway | | [JIRA](jira.md) | JIRA issue tracker | | JetBrains TeamCity CI | A continuous integration and build server | diff --git a/lib/api/services.rb b/lib/api/services.rb index bda6be51553..f52bd8c2622 100644 --- a/lib/api/services.rb +++ b/lib/api/services.rb @@ -1,3 +1,4 @@ +# coding: utf-8 # frozen_string_literal: true module API class Services < Grape::API @@ -371,6 +372,44 @@ module API }, CHAT_NOTIFICATION_EVENTS ].flatten, + 'hipchat' => [ + { + required: true, + name: :token, + type: String, + desc: 'The room token' + }, + { + required: false, + name: :room, + type: String, + desc: 'The room name or ID' + }, + { + required: false, + name: :color, + type: String, + desc: 'The room color' + }, + { + required: false, + name: :notify, + type: Boolean, + desc: 'Enable notifications' + }, + { + required: false, + name: :api_version, + type: String, + desc: 'Leave blank for default (v2)' + }, + { + required: false, + name: :server, + type: String, + desc: 'Leave blank for default. https://hipchat.example.com' + } + ], 'irker' => [ { required: true, @@ -674,6 +713,7 @@ module API ExternalWikiService, FlowdockService, HangoutsChatService, + HipchatService, IrkerService, JiraService, KubernetesService, diff --git a/spec/factories/services.rb b/spec/factories/services.rb index 70c34f8640b..0d8c26a2ee9 100644 --- a/spec/factories/services.rb +++ b/spec/factories/services.rb @@ -62,4 +62,10 @@ FactoryBot.define do project_key: 'jira-key' ) end + + factory :hipchat_service do + project + type 'HipchatService' + token 'test_token' + end end diff --git a/spec/features/projects/services/disable_triggers_spec.rb b/spec/features/projects/services/disable_triggers_spec.rb index 65b597da269..1a13fe03a67 100644 --- a/spec/features/projects/services/disable_triggers_spec.rb +++ b/spec/features/projects/services/disable_triggers_spec.rb @@ -14,11 +14,10 @@ describe 'Disable individual triggers' do end context 'service has multiple supported events' do - let(:service_name) { 'JIRA' } + let(:service_name) { 'HipChat' } it 'shows trigger checkboxes' do - event_count = JiraService.supported_events.count - expect(event_count).to be > 1 + event_count = HipchatService.supported_events.count expect(page).to have_content "Trigger" expect(page).to have_css(checkbox_selector, count: event_count) diff --git a/spec/features/projects/services/user_activates_hipchat_spec.rb b/spec/features/projects/services/user_activates_hipchat_spec.rb new file mode 100644 index 00000000000..d6b69a5bd68 --- /dev/null +++ b/spec/features/projects/services/user_activates_hipchat_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'User activates HipChat' do + let(:project) { create(:project) } + let(:user) { create(:user) } + + before do + project.add_maintainer(user) + sign_in(user) + + visit(project_settings_integrations_path(project)) + + click_link('HipChat') + end + + context 'with standart settings' do + it 'activates service' do + check('Active') + fill_in('Room', with: 'gitlab') + fill_in('Token', with: 'verySecret') + click_button('Save') + + expect(page).to have_content('HipChat activated.') + end + end + + context 'with custom settings' do + it 'activates service' do + check('Active') + fill_in('Room', with: 'gitlab_custom') + fill_in('Token', with: 'secretCustom') + fill_in('Server', with: 'https://chat.example.com') + click_button('Save') + + expect(page).to have_content('HipChat activated.') + end + end +end diff --git a/spec/features/projects/services/user_views_services_spec.rb b/spec/features/projects/services/user_views_services_spec.rb index b0a838a7d2b..e9c8cf0fe34 100644 --- a/spec/features/projects/services/user_views_services_spec.rb +++ b/spec/features/projects/services/user_views_services_spec.rb @@ -14,6 +14,7 @@ describe 'User views services' do it 'shows the list of available services' do expect(page).to have_content('Project services') expect(page).to have_content('Campfire') + expect(page).to have_content('HipChat') expect(page).to have_content('Assembla') expect(page).to have_content('Pushover') expect(page).to have_content('Atlassian Bamboo') @@ -21,7 +22,5 @@ describe 'User views services' do expect(page).to have_content('Asana') expect(page).to have_content('Irker (IRC gateway)') expect(page).to have_content('Packagist') - expect(page).to have_content('Mattermost') - expect(page).to have_content('Slack') end end diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index 01da3ea7081..017624d7b55 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -220,6 +220,7 @@ project: - packagist_service - pivotaltracker_service - prometheus_service +- hipchat_service - flowdock_service - assembla_service - asana_service diff --git a/spec/lib/gitlab/import_export/project.json b/spec/lib/gitlab/import_export/project.json index 773651dd226..4a7accc4c52 100644 --- a/spec/lib/gitlab/import_export/project.json +++ b/spec/lib/gitlab/import_export/project.json @@ -6794,6 +6794,28 @@ "default": false, "wiki_page_events": true }, + { + "id": 93, + "title": "HipChat", + "project_id": 5, + "created_at": "2016-06-14T15:01:51.219Z", + "updated_at": "2016-06-14T15:01:51.219Z", + "active": false, + "properties": { + "notify_only_broken_pipelines": true + }, + "template": false, + "push_events": true, + "issues_events": true, + "merge_requests_events": true, + "tag_push_events": true, + "note_events": true, + "pipeline_events": true, + "type": "HipchatService", + "category": "common", + "default": false, + "wiki_page_events": true + }, { "id": 91, "title": "Flowdock", diff --git a/spec/models/project_services/hipchat_service_spec.rb b/spec/models/project_services/hipchat_service_spec.rb new file mode 100644 index 00000000000..b9c6213ed06 --- /dev/null +++ b/spec/models/project_services/hipchat_service_spec.rb @@ -0,0 +1,410 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe HipchatService do + describe "Associations" do + it { is_expected.to belong_to :project } + it { is_expected.to have_one :service_hook } + end + + describe 'Validations' do + context 'when service is active' do + before do + subject.active = true + end + + it { is_expected.to validate_presence_of(:token) } + end + + context 'when service is inactive' do + before do + subject.active = false + end + + it { is_expected.not_to validate_presence_of(:token) } + end + end + + describe "Execute" do + let(:hipchat) { described_class.new } + let(:user) { create(:user) } + let(:project) { create(:project, :repository) } + let(:api_url) { 'https://hipchat.example.com/v2/room/123456/notification?auth_token=verySecret' } + let(:project_name) { project.full_name.gsub(/\s/, '') } + let(:token) { 'verySecret' } + let(:server_url) { 'https://hipchat.example.com'} + let(:push_sample_data) do + Gitlab::DataBuilder::Push.build_sample(project, user) + end + + before do + allow(hipchat).to receive_messages( + project_id: project.id, + project: project, + room: 123456, + server: server_url, + token: token + ) + WebMock.stub_request(:post, api_url) + end + + it 'tests and return errors' do + allow(hipchat).to receive(:execute).and_raise(StandardError, 'no such room') + result = hipchat.test(push_sample_data) + + expect(result[:success]).to be_falsey + expect(result[:result].to_s).to eq('no such room') + end + + it 'uses v1 if version is provided' do + allow(hipchat).to receive(:api_version).and_return('v1') + expect(HipChat::Client).to receive(:new).with( + token, + api_version: 'v1', + server_url: server_url + ).and_return(double(:hipchat_service).as_null_object) + hipchat.execute(push_sample_data) + end + + it 'uses v2 as the version when nothing is provided' do + allow(hipchat).to receive(:api_version).and_return('') + expect(HipChat::Client).to receive(:new).with( + token, + api_version: 'v2', + server_url: server_url + ).and_return(double(:hipchat_service).as_null_object) + hipchat.execute(push_sample_data) + end + + context 'push events' do + it "calls Hipchat API for push events" do + hipchat.execute(push_sample_data) + + expect(WebMock).to have_requested(:post, api_url).once + end + + it "creates a push message" do + message = hipchat.send(:create_push_message, push_sample_data) + + push_sample_data[:object_attributes] + branch = push_sample_data[:ref].gsub('refs/heads/', '') + expect(message).to include("#{user.name} pushed to branch " \ + "#{branch} of " \ + "#{project_name}") + end + end + + context 'tag_push events' do + let(:push_sample_data) do + Gitlab::DataBuilder::Push.build( + project, + user, + Gitlab::Git::BLANK_SHA, + '1' * 40, + 'refs/tags/test', + []) + end + + it "calls Hipchat API for tag push events" do + hipchat.execute(push_sample_data) + + expect(WebMock).to have_requested(:post, api_url).once + end + + it "creates a tag push message" do + message = hipchat.send(:create_push_message, push_sample_data) + + push_sample_data[:object_attributes] + expect(message).to eq("#{user.name} pushed new tag " \ + "test to " \ + "#{project_name}\n") + end + end + + context 'issue events' do + let(:issue) { create(:issue, title: 'Awesome issue', description: '**please** fix') } + let(:issue_service) { Issues::CreateService.new(project, user) } + let(:issues_sample_data) { issue_service.hook_data(issue, 'open') } + + it "calls Hipchat API for issue events" do + hipchat.execute(issues_sample_data) + + expect(WebMock).to have_requested(:post, api_url).once + end + + it "creates an issue message" do + message = hipchat.send(:create_issue_message, issues_sample_data) + + obj_attr = issues_sample_data[:object_attributes] + expect(message).to eq("#{user.name} opened " \ + "issue ##{obj_attr["iid"]} in " \ + "#{project_name}: " \ + "Awesome issue" \ + "
please fix
") + end + end + + context 'merge request events' do + let(:merge_request) { create(:merge_request, description: '**please** fix', title: 'Awesome merge request', target_project: project, source_project: project) } + let(:merge_service) { MergeRequests::CreateService.new(project, user) } + let(:merge_sample_data) { merge_service.hook_data(merge_request, 'open') } + + it "calls Hipchat API for merge requests events" do + hipchat.execute(merge_sample_data) + + expect(WebMock).to have_requested(:post, api_url).once + end + + it "creates a merge request message" do + message = hipchat.send(:create_merge_request_message, + merge_sample_data) + + obj_attr = merge_sample_data[:object_attributes] + expect(message).to eq("#{user.name} opened " \ + "merge request !#{obj_attr["iid"]} in " \ + "#{project_name}: " \ + "Awesome merge request" \ + "
please fix
") + end + end + + context "Note events" do + let(:user) { create(:user) } + let(:project) { create(:project, :repository, creator: user) } + + context 'when commit comment event triggered' do + let(:commit_note) do + create(:note_on_commit, author: user, project: project, + commit_id: project.repository.commit.id, + note: 'a comment on a commit') + end + + it "calls Hipchat API for commit comment events" do + data = Gitlab::DataBuilder::Note.build(commit_note, user) + hipchat.execute(data) + + expect(WebMock).to have_requested(:post, api_url).once + + message = hipchat.send(:create_message, data) + + obj_attr = data[:object_attributes] + commit_id = Commit.truncate_sha(data[:commit][:id]) + title = hipchat.send(:format_title, data[:commit][:message]) + + expect(message).to eq("#{user.name} commented on " \ + "commit #{commit_id} in " \ + "#{project_name}: " \ + "#{title}" \ + "
a comment on a commit
") + end + end + + context 'when merge request comment event triggered' do + let(:merge_request) do + create(:merge_request, source_project: project, + target_project: project) + end + + let(:merge_request_note) do + create(:note_on_merge_request, noteable: merge_request, + project: project, + note: "merge request **note**") + end + + it "calls Hipchat API for merge request comment events" do + data = Gitlab::DataBuilder::Note.build(merge_request_note, user) + hipchat.execute(data) + + expect(WebMock).to have_requested(:post, api_url).once + + message = hipchat.send(:create_message, data) + + obj_attr = data[:object_attributes] + merge_id = data[:merge_request]['iid'] + title = data[:merge_request]['title'] + + expect(message).to eq("#{user.name} commented on " \ + "merge request !#{merge_id} in " \ + "#{project_name}: " \ + "#{title}" \ + "
merge request note
") + end + end + + context 'when issue comment event triggered' do + let(:issue) { create(:issue, project: project) } + let(:issue_note) do + create(:note_on_issue, noteable: issue, project: project, + note: "issue **note**") + end + + it "calls Hipchat API for issue comment events" do + data = Gitlab::DataBuilder::Note.build(issue_note, user) + hipchat.execute(data) + + message = hipchat.send(:create_message, data) + + obj_attr = data[:object_attributes] + issue_id = data[:issue]['iid'] + title = data[:issue]['title'] + + expect(message).to eq("#{user.name} commented on " \ + "issue ##{issue_id} in " \ + "#{project_name}: " \ + "#{title}" \ + "
issue note
") + end + + context 'with confidential issue' do + before do + issue.update!(confidential: true) + end + + it 'calls Hipchat API with issue comment' do + data = Gitlab::DataBuilder::Note.build(issue_note, user) + hipchat.execute(data) + + message = hipchat.send(:create_message, data) + + expect(message).to include("
issue note
") + end + end + end + + context 'when snippet comment event triggered' do + let(:snippet) { create(:project_snippet, project: project) } + let(:snippet_note) do + create(:note_on_project_snippet, noteable: snippet, + project: project, + note: "snippet note") + end + + it "calls Hipchat API for snippet comment events" do + data = Gitlab::DataBuilder::Note.build(snippet_note, user) + hipchat.execute(data) + + expect(WebMock).to have_requested(:post, api_url).once + + message = hipchat.send(:create_message, data) + + obj_attr = data[:object_attributes] + snippet_id = data[:snippet]['id'] + title = data[:snippet]['title'] + + expect(message).to eq("#{user.name} commented on " \ + "snippet ##{snippet_id} in " \ + "#{project_name}: " \ + "#{title}" \ + "
snippet note
") + end + end + end + + context 'pipeline events' do + let(:pipeline) { create(:ci_empty_pipeline, user: create(:user)) } + let(:data) { Gitlab::DataBuilder::Pipeline.build(pipeline) } + + context 'for failed' do + before do + pipeline.drop + end + + it "calls Hipchat API" do + hipchat.execute(data) + + expect(WebMock).to have_requested(:post, api_url).once + end + + it "creates a build message" do + message = hipchat.__send__(:create_pipeline_message, data) + + project_url = project.web_url + project_name = project.full_name.gsub(/\s/, '') + pipeline_attributes = data[:object_attributes] + ref = pipeline_attributes[:ref] + ref_type = pipeline_attributes[:tag] ? 'tag' : 'branch' + duration = pipeline_attributes[:duration] + user_name = data[:user][:name] + + expect(message).to eq("#{project_name}: " \ + "Pipeline ##{pipeline.id} " \ + "of #{ref} #{ref_type} " \ + "by #{user_name} failed in #{duration} second(s)") + end + end + + context 'for succeeded' do + before do + pipeline.succeed + end + + it "calls Hipchat API" do + hipchat.notify_only_broken_pipelines = false + hipchat.execute(data) + expect(WebMock).to have_requested(:post, api_url).once + end + + it "notifies only broken" do + hipchat.notify_only_broken_pipelines = true + hipchat.execute(data) + expect(WebMock).not_to have_requested(:post, api_url).once + end + end + end + + context "#message_options" do + it "is set to the defaults" do + expect(hipchat.__send__(:message_options)).to eq({ notify: false, color: 'yellow' }) + end + + it "sets notify to true" do + allow(hipchat).to receive(:notify).and_return('1') + + expect(hipchat.__send__(:message_options)).to eq({ notify: true, color: 'yellow' }) + end + + it "sets the color" do + allow(hipchat).to receive(:color).and_return('red') + + expect(hipchat.__send__(:message_options)).to eq({ notify: false, color: 'red' }) + end + + context 'with a successful build' do + it 'uses the green color' do + data = { object_kind: 'pipeline', + object_attributes: { status: 'success' } } + + expect(hipchat.__send__(:message_options, data)).to eq({ notify: false, color: 'green' }) + end + end + + context 'with a failed build' do + it 'uses the red color' do + data = { object_kind: 'pipeline', + object_attributes: { status: 'failed' } } + + expect(hipchat.__send__(:message_options, data)).to eq({ notify: false, color: 'red' }) + end + end + end + end + + context 'with UrlBlocker' do + let(:user) { create(:user) } + let(:project) { create(:project, :repository) } + let(:hipchat) { described_class.new(project: project) } + let(:push_sample_data) { Gitlab::DataBuilder::Push.build_sample(project, user) } + + describe '#execute' do + before do + hipchat.server = 'http://localhost:9123' + end + + it 'raises UrlBlocker for localhost' do + expect(Gitlab::UrlBlocker).to receive(:validate!).and_call_original + expect { hipchat.execute(push_sample_data) }.to raise_error(Gitlab::HTTP::BlockedUrlError) + end + end + end +end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 3beddaeddbd..b09ea108e81 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -41,6 +41,7 @@ describe Project do it { is_expected.to have_one(:pipelines_email_service) } it { is_expected.to have_one(:irker_service) } it { is_expected.to have_one(:pivotaltracker_service) } + it { is_expected.to have_one(:hipchat_service) } it { is_expected.to have_one(:flowdock_service) } it { is_expected.to have_one(:assembla_service) } it { is_expected.to have_one(:slack_slash_commands_service) } diff --git a/vendor/licenses.csv b/vendor/licenses.csv index ed79ec5bac3..d706d76358a 100644 --- a/vendor/licenses.csv +++ b/vendor/licenses.csv @@ -520,6 +520,7 @@ hashie-forbidden_attributes,0.1.1,MIT he,1.1.1,MIT health_check,2.6.0,MIT highlight.js,9.13.1,New BSD +hipchat,1.5.2,MIT hmac-drbg,1.0.1,MIT hoopy,0.1.4,MIT html-pipeline,2.8.4,MIT -- GitLab