diff --git a/resources/frontend_client/app/setup/setup.controllers.js b/resources/frontend_client/app/setup/setup.controllers.js index 9e0fce9faedd25e748e2446371946dc1ac425845..4d11dc10064e1935fbd491d579b6bc21b34ebe93 100644 --- a/resources/frontend_client/app/setup/setup.controllers.js +++ b/resources/frontend_client/app/setup/setup.controllers.js @@ -111,7 +111,7 @@ SetupControllers.controller('SetupConnection', ['$scope', '$routeParams', '$loca } // Validate the connection string - Metabase.validate_connection(database, function(result){ + Metabase.validate_connection($scope.connection, function(result){ if(newConnection) { Metabase.db_create(database, success, error); } else { diff --git a/src/metabase/api/meta/db.clj b/src/metabase/api/meta/db.clj index e23af9807c00d06be734301fa04883ee7478fdd8..56b6e54251648cf887bb5de25f787410cff7b2ac 100644 --- a/src/metabase/api/meta/db.clj +++ b/src/metabase/api/meta/db.clj @@ -1,6 +1,7 @@ (ns metabase.api.meta.db "/api/meta/db endpoints." (:require [compojure.core :refer [GET POST PUT DELETE]] + [clojure.tools.logging :as log] [korma.core :refer :all] [medley.core :as medley] [metabase.api.common :refer :all] @@ -30,12 +31,23 @@ {:timezones metabase.models.common/timezones :engines driver/available-drivers}) + + + + + + +{{:body {}} :body} + ;Stub function that will eventually validate a connection string -(defendpoint POST "/validate" [] - (if (= (rand-int 2) 1) - {:status 200 :body {:valid true}} - (let [error-message (rand-nth ["Host not reachable" "Invalid Port" "Invalid User or Password"])] - {:status 400 :body {:valid false :message error-message}} ))) +(defendpoint POST "/validate" [:as {{:keys [host port]} :body}] + (require-params host port) + (log/debug host port) + (cond + (not (u/host-up? host)) {:status 400 :body {:valid false :message "Host not reachable"}} + (not (u/host-port-up? host (Integer. port))) {:status 400 :body {:valid false :message "Invalid port"}} + (= (rand-int 2) 1) {:status 400 :body {:valid false :message "Invalid User or Password"}} + :else {:status 200 :body {:valid true}} )) (defendpoint GET "/:id" [id] (->404 (sel :one Database :id id) diff --git a/src/metabase/util.clj b/src/metabase/util.clj index a17ad0c8d23d299a1107a2696dae8dd1032d7b06..40596c0d8de8e1fcec77fba1458eb6ab43bd9a5d 100644 --- a/src/metabase/util.clj +++ b/src/metabase/util.clj @@ -1,6 +1,7 @@ (ns metabase.util "Common utility functions useful throughout the codebase." (:require [medley.core :refer :all] + [clojure.tools.logging :as log] [clj-time.format :as time] [clj-time.coerce :as coerce])) @@ -149,3 +150,32 @@ false (boolean (re-matches #"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?" (clojure.string/lower-case v))))) + + +(import '(java.io IOException) + '(java.net Socket) + '(java.net InetSocketAddress) + '(java.net InetAddress) + '(java.net SocketTimeoutException) + '(java.net UnknownHostException)) + +(defn host-port-up? [hostname port] + (log/debug "in host-port-up?" hostname port) + (let [sock-addr (InetSocketAddress. hostname port) + timeout 5000] + (try + (with-open [sock (Socket.)] + (. sock connect sock-addr timeout) + true) + (catch IOException e false) + (catch SocketTimeoutException e false) + (catch UnknownHostException e false)))) + +(defn host-up? [hostname] + (let [host-addr (. InetAddress getByName hostname) + timeout 5000] + (try + (. host-addr isReachable timeout) + (catch IOException e false) + (catch SocketTimeoutException e false) + (catch UnknownHostException e false)))) \ No newline at end of file