diff --git a/CHANGELOG b/CHANGELOG index 2d41a65d2df..d538bb42992 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -5,6 +5,7 @@ v 7.13.0 (unreleased) - Fix external issue tracker hook/test for HTTPS URLs (Daniel Gerhardt) - Remove link leading to a 404 error in Deploy Keys page (Stan Hu) - Add support for unlocking users in admin settings (Stan Hu) + - Add Irker service configuration options (Stan Hu) - Fix order of issues imported form GitHub (Hiroyuki Sato) - Bump rugments to 1.0.0beta8 to fix C prototype function highlighting (Jonathon Reinhart) - Fix Merge Request webhook to properly fire "merge" action when accepted from the web UI @@ -39,6 +40,8 @@ v 7.13.0 (unreleased) v 7.12.2 - Correctly show anonymous authorized applications under Profile > Applications. + - Faster automerge check and merge itself when source and target branches are in same repository + - Audit log for user authentication v 7.12.1 - Fix error when deleting a user who has projects (Stan Hu) diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index 765adaf2128..fd51b380da2 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -28,6 +28,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController # Do additional LDAP checks for the user filter and EE features if @user.allowed? + log_audit_event(gl_user, with: :ldap) sign_in_and_redirect(gl_user) else flash[:alert] = "Access denied for your LDAP account." @@ -47,6 +48,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController if current_user # Add new authentication method current_user.identities.find_or_create_by(extern_uid: oauth['uid'], provider: oauth['provider']) + log_audit_event(current_user, with: oauth['provider']) redirect_to profile_account_path, notice: 'Authentication method updated' else @user = Gitlab::OAuth::User.new(oauth) @@ -54,6 +56,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController # Only allow properly saved users to login. if @user.persisted? && @user.valid? + log_audit_event(@user.gl_user, with: oauth['provider']) sign_in_and_redirect(@user.gl_user) else error_message = @@ -83,4 +86,9 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController def oauth @oauth ||= request.env['omniauth.auth'] end + + def log_audit_event(user, options = {}) + AuditEventService.new(user, user, options). + for_authentication.security_event + end end diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb index 5382a6cf6ac..26a4de15462 100644 --- a/app/controllers/profiles_controller.rb +++ b/app/controllers/profiles_controller.rb @@ -38,8 +38,11 @@ class ProfilesController < Profiles::ApplicationController redirect_to profile_account_path end - def history - @events = current_user.recent_events.page(params[:page]).per(PER_PAGE) + def audit_log + @events = AuditEvent.where(entity_type: "User", entity_id: current_user.id). + order("created_at DESC"). + page(params[:page]). + per(PER_PAGE) end def update_username diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb index dc18bbd8d5b..1e435be8275 100644 --- a/app/controllers/projects/services_controller.rb +++ b/app/controllers/projects/services_controller.rb @@ -7,7 +7,8 @@ class Projects::ServicesController < Projects::ApplicationController :colorize_messages, :channels, :push_events, :issues_events, :merge_requests_events, :tag_push_events, :note_events, :send_from_committer_email, :disable_diffs, :external_wiki_url, - :notify, :color] + :notify, :color, + :server_host, :server_port, :default_irc_uri] # Authorize before_action :authorize_admin_project! before_action :service, only: [:edit, :update, :test] diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 7577fc96d6d..89629bc0581 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -37,6 +37,8 @@ class SessionsController < Devise::SessionsController resource.update_attributes(reset_password_token: nil, reset_password_sent_at: nil) end + authenticated_with = user_params[:otp_attempt] ? "two-factor" : "standard" + log_audit_event(current_user, with: authenticated_with) end end @@ -95,4 +97,9 @@ class SessionsController < Devise::SessionsController user.valid_otp?(user_params[:otp_attempt]) || user.invalidate_otp_backup_code!(user_params[:otp_attempt]) end + + def log_audit_event(user, options = {}) + AuditEventService.new(user, user, options). + for_authentication.security_event + end end diff --git a/app/models/audit_event.rb b/app/models/audit_event.rb new file mode 100644 index 00000000000..967ffd46db0 --- /dev/null +++ b/app/models/audit_event.rb @@ -0,0 +1,19 @@ +class AuditEvent < ActiveRecord::Base + serialize :details, Hash + + belongs_to :user, foreign_key: :author_id + + validates :author_id, presence: true + validates :entity_id, presence: true + validates :entity_type, presence: true + + after_initialize :initialize_details + + def initialize_details + self.details = {} if details.nil? + end + + def author_name + self.user.name + end +end diff --git a/app/models/project_services/irker_service.rb b/app/models/project_services/irker_service.rb index 89f312e8c98..a4d0914dbe7 100644 --- a/app/models/project_services/irker_service.rb +++ b/app/models/project_services/irker_service.rb @@ -21,26 +21,11 @@ require 'uri' class IrkerService < Service + prop_accessor :server_host, :server_port, :default_irc_uri prop_accessor :colorize_messages, :recipients, :channels validates :recipients, presence: true, if: :activated? - validate :check_recipients_count, if: :activated? before_validation :get_channels - after_initialize :initialize_settings - - # Writer for RSpec tests - attr_writer :settings - - def initialize_settings - # See the documentation (doc/project_services/irker.md) for possible values - # here - @settings ||= { - server_ip: 'localhost', - server_port: 6659, - max_channels: 3, - default_irc_uri: nil - } - end def title 'Irker (IRC gateway)' @@ -51,20 +36,6 @@ class IrkerService < Service 'gateway.' end - def help - msg = 'Recipients have to be specified with a full URI: '\ - 'irc[s]://irc.network.net[:port]/#channel. Special cases: if you want '\ - 'the channel to be a nickname instead, append ",isnick" to the channel '\ - 'name; if the channel is protected by a secret password, append '\ - '"?key=secretpassword" to the URI.' - - unless @settings[:default_irc].nil? - msg += ' Note that a default IRC URI is provided by this service\'s '\ - "administrator: #{default_irc}. You can thus just give a channel name." - end - msg - end - def to_param 'irker' end @@ -77,31 +48,46 @@ class IrkerService < Service return unless supported_events.include?(data[:object_kind]) IrkerWorker.perform_async(project_id, channels, - colorize_messages, data, @settings) + colorize_messages, data, settings) + end + + def settings + { server_host: server_host.present? ? server_host : 'localhost', + server_port: server_port.present? ? server_port : 6659 + } end def fields [ + { type: 'text', name: 'server_host', placeholder: 'localhost', + help: 'Irker daemon hostname (defaults to localhost)' }, + { type: 'text', name: 'server_port', placeholder: 6659, + help: 'Irker daemon port (defaults to 6659)' }, + { type: 'text', name: 'default_irc_uri', + help: 'A default IRC URI to prepend before each recipient (optional)', + placeholder: 'irc://irc.network.net:6697/' }, { type: 'textarea', name: 'recipients', - placeholder: 'Recipients/channels separated by whitespaces' }, + placeholder: 'Recipients/channels separated by whitespaces', + help: 'Recipients have to be specified with a full URI: '\ + 'irc[s]://irc.network.net[:port]/#channel. Special cases: if '\ + 'you want the channel to be a nickname instead, append ",isnick" to ' \ + 'the channel name; if the channel is protected by a secret password, ' \ + ' append "?key=secretpassword" to the URI. Note that if you specify a ' \ + ' default IRC URI to prepend before each recipient, you can just give ' \ + ' a channel name.' }, { type: 'checkbox', name: 'colorize_messages' }, ] end + def help + ' NOTE: Irker does NOT have built-in authentication, which makes it' \ + ' vulnerable to spamming IRC channels if it is hosted outside of a ' \ + ' firewall. Please make sure you run the daemon within a secured network ' \ + ' to prevent abuse. For more details, read: http://www.catb.org/~esr/irker/security.html.' + end + private - def check_recipients_count - return true if recipients.nil? || recipients.empty? - - if recipients.split(/\s+/).count > max_chans - errors.add(:recipients, "are limited to #{max_chans}") - end - end - - def max_chans - @settings[:max_channels] - end - def get_channels return true unless :activated? return true if recipients.nil? || recipients.empty? @@ -114,40 +100,35 @@ class IrkerService < Service def map_recipients self.channels = recipients.split(/\s+/).map do |recipient| - format_channel default_irc_uri, recipient + format_channel(recipient) end channels.reject! &:nil? end - def default_irc_uri - default_irc = @settings[:default_irc_uri] - if !(default_irc.nil? || default_irc[-1] == '/') - default_irc += '/' - end - default_irc - end - - def format_channel(default_irc, recipient) - cnt = 0 - url = nil + def format_channel(recipient) + uri = nil # Try to parse the chan as a full URI begin - uri = URI.parse(recipient) - raise URI::InvalidURIError if uri.scheme.nil? && cnt == 0 + uri = consider_uri(URI.parse(recipient)) rescue URI::InvalidURIError - unless default_irc.nil? - cnt += 1 - recipient = "#{default_irc}#{recipient}" - retry if cnt == 1 - end - else - url = consider_uri uri end - url + + unless uri.present? and default_irc_uri.nil? + begin + new_recipient = URI.join(default_irc_uri, '/', recipient).to_s + uri = consider_uri(URI.parse(new_recipient)) + rescue + Rails.logger.error("Unable to create a valid URL from #{default_irc_uri} and #{recipient}") + end + end + + uri end def consider_uri(uri) + return nil if uri.scheme.nil? + # Authorize both irc://domain.com/#chan and irc://domain.com/chan if uri.is_a?(URI) && uri.scheme[/^ircs?\z/] && !uri.path.nil? # Do not authorize irc://domain.com/ diff --git a/app/models/security_event.rb b/app/models/security_event.rb new file mode 100644 index 00000000000..d131c11cb6c --- /dev/null +++ b/app/models/security_event.rb @@ -0,0 +1,2 @@ +class SecurityEvent < AuditEvent +end diff --git a/app/services/audit_event_service.rb b/app/services/audit_event_service.rb new file mode 100644 index 00000000000..a7f090655e1 --- /dev/null +++ b/app/services/audit_event_service.rb @@ -0,0 +1,25 @@ +class AuditEventService + def initialize(author, entity, details = {}) + @author, @entity, @details = author, entity, details + end + + def for_authentication + @details = { + with: @details[:with], + target_id: @author.id, + target_type: "User", + target_details: @author.name, + } + + self + end + + def security_event + SecurityEvent.create( + author_id: @author.id, + entity_id: @entity.id, + entity_type: @entity.class.name, + details: @details + ) + end +end diff --git a/app/views/layouts/nav/_profile.html.haml b/app/views/layouts/nav/_profile.html.haml index 914e1b83d1f..de5544268a1 100644 --- a/app/views/layouts/nav/_profile.html.haml +++ b/app/views/layouts/nav/_profile.html.haml @@ -44,8 +44,8 @@ = icon('image fw') %span Preferences - = nav_link(path: 'profiles#history') do - = link_to history_profile_path, title: 'History', data: {placement: 'right'} do + = nav_link(path: 'profiles#audit_log') do + = link_to audit_log_profile_path, title: 'Audit Log', data: {placement: 'right'} do = icon('history fw') %span - History + Audit Log diff --git a/app/views/profiles/_event_table.html.haml b/app/views/profiles/_event_table.html.haml new file mode 100644 index 00000000000..c19ac429d52 --- /dev/null +++ b/app/views/profiles/_event_table.html.haml @@ -0,0 +1,16 @@ +%table.table#audits + %thead + %tr + %th Action + %th When + + %tbody + - events.each do |event| + %tr + %td + %span + Signed in with + %b= event.details[:with] + authentication + %td #{time_ago_in_words event.created_at} ago += paginate events, theme: "gitlab" diff --git a/app/views/profiles/audit_log.html.haml b/app/views/profiles/audit_log.html.haml new file mode 100644 index 00000000000..698d6037428 --- /dev/null +++ b/app/views/profiles/audit_log.html.haml @@ -0,0 +1,5 @@ +- page_title "Audit Log" +%h3.page-title Audit Log +%p.light History of authentications + += render 'event_table', events: @events \ No newline at end of file diff --git a/app/views/profiles/history.html.haml b/app/views/profiles/history.html.haml deleted file mode 100644 index b414fb69f4e..00000000000 --- a/app/views/profiles/history.html.haml +++ /dev/null @@ -1,11 +0,0 @@ -- page_title "History" -%h3.page-title - Your Account History -%p.light - All events created by your account are listed below. -%hr -.profile_history - = render @events -%hr -= paginate @events, theme: "gitlab" - diff --git a/app/workers/irker_worker.rb b/app/workers/irker_worker.rb index 84a54656df2..2d44d8d4dc6 100644 --- a/app/workers/irker_worker.rb +++ b/app/workers/irker_worker.rb @@ -19,7 +19,7 @@ class IrkerWorker branch = "\x0305#{branch}\x0f" end - # Firsts messages are for branch creation/deletion + # First messages are for branch creation/deletion send_branch_updates push_data, project, repo_name, committer, branch # Next messages are for commits @@ -34,7 +34,7 @@ class IrkerWorker def init_perform(set, chans, colors) @colors = colors @channels = chans - start_connection set['server_ip'], set['server_port'] + start_connection set['server_host'], set['server_port'] end def start_connection(irker_server, irker_port) diff --git a/config/routes.rb b/config/routes.rb index f904c975733..8617839a256 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -208,7 +208,7 @@ Gitlab::Application.routes.draw do # resource :profile, only: [:show, :update] do member do - get :history + get :audit_log get :applications put :reset_private_token diff --git a/db/migrate/20141118150935_add_audit_event.rb b/db/migrate/20141118150935_add_audit_event.rb new file mode 100644 index 00000000000..07383c6bbc7 --- /dev/null +++ b/db/migrate/20141118150935_add_audit_event.rb @@ -0,0 +1,22 @@ +class AddAuditEvent < ActiveRecord::Migration + def change + create_table :audit_events do |t| + t.integer :author_id, null: false + t.string :type, null: false + + # "Namespace" where the change occurs + # eg. On a project, group or user + t.integer :entity_id, null: false + t.string :entity_type, null: false + + # Details for the event + t.text :details + + t.timestamps + end + + add_index :audit_events, :author_id + add_index :audit_events, :type + add_index :audit_events, [:entity_id, :entity_type] + end +end diff --git a/db/schema.rb b/db/schema.rb index 3a5af6a76d4..8736d1e0df5 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -28,16 +28,30 @@ ActiveRecord::Schema.define(version: 20150620233230) do t.integer "default_branch_protection", default: 2 t.boolean "twitter_sharing_enabled", default: true t.text "restricted_visibility_levels" - t.boolean "version_check_enabled", default: true t.integer "max_attachment_size", default: 10, null: false t.integer "default_project_visibility" t.integer "default_snippet_visibility" t.text "restricted_signup_domains" + t.boolean "version_check_enabled", default: true t.boolean "user_oauth_applications", default: true t.string "after_sign_out_path" t.integer "session_expire_delay", default: 10080, null: false end + create_table "audit_events", force: true do |t| + t.integer "author_id", null: false + t.string "type", null: false + t.integer "entity_id", null: false + t.string "entity_type", null: false + t.text "details" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "audit_events", ["author_id"], name: "index_audit_events_on_author_id", using: :btree + add_index "audit_events", ["entity_id", "entity_type"], name: "index_audit_events_on_entity_id_and_entity_type", using: :btree + add_index "audit_events", ["type"], name: "index_audit_events_on_type", using: :btree + create_table "broadcast_messages", force: true do |t| t.text "message", null: false t.datetime "starts_at" @@ -496,12 +510,12 @@ ActiveRecord::Schema.define(version: 20150620233230) do t.string "bitbucket_access_token" t.string "bitbucket_access_token_secret" t.string "location" + t.string "public_email", default: "", null: false t.string "encrypted_otp_secret" t.string "encrypted_otp_secret_iv" t.string "encrypted_otp_secret_salt" t.boolean "otp_required_for_login", default: false, null: false t.text "otp_backup_codes" - t.string "public_email", default: "", null: false t.integer "dashboard", default: 0 end diff --git a/doc/markdown/markdown.md b/doc/markdown/markdown.md index 9c7f723c06d..322111ae9e1 100644 --- a/doc/markdown/markdown.md +++ b/doc/markdown/markdown.md @@ -343,6 +343,36 @@ Strikethrough uses two tildes. ~~Scratch this.~~ - Or minuses + Or pluses +If a list item contains multiple paragraphs, +each subsequent paragraph should be indented with four spaces. + +```no-highlight +1. First ordered list item + + Second paragraph of first item. +2. Another item +``` + +1. First ordered list item + + Second paragraph of first item. +2. Another item + +If the second paragraph isn't indented with four spaces, +the second list item will be incorrectly labeled as `1`. + +```no-highlight +1. First ordered list item + + Second paragraph of first item. +2. Another item +``` + +1. First ordered list item + + Second paragraph of first item. +2. Another item + ## Links There are two ways to create links, inline-style and reference-style. diff --git a/doc/project_services/irker.md b/doc/project_services/irker.md index 9875bebf66b..1dbca20baf9 100644 --- a/doc/project_services/irker.md +++ b/doc/project_services/irker.md @@ -9,38 +9,43 @@ See the project homepage for further info: https://gitlab.com/esr/irker ## Needed setup You will first need an Irker daemon. You can download the Irker code from its -gitorious repository on https://gitorious.org/irker: `git clone -git@gitorious.org:irker/irker.git`. Once you have downloaded the code, you can -run the python script named `irkerd`. This script is the gateway script, it acts -both as an IRC client, for sending messages to an IRC server obviously, and as a -TCP server, for receiving messages from the GitLab service. +repository on https://gitlab.com/esr/irker: + +``` +git clone https://gitlab.com/esr/irker.git +``` + +Once you have downloaded the code, you can run the python script named `irkerd`. +This script is the gateway script, it acts both as an IRC client, for sending +messages to an IRC server obviously, and as a TCP server, for receiving messages +from the GitLab service. If the Irker server runs on the same machine, you are done. If not, you will need to follow the firsts steps of the next section. -## Optional setup +## Complete these steps in GitLab: -In the `app/models/project_services/irker_service.rb` file, you can modify some -options in the `initialize_settings` method: -- **server_ip** (defaults to `localhost`): the server IP address where the -`irkerd` daemon runs; -- **server_port** (defaults to `6659`): the server port of the `irkerd` daemon; -- **max_channels** (defaults to `3`): the maximum number of recipients the -client is authorized to join, per project; -- **default_irc_uri** (no default) : if this option is set, it has to be in the -format `irc[s]://domain.name` and will be prepend to each and every channel -provided by the user which is not a full URI. - -If the Irker server and the GitLab application do not run on the same host, you -will **need** to setup at least the **server_ip** option. +1. Navigate to the project you want to configure for notifications. +1. Select "Settings" in the top navigation. +1. Select "Services" in the left navigation. +1. Click "Irker". +1. Select the "Active" checkbox. +1. Enter the server host address where `irkerd` runs (defaults to `localhost`) +in the `Server host` field on the Web page +1. Enter the server port of `irkerd` (e.g. defaults to 6659) in the +`Server port` field on the Web page. +1. Optional: if `Default irc uri` is set, it has to be in the format +`irc[s]://domain.name` and will be prepend to each and every channel provided +by the user which is not a full URI. +1. Specify the recipients (e.g. #channel1, user1, etc.) +1. Save or optionally click "Test Settings". ## Note on Irker recipients Irker accepts channel names of the form `chan` and `#chan`, both for the `#chan` channel. If you want to send messages in query, you will need to add -`,isnick` avec the channel name, in this form: `Aorimn,isnick`. In this latter +`,isnick` after the channel name, in this form: `Aorimn,isnick`. In this latter case, `Aorimn` is treated as a nick and no more as a channel name. Irker can also join password-protected channels. Users need to append `?key=thesecretpassword` to the chan name. - diff --git a/features/profile/active_tab.feature b/features/profile/active_tab.feature index 1fa4ac88ddc..788b7895d72 100644 --- a/features/profile/active_tab.feature +++ b/features/profile/active_tab.feature @@ -23,7 +23,7 @@ Feature: Profile Active Tab Then the active main tab should be Preferences And no other main tabs should be active - Scenario: On Profile History - Given I visit profile history page - Then the active main tab should be History + Scenario: On Profile Audit Log + Given I visit Audit Log page + Then the active main tab should be Audit Log And no other main tabs should be active diff --git a/features/profile/profile.feature b/features/profile/profile.feature index 0dd0afde8b1..7a1345f2b37 100644 --- a/features/profile/profile.feature +++ b/features/profile/profile.feature @@ -63,7 +63,7 @@ Feature: Profile Scenario: I visit history tab Given I have activity - When I visit profile history page + When I visit Audit Log page Then I should see my activity Scenario: I visit my user page diff --git a/features/steps/profile/active_tab.rb b/features/steps/profile/active_tab.rb index 79e3b55f6e1..4724a326277 100644 --- a/features/steps/profile/active_tab.rb +++ b/features/steps/profile/active_tab.rb @@ -19,7 +19,7 @@ class Spinach::Features::ProfileActiveTab < Spinach::FeatureSteps ensure_active_main_tab('Preferences') end - step 'the active main tab should be History' do - ensure_active_main_tab('History') + step 'the active main tab should be Audit Log' do + ensure_active_main_tab('Audit Log') end end diff --git a/features/steps/profile/profile.rb b/features/steps/profile/profile.rb index 11e1163c352..2b6b8b167f6 100644 --- a/features/steps/profile/profile.rb +++ b/features/steps/profile/profile.rb @@ -115,7 +115,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps end step 'I should see my activity' do - expect(page).to have_content "#{current_user.name} closed issue" + expect(page).to have_content "Signed in with standard authentication" end step 'my password is expired' do diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index 4cc01443c8b..fe651e81dac 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -127,8 +127,8 @@ module SharedPaths visit profile_preferences_path end - step 'I visit profile history page' do - visit history_profile_path + step 'I visit Audit Log page' do + visit audit_log_profile_path end # ---------------------------------------- diff --git a/spec/features/security/profile_access_spec.rb b/spec/features/security/profile_access_spec.rb index 8f7a9606262..bcabc2d53ac 100644 --- a/spec/features/security/profile_access_spec.rb +++ b/spec/features/security/profile_access_spec.rb @@ -45,8 +45,8 @@ describe "Profile access", feature: true do it { is_expected.to be_denied_for :visitor } end - describe "GET /profile/history" do - subject { history_profile_path } + describe "GET /profile/audit_log" do + subject { audit_log_profile_path } it { is_expected.to be_allowed_for @u1 } it { is_expected.to be_allowed_for :admin } diff --git a/spec/models/project_services/irker_service_spec.rb b/spec/models/project_services/irker_service_spec.rb index 37690434ec8..7d483a44c53 100644 --- a/spec/models/project_services/irker_service_spec.rb +++ b/spec/models/project_services/irker_service_spec.rb @@ -38,22 +38,6 @@ describe IrkerService do let(:_recipients) { nil } it { should validate_presence_of :recipients } end - - context 'too many recipients' do - let(:_recipients) { 'a b c d' } - it 'should add an error if there is too many recipients' do - subject.send :check_recipients_count - expect(subject.errors).not_to be_blank - end - end - - context '3 recipients' do - let(:_recipients) { 'a b c' } - it 'should not add an error if there is 3 recipients' do - subject.send :check_recipients_count - expect(subject.errors).to be_blank - end - end end describe 'Execute' do @@ -62,7 +46,7 @@ describe IrkerService do let(:project) { create(:project) } let(:sample_data) { Gitlab::PushDataBuilder.build_sample(project, user) } - let(:recipients) { '#commits' } + let(:recipients) { '#commits irc://test.net/#test ftp://bad' } let(:colorize_messages) { '1' } before do @@ -71,17 +55,12 @@ describe IrkerService do project: project, project_id: project.id, service_hook: true, - properties: { - 'recipients' => recipients, - 'colorize_messages' => colorize_messages - } - ) - irker.settings = { - server_ip: 'localhost', + server_host: 'localhost', server_port: 6659, - max_channels: 3, - default_irc_uri: 'irc://chat.freenode.net/' - } + default_irc_uri: 'irc://chat.freenode.net/', + recipients: recipients, + colorize_messages: colorize_messages) + irker.valid? @irker_server = TCPServer.new 'localhost', 6659 end @@ -97,11 +76,8 @@ describe IrkerService do conn.readlines.each do |line| msg = JSON.load(line.chomp("\n")) expect(msg.keys).to match_array(['to', 'privmsg']) - if msg['to'].is_a?(String) - expect(msg['to']).to eq 'irc://chat.freenode.net/#commits' - else - expect(msg['to']).to match_array(['irc://chat.freenode.net/#commits']) - end + expect(msg['to']).to match_array(["irc://chat.freenode.net/#commits", + "irc://test.net/#test"]) end conn.close end diff --git a/spec/routing/routing_spec.rb b/spec/routing/routing_spec.rb index 0fda6202a11..dd045826692 100644 --- a/spec/routing/routing_spec.rb +++ b/spec/routing/routing_spec.rb @@ -108,8 +108,8 @@ describe ProfilesController, "routing" do expect(get("/profile/account")).to route_to('profiles/accounts#show') end - it "to #history" do - expect(get("/profile/history")).to route_to('profiles#history') + it "to #audit_log" do + expect(get("/profile/audit_log")).to route_to('profiles#audit_log') end it "to #reset_private_token" do