From 9a58e16e39926281b5a9bb9d5113109d287ccc10 Mon Sep 17 00:00:00 2001 From: Cam Saul <cammsaul@gmail.com> Date: Tue, 5 Sep 2017 14:17:05 -0700 Subject: [PATCH] Fix Mac App reset password --- OSX/Metabase.xcodeproj/project.pbxproj | 4 ---- OSX/Metabase/Backend/MetabaseTask.m | 2 +- OSX/Metabase/Backend/ResetPasswordTask.m | 22 ++++++++---------- bin/osx-setup | 5 ---- docs/developers-guide-osx.md | 13 +++++++---- project.clj | 11 --------- .../metabase/reset_password/core.clj | 23 ------------------- src/metabase/cmd/reset_password.clj | 23 +++++++++++++++++++ src/metabase/core.clj | 6 +++++ 9 files changed, 48 insertions(+), 61 deletions(-) delete mode 100644 reset_password/metabase/reset_password/core.clj create mode 100644 src/metabase/cmd/reset_password.clj diff --git a/OSX/Metabase.xcodeproj/project.pbxproj b/OSX/Metabase.xcodeproj/project.pbxproj index 7c39d5f41b6..852019b3738 100644 --- a/OSX/Metabase.xcodeproj/project.pbxproj +++ b/OSX/Metabase.xcodeproj/project.pbxproj @@ -43,7 +43,6 @@ D1BDAC6A1C053E220075D3AC /* ResetPasswordWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D1BDAC691C053E220075D3AC /* ResetPasswordWindowController.xib */; }; D1BDAC6D1C0565640075D3AC /* JavaTask.m in Sources */ = {isa = PBXBuildFile; fileRef = D1BDAC6C1C0565640075D3AC /* JavaTask.m */; }; D1BDAC721C05695B0075D3AC /* ResetPasswordTask.m in Sources */ = {isa = PBXBuildFile; fileRef = D1BDAC711C05695B0075D3AC /* ResetPasswordTask.m */; }; - D1BDAC731C056C7C0075D3AC /* reset-password.jar in Resources */ = {isa = PBXBuildFile; fileRef = D1BDAC6E1C0566490075D3AC /* reset-password.jar */; }; D1CB9FE81BCEDE9A009A61FB /* LoadingView.m in Sources */ = {isa = PBXBuildFile; fileRef = D1CB9FE71BCEDE9A009A61FB /* LoadingView.m */; }; D1CB9FEA1BCEDEA5009A61FB /* LoadingView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D1CB9FE91BCEDEA5009A61FB /* LoadingView.xib */; }; D1CB9FED1BCEDF02009A61FB /* Loading_View_Inner.png in Resources */ = {isa = PBXBuildFile; fileRef = D1CB9FEB1BCEDF02009A61FB /* Loading_View_Inner.png */; }; @@ -129,7 +128,6 @@ D1BDAC691C053E220075D3AC /* ResetPasswordWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ResetPasswordWindowController.xib; sourceTree = "<group>"; }; D1BDAC6B1C0565640075D3AC /* JavaTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JavaTask.h; sourceTree = "<group>"; }; D1BDAC6C1C0565640075D3AC /* JavaTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JavaTask.m; sourceTree = "<group>"; }; - D1BDAC6E1C0566490075D3AC /* reset-password.jar */ = {isa = PBXFileReference; lastKnownFileType = archive.jar; path = "reset-password.jar"; sourceTree = "<group>"; }; D1BDAC701C05695B0075D3AC /* ResetPasswordTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResetPasswordTask.h; sourceTree = "<group>"; }; D1BDAC711C05695B0075D3AC /* ResetPasswordTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ResetPasswordTask.m; sourceTree = "<group>"; }; D1CB9FE61BCEDE9A009A61FB /* LoadingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LoadingView.h; sourceTree = "<group>"; }; @@ -338,7 +336,6 @@ children = ( D18853D61BB0CEC600D89803 /* Images.xcassets */, D105B2321BB5BE4A00A5D850 /* Images */, - D1BDAC6E1C0566490075D3AC /* reset-password.jar */, D18854021BB0DB6000D89803 /* metabase.jar */, D121FD681BC5B4E7002101B0 /* dsa_pub.pem */, ); @@ -426,7 +423,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - D1BDAC731C056C7C0075D3AC /* reset-password.jar in Resources */, D1DFF6C31BCEF9E700ECC7B6 /* Loading_View_Inner@2x.png in Resources */, D1CB9FEE1BCEDF02009A61FB /* Loading_View_Outer.png in Resources */, D105B23D1BB5BE4A00A5D850 /* back_icon@2x.png in Resources */, diff --git a/OSX/Metabase/Backend/MetabaseTask.m b/OSX/Metabase/Backend/MetabaseTask.m index 078d848e317..40010f23bc5 100644 --- a/OSX/Metabase/Backend/MetabaseTask.m +++ b/OSX/Metabase/Backend/MetabaseTask.m @@ -63,7 +63,7 @@ self.task = [[NSTask alloc] init]; self.task.launchPath = JREPath(); - self.task.environment = @{@"MB_DB_FILE": DBPath(), + self.task.environment = @{@"MB_DB_FILE": [DBPath() stringByAppendingString:@";AUTO_SERVER=TRUE"], @"MB_PLUGINS_DIR": PluginsDirPath(), @"MB_JETTY_PORT": @(self.port), @"MB_CLIENT": @"OSX"}; diff --git a/OSX/Metabase/Backend/ResetPasswordTask.m b/OSX/Metabase/Backend/ResetPasswordTask.m index 13d97d96abc..8c672066a91 100644 --- a/OSX/Metabase/Backend/ResetPasswordTask.m +++ b/OSX/Metabase/Backend/ResetPasswordTask.m @@ -8,10 +8,6 @@ #import "ResetPasswordTask.h" -NSString *ResetPasswordJarPath() { - return [[NSBundle mainBundle] pathForResource:@"reset-password" ofType:@"jar"]; -} - @interface ResetPasswordTask () @property (copy) NSString *output; @end @@ -25,7 +21,7 @@ NSString *ResetPasswordJarPath() { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ self.task = [[NSTask alloc] init]; - NSString *dbPath = [DBPath() stringByAppendingString:@";IFEXISTS=TRUE"]; + NSString *dbPath = [DBPath() stringByAppendingString:@";IFEXISTS=TRUE;AUTO_SERVER=TRUE"]; self.task.environment = @{@"MB_DB_FILE": dbPath, @"HOME": @"/Users/camsaul"}; // time travelers from the future: this is hardcoded since I'm the only one who works on this. I give you permission to fix it - Cam @@ -33,16 +29,18 @@ NSString *ResetPasswordJarPath() { #if DEBUG_RUN_LEIN_TASK self.task.environment = @{@"MB_DB_FILE": dbPath}; - self.task.currentDirectoryPath = @"/Users/camsaul/metabase"; - self.task.launchPath = @"/Users/camsaul/scripts/lein"; - self.task.arguments = @[@"with-profile", @"reset-password", @"run", emailAddress]; - NSLog(@"Launching ResetPasswordTask\nMB_DB_FILE='%@' lein with-profile reset-password run %@", dbPath, emailAddress); + self.task.currentDirectoryPath = @"/Users/cam/metabase"; + self.task.launchPath = @"/usr/local/bin/lein"; + self.task.arguments = @[@"run", @"reset-password", emailAddress]; + NSLog(@"Launching ResetPasswordTask\nMB_DB_FILE='%@' lein run reset-password %@", dbPath, emailAddress); #else self.task.environment = @{@"MB_DB_FILE": dbPath}; self.task.launchPath = JREPath(); - self.task.arguments = @[@"-classpath", [NSString stringWithFormat:@"%@:%@", UberjarPath(), ResetPasswordJarPath()], - @"metabase.reset_password.core", emailAddress]; - NSLog(@"Launching ResetPasswordTask\nMB_DB_FILE='%@' %@ -classpath %@:%@ metabase.reset_password.core %@", dbPath, JREPath(), UberjarPath(), ResetPasswordJarPath(), emailAddress); + self.task.arguments = @[@"-Djava.awt.headless=true", // this prevents the extra java icon from popping up in the dock when running + @"-Xverify:none", // disable bytecode verification for faster launch speed, not really needed here since JAR is packaged as part of signed .app + @"-jar", UberjarPath(), + @"reset-password", emailAddress]; + NSLog(@"Launching ResetPasswordTask\nMB_DB_FILE='%@' %@ -jar %@ reset-password %@", dbPath, JREPath(), UberjarPath(), emailAddress); #endif __weak ResetPasswordTask *weakSelf = self; diff --git a/bin/osx-setup b/bin/osx-setup index 811963ad718..58418ed189b 100755 --- a/bin/osx-setup +++ b/bin/osx-setup @@ -18,9 +18,6 @@ use constant JRE_HOME => trim(`/usr/libexec/java_home`) . '/jre'; use constant UBERJAR_SRC => getcwd() . '/target/uberjar/metabase.jar'; use constant UBERJAR_DEST => getcwd() . '/OSX/Resources/metabase.jar'; -use constant RESET_PW_SRC => getcwd() . '/reset-password-artifacts/reset-password/reset-password.jar'; -use constant RESET_PW_DEST => getcwd() . '/OSX/Resources/reset-password.jar'; - use constant BUILD_SCRIPT => getcwd() . '/bin/build'; # Copy the JRE if needed @@ -28,7 +25,6 @@ use constant BUILD_SCRIPT => getcwd() . '/bin/build'; # Build jars if needed (system(BUILD_SCRIPT) or die $!) unless -f UBERJAR_SRC; -(system('lein', 'with-profile', 'reset-password', 'jar') or die $!) unless -f RESET_PW_SRC; # Copy jars over sub copy_jar { @@ -37,6 +33,5 @@ sub copy_jar { copy(get_file_or_die($src), $dest) or die $!; } copy_jar(UBERJAR_SRC, UBERJAR_DEST); -copy_jar(RESET_PW_SRC, RESET_PW_DEST); print_giant_success_banner(); diff --git a/docs/developers-guide-osx.md b/docs/developers-guide-osx.md index 53c6448b879..946ff3c7c47 100644 --- a/docs/developers-guide-osx.md +++ b/docs/developers-guide-osx.md @@ -1,6 +1,7 @@ # Metabase OS X App -NOTE: These instructions are only for packaging a built Metabase uberjar into `Metabase.app`. They are not useful if your goal is to work on Metabase itself; for development, please see our [developers' guide](developers-guide.md). +NOTE: These instructions are only for packaging a built Metabase uberjar into `Metabase.app`. They are not useful if your goal is to work on Metabase itself; for development, please see +our [developers' guide](developers-guide.md). ## Prereqs @@ -23,10 +24,8 @@ NOTE: These instructions are only for packaging a built Metabase uberjar into `M ./bin/osx-setup ``` -`./bin/osx-setup` will build run commands to build the uberjar for you if needed. -Run `./bin/osx-setup` again at any time in the future to copy the latest version of the uberjar into the project. - -(If the script fails near the end, you can just copy the JARs in question to `OSX/Resources/metabase.jar` and `OSX/Resources/reset-password.jar`.) +`./bin/osx-setup` will copy over things like the JRE into the Mac App directory for you. You only need to do this once the first time you plan on building the Mac App. +This also runs `./bin/build` to get the latest uberjar and copies it for you; if the script fails near the end, you can just copy the uberjar to `OSX/Resources/metabase.jar`.) ## Releasing @@ -55,6 +54,10 @@ Run `open OSX/Metabase.xcodeproj` to open the project, which will automatically After that, you are good to go: ```bash +# Build the latest version of the uberjar and copy it to the Mac App build directory +# (You can skip this step if you just ran ./bin/osx-setup, because it does this step for you) +./bin/build && cp target/uberjar/metabase.jar OSX/Resources/metabase.jar + # Bundle entire app, and upload to s3 ./bin/osx-release ``` diff --git a/project.clj b/project.clj index e76766566d3..63c47f54e2b 100644 --- a/project.clj +++ b/project.clj @@ -160,16 +160,5 @@ ;; Profile Metabase start time with `lein profile` :profile {:jvm-opts ["-XX:+CITime" ; print time spent in JIT compiler "-XX:+PrintGC"]} ; print a message when garbage collection takes place - ;; Run reset password from source: MB_DB_PATH=/path/to/metabase.db lein with-profile reset-password run email@address.com - ;; Create the reset password JAR: lein with-profile reset-password jar - ;; -> ./reset-password-artifacts/reset-password/reset-password.jar - ;; Run the reset password JAR: MB_DB_PATH=/path/to/metabase.db java -classpath /path/to/metabase-uberjar.jar:/path/to/reset-password.jar \ - ;; metabase.reset_password.core email@address.com - :reset-password {:source-paths ["reset_password"] - :main metabase.reset-password.core - :jar-name "reset-password.jar" - ;; Exclude everything except for reset-password specific code in the created jar - :jar-exclusions [#"^(?!metabase/reset_password).*$"] - :target-path "reset-password-artifacts/%s"} ; different than ./target because otherwise lein uberjar will delete our artifacts and vice versa ;; get the H2 shell with 'lein h2' :h2-shell {:main org.h2.tools.Shell}}) diff --git a/reset_password/metabase/reset_password/core.clj b/reset_password/metabase/reset_password/core.clj deleted file mode 100644 index 3940a7dbc27..00000000000 --- a/reset_password/metabase/reset_password/core.clj +++ /dev/null @@ -1,23 +0,0 @@ -(ns metabase.reset-password.core - (:gen-class) - (:require [metabase.db :as mdb] - [metabase.models.user :as user] - [toucan.db :as db])) - -(defn- set-reset-token! - "Set and return a new `reset_token` for the user with EMAIL-ADDRESS." - [email-address] - (let [user-id (or (db/select-one-id 'User, :email email-address) - (throw (Exception. (format "No user found with email address '%s'. Please check the spelling and try again." email-address))))] - (user/set-password-reset-token! user-id))) - -(defn -main - [email-address] - (mdb/setup-db!) - (printf "Resetting password for %s...\n" email-address) - (try - (printf "OK [[[%s]]]\n" (set-reset-token! email-address)) - (System/exit 0) - (catch Throwable e - (printf "FAIL [[[%s]]]\n" (.getMessage e)) - (System/exit -1)))) diff --git a/src/metabase/cmd/reset_password.clj b/src/metabase/cmd/reset_password.clj new file mode 100644 index 00000000000..e515f464fa2 --- /dev/null +++ b/src/metabase/cmd/reset_password.clj @@ -0,0 +1,23 @@ +(ns metabase.cmd.reset-password + (:require [metabase.db :as mdb] + [metabase.models.user :refer [User] :as user] + [toucan.db :as db])) + +(defn- set-reset-token! + "Set and return a new `reset_token` for the user with EMAIL-ADDRESS." + [email-address] + (let [user-id (or (db/select-one-id User, :email email-address) + (throw (Exception. (format "No user found with email address '%s'. Please check the spelling and try again." email-address))))] + (user/set-password-reset-token! user-id))) + +(defn reset-password! + "Reset the password for EMAIL-ADDRESS, and return the reset token in a format that can be understood by the Mac App." + [email-address] + (mdb/setup-db!) + (println (format "Resetting password for %s...\n" email-address)) + (try + (println (format "OK [[[%s]]]" (set-reset-token! email-address))) + (System/exit 0) + (catch Throwable e + (println (format "FAIL [[[%s]]]" (.getMessage e))) + (System/exit -1)))) diff --git a/src/metabase/core.clj b/src/metabase/core.clj index 16cc4c3c09a..2ba2c106ef3 100644 --- a/src/metabase/core.clj +++ b/src/metabase/core.clj @@ -216,6 +216,12 @@ (intern 'environ.core 'env (assoc environ.core/env :mb-jetty-join "false")) (u/profile "start-normally" (start-normally))) +(defn ^:command reset-password + "Reset the password for a user with EMAIL-ADDRESS." + [email-address] + (require 'metabase.cmd.reset-password) + ((resolve 'metabase.cmd.reset-password/reset-password!) email-address)) + (defn ^:command help "Show this help message listing valid Metabase commands." [] -- GitLab