Browse Source

Merge branch 'develop' of git.znuny.com:zammad/zammad into develop

Martin Edenhofer 7 years ago
parent
commit
3f633f252a

+ 2 - 2
Gemfile.lock

@@ -1,6 +1,6 @@
 GIT
   remote: https://github.com/thorsteneckel/autodiscover.git
-  revision: 29d713ee0c8c25fcf74c4292ff13fe1fa4d0d827
+  revision: ee9b53dfa797ce6d4f970b82beea7fbdd2df56bb
   specs:
     autodiscover (1.0.2)
       httpclient
@@ -221,7 +221,7 @@ GEM
     mime-types (2.99.3)
     mini_portile2 (2.3.0)
     minitest (5.10.3)
-    multi_json (1.12.1)
+    multi_json (1.12.2)
     multi_xml (0.6.0)
     multipart-post (2.0.0)
     mysql2 (0.4.9)

+ 71 - 28
app/assets/javascripts/app/controllers/_integration/exchange.coffee

@@ -174,17 +174,18 @@ class ConnectionWizard extends App.WizardModal
     'js-mapping': 'mappingShow'
 
   events:
-    'submit form.js-discover':           'discover'
-    'submit form.js-discoverSsl':        'discover'
-    'submit form.js-bind':               'folders'
-    'submit form.js-folders':            'mapping'
-    'click .js-cancelSsl':               'showSlideDiscover'
-    'click .js-mapping .js-submitTry':   'mappingChange'
-    'click .js-try .js-submitSave':      'save'
-    'click .js-close':                   'hide'
-    'click .js-remove':                  'removeRow'
-    'click .js-userMappingForm .js-add': 'addUserMapping'
-    'click .js-goToSlide':               'goToSlide'
+    'submit form.js-discover':                 'discover'
+    'submit form.js-discoverCertificateIssue': 'discover'
+    'submit form.js-bind':                     'folders'
+    'submit form.js-bindCertificateIssue':     'folders'
+    'submit form.js-folders':                  'mapping'
+    'click .js-cancelSsl':                     'showSlideDiscover'
+    'click .js-mapping .js-submitTry':         'mappingChange'
+    'click .js-try .js-submitSave':            'save'
+    'click .js-close':                         'hide'
+    'click .js-remove':                        'removeRow'
+    'click .js-userMappingForm .js-add':       'addUserMapping'
+    'click .js-goToSlide':                     'goToSlide'
 
   elements:
     '.modal-body': 'body'
@@ -261,20 +262,17 @@ class ConnectionWizard extends App.WizardModal
       processData: true
       success: (data, status, xhr) =>
         if data.result isnt 'ok'
-
-          if data.message.indexOf('certificate') is -1
-            @showSlide('js-discover')
-            @showAlert('js-discover', data.message)
-          else
-            @$('.js-discoverSsl input[name="user"]').val(params.user)
-            @$('.js-discoverSsl input[name="password"]').val(params.password)
-            @showSlide('js-discoverSsl')
-
+          @handleCertificateIssue(
+            message:     data.message
+            wizardClass: 'js-discover'
+            user:        params.user
+            password:    params.password
+          )
           return
 
-        @wizardConfig.endpoint = data.endpoint
-        @wizardConfig.user     = params.user
-        @wizardConfig.password = params.password
+        @wizardConfig.disable_ssl_verify = params.disable_ssl_verify
+        @wizardConfig.user               = params.user
+        @wizardConfig.password           = params.password
 
         @showSlide('js-bind')
         @showBindDetails()
@@ -300,13 +298,19 @@ class ConnectionWizard extends App.WizardModal
       processData: true
       success: (data, status, xhr) =>
         if data.result isnt 'ok'
-          @showSlide('js-bind')
-          @showAlert('js-bind', data.message)
+          @handleCertificateIssue(
+            message:     data.message
+            wizardClass: 'js-bind'
+            endpoint:    params.endpoint
+            user:        params.user
+            password:    params.password
+          )
           return
 
-        @wizardConfig.endpoint = params.endpoint
-        @wizardConfig.user     = params.user
-        @wizardConfig.password = params.password
+        @wizardConfig.disable_ssl_verify = params.disable_ssl_verify
+        @wizardConfig.endpoint           = params.endpoint
+        @wizardConfig.user               = params.user
+        @wizardConfig.password           = params.password
 
         # update wizard data
         @wizardConfig.wizardData = {}
@@ -341,6 +345,45 @@ class ConnectionWizard extends App.WizardModal
           @foldersSelectSubmit.addClass('is-disabled')
     )
 
+  handleCertificateIssue: (params) =>
+    if params.message.indexOf('certificate') is -1
+      @showSlide(params.wizardClass)
+      @showAlert(params.wizardClass, params.message)
+    else
+      wizardClass = "#{params.wizardClass}CertificateIssue"
+
+      domain = @domainFromMessageOrEmail(
+        message: params.message
+        user:    params.user
+      )
+
+      wizardSlide = App.view('integration/exchange_certificate_issue')(
+        wizardClass: wizardClass
+        endpoint:    params.endpoint
+        user:        params.user
+        password:    params.password
+        domain:      domain
+      )
+
+      @$('.js-certificateIssuePlaceholder').html(wizardSlide)
+
+      @showSlide(wizardClass)
+
+  domainFromMessageOrEmail: (params) ->
+
+    # try to extract the hostname from the error message
+    hostname = params.message.match(/hostname[ ]\"([^\"]+)"/i)
+    if hostname
+      return hostname[1]
+
+    # try to extract it from the given user
+    emailDomain = params.user.match(/@(.*)$/)
+    if emailDomain
+      return emailDomain[1]
+
+    # fallback to user - better than no value?!
+    return user
+
   mapping: (e) =>
     e.preventDefault()
     @showSlide('js-analyze')

+ 25 - 0
app/assets/javascripts/app/views/integration/exchange_certificate_issue.jst.eco

@@ -0,0 +1,25 @@
+<form class="modal-content setup wizard hide <%= @wizardClass %>">
+  <input type="hidden" name="disable_ssl_verify" value="1">
+  <input type="hidden" name="endpoint" value="<%= @endpoint %>">
+  <input type="hidden" name="user" value="<%= @user %>">
+  <input type="hidden" name="password" value="<%= @password %>">
+  <div class="modal-header">
+    <div class="modal-close js-close">
+      <%- @Icon('diagonal-cross') %>
+    </div>
+    <h1 class="modal-title"><%- @T('Your connection is not private') %></h1>
+  </div>
+  <div class="modal-body">
+    <div class="wizard-body vertical">
+      <p><%- @T('The certificate of the domain |%s| could not be verified. This may allow hackers to steal your credentials. If you are sure that you are using a self-signed certificate, you can press "Proceed". Otherwise, please "Cancel".', @domain) %></p>
+    </div>
+  </div>
+  <div class="modal-footer">
+    <div class="modal-leftFooter">
+      <button class="btn btn--text btn--danger btn--secondary js-submit"><%- @T('Proceed') %></button>
+    </div>
+    <div class="modal-rightFooter">
+      <a class="btn btn--primary align-right js-cancelSsl"><%- @T('Cancel') %></a>
+    </div>
+  </div>
+</form>

+ 2 - 25
app/assets/javascripts/app/views/integration/exchange_wizard.jst.eco

@@ -19,7 +19,7 @@
           <tbody>
             <tr>
               <td class="settings-list-row-control"><%- @T('User') %>
-              <td class="settings-list-control-cell"><input type="text" name="user" class="form-control form-control--small js-user" value="" placeholder="" autocomplete="off" required>
+              <td class="settings-list-control-cell"><input type="text" name="user" class="form-control form-control--small js-user" value="" placeholder="user@your-exchange.tld" autocomplete="off" required>
             <tr>
               <td class="settings-list-row-control"><%- @T('Password') %>
               <td class="settings-list-control-cell"><input type="password" name="password" class="form-control form-control--small js-password" value="" placeholder="" autocomplete="new-password" required>
@@ -34,30 +34,7 @@
     </div>
   </form>
 
-  <form class="modal-content setup wizard hide js-discoverSsl">
-    <input type="hidden" name="disable_ssl_verify" value="1">
-    <input type="hidden" name="user" value="">
-    <input type="hidden" name="password" value="">
-    <div class="modal-header">
-      <div class="modal-close js-close">
-        <%- @Icon('diagonal-cross') %>
-      </div>
-      <h1 class="modal-title"><%- @T('Your connection is not private') %></h1>
-    </div>
-    <div class="modal-body">
-      <div class="wizard-body vertical">
-        <p><%- @T('The certificate of the domain could not be verified. Hackers could steal the credentials or redirect the connection. Or maybe you are using a self-signed certificate.') %></p>
-      </div>
-    </div>
-    <div class="modal-footer">
-      <div class="modal-leftFooter">
-        <button class="btn btn--text btn--danger btn--secondary js-submit"><%- @T('Proceed') %></button>
-      </div>
-      <div class="modal-rightFooter">
-        <a class="btn btn--primary align-right js-cancelSsl"><%- @T('Cancel') %></a>
-      </div>
-    </div>
-  </form>
+  <div class="js-certificateIssuePlaceholder"></div>
 
   <form class="modal-content setup wizard hide js-connect">
     <div class="modal-header">

+ 12 - 15
app/controllers/integration/exchange_controller.rb

@@ -26,11 +26,7 @@ class Integration::ExchangeController < ApplicationController
     answer_with do
       Sequencer.process('Import::Exchange::AvailableFolders',
                         parameters: {
-                          ews_config: {
-                            endpoint: params[:endpoint],
-                            user:     params[:user],
-                            password: params[:password],
-                          }
+                          ews_config: ews_config
                         })
     end
   end
@@ -42,11 +38,7 @@ class Integration::ExchangeController < ApplicationController
       examples = Sequencer.process('Import::Exchange::AttributesExamples',
                                    parameters: {
                                      ews_folder_ids: params[:folders],
-                                     ews_config:     {
-                                       endpoint: params[:endpoint],
-                                       user:     params[:user],
-                                       password: params[:password],
-                                     }
+                                     ews_config:     ews_config
                                    })
       examples.tap do |result|
         raise 'No entries found in selected folder(s).' if result[:attributes].blank?
@@ -61,15 +53,20 @@ class Integration::ExchangeController < ApplicationController
     {
       ews_attributes: params[:attributes].permit!.to_h,
       ews_folder_ids: params[:folders],
-      ews_config:     {
-        endpoint: params[:endpoint],
-        user:     params[:user],
-        password: params[:password],
-      }
+      ews_config:     ews_config
     }
   end
 
   def payload_import
     nil
   end
+
+  def ews_config
+    {
+      disable_ssl_verify: params[:disable_ssl_verify],
+      endpoint:           params[:endpoint],
+      user:               params[:user],
+      password:           params[:password],
+    }
+  end
 end

+ 28 - 3
lib/sequencer/unit/exchange/connection.rb

@@ -11,12 +11,37 @@ class Sequencer
           return if state.provided?(:ews_connection)
 
           state.provide(:ews_connection) do
-            config   = ews_config
-            config ||= ::Import::Exchange.config
+            Viewpoint::EWSClient.new(
+              config[:endpoint],
+              config[:user],
+              config[:password],
+              additional_opts
+            )
+          end
+        end
+
+        private
+
+        def config
+          @config ||= begin
+            ews_config || ::Import::Exchange.config
+          end
+        end
 
-            Viewpoint::EWSClient.new(config[:endpoint], config[:user], config[:password])
+        def additional_opts
+          @additional_opts ||= begin
+            http_opts
           end
         end
+
+        def http_opts
+          return {} if config[:disable_ssl_verify].blank?
+          {
+            http_opts: {
+              ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE
+            }
+          }
+        end
       end
     end
   end