-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Bruce Potter
committed
Oct 6, 2019
1 parent
0af8594
commit 949c958
Showing
8 changed files
with
219 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io/ioutil" | ||
"log" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
"sync" | ||
|
||
"golang.org/x/crypto/bcrypt" | ||
) | ||
|
||
/* | ||
A tool to change 1 of the user's passwords in the database. Use this, for example, when you've lost the admin pw. | ||
Must be run as root, and when the web svr is stopped. | ||
*/ | ||
|
||
type Database struct { | ||
Version int `json:"version"` | ||
CookieHashKey []byte `json:"cookie_hash_key"` | ||
CookieBlockKey []byte `json:"cookie_block_key"` | ||
Jobs map[string]interface{} `json:"jobs"` | ||
Users map[string]DatabaseUser `json:"users"` | ||
} | ||
|
||
type DatabaseUser struct { | ||
Id string `json:"id"` | ||
Username string `json:"username"` | ||
Password []byte `json:"password"` | ||
IsAdmin bool `json:"is_admin"` | ||
} | ||
|
||
var globalDb Database | ||
var globalDbLock sync.RWMutex | ||
|
||
// Print error msg to stderr and exit with the specified code | ||
func Fatal(exitCode int, msg string, args ...interface{}) { | ||
if !strings.HasSuffix(msg, "\n") { | ||
msg += "\n" | ||
} | ||
l := log.New(os.Stderr, "", 0) | ||
l.Printf("Error: "+msg, args...) | ||
os.Exit(exitCode) | ||
} | ||
|
||
func GetEnvVarWithDefault(envVarName, defaultValue string) string { | ||
envVarValue := os.Getenv(envVarName) | ||
if envVarValue == "" { | ||
return defaultValue | ||
} | ||
return envVarValue | ||
} | ||
|
||
// Read in a parse the db | ||
func loadDatabase(dbFile string) Database { | ||
bytes, err := ioutil.ReadFile(dbFile) | ||
if err != nil { | ||
Fatal(1, "%v", err) | ||
} | ||
|
||
var db Database | ||
err = json.Unmarshal(bytes, &db) | ||
if err != nil { | ||
Fatal(2, "%v", err) | ||
} | ||
|
||
return db | ||
} | ||
|
||
// Write out the db | ||
func persistDatabase(dbFile string) error { | ||
dbJson, err := json.Marshal(globalDb) | ||
if err != nil { | ||
Fatal(2, "%v", err) | ||
} | ||
|
||
return ioutil.WriteFile(dbFile, dbJson, 0644) | ||
} | ||
|
||
func main() { | ||
if len(os.Args) <= 2 { | ||
fmt.Printf("Usage: %s <username> <pw>\n", filepath.Base(os.Args[0])) | ||
os.Exit(0) | ||
} | ||
|
||
username := os.Args[1] | ||
pw := os.Args[2] | ||
if pw == "" { | ||
Fatal(1, "password can not be empty") | ||
} | ||
|
||
dbFile := GetEnvVarWithDefault("MENDEL_DB_FILE", "/usr/local/var/run/mendel-web-ui/database/database.json") | ||
|
||
globalDb = loadDatabase(dbFile) // read in the db | ||
|
||
// Find this user in the db | ||
dbUser := DatabaseUser{} | ||
globalDbLock.RLock() | ||
for _, u := range globalDb.Users { | ||
if u.Username == username { | ||
dbUser = u | ||
break | ||
} | ||
} | ||
globalDbLock.RUnlock() | ||
|
||
if dbUser.Id == "" { | ||
Fatal(1, "%s does not exist in the database", username) | ||
} | ||
|
||
// Bcrypt the pw they gave us | ||
hashedPw, err := bcrypt.GenerateFromPassword([]byte(pw), bcrypt.DefaultCost) | ||
if err != nil { | ||
Fatal(3, "could not bcrypt password: %v", err) | ||
} | ||
dbUser.Password = hashedPw | ||
|
||
// Write out the db with the new user pw | ||
globalDbLock.Lock() | ||
globalDb.Users[dbUser.Id] = dbUser | ||
err = persistDatabase(dbFile) | ||
globalDbLock.Unlock() | ||
if err != nil { | ||
Fatal(3, "could not persist database: %v", err) | ||
} | ||
|
||
fmt.Printf("password for %s updated successfully\n", username) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
#!/bin/bash | ||
|
||
# Changes the pw of the specified user (and restarts the mendel web ui in the process). | ||
|
||
if [[ -z "$2" ]]; then | ||
echo "Usage: $(basename $0) <username> <pw>" | ||
exit | ||
fi | ||
|
||
username="$1" | ||
pw="$2" | ||
|
||
myDir=$(dirname $0) | ||
dbFile=/usr/local/var/run/mendel-web-ui/database/database.json | ||
#tempDbFile=/tmp/mendel-web-ui-database.json | ||
|
||
isMacos() { | ||
if [[ "$(uname -s)" == "Darwin" ]]; then | ||
return 0 | ||
else | ||
return 1 | ||
fi | ||
} | ||
|
||
confirmCmds() { | ||
for c in $*; do | ||
if ! which $c >/dev/null 2>&1; then | ||
echo "Error: $c is not installed but required, exiting" | ||
exit 2 | ||
fi | ||
done | ||
} | ||
|
||
stopWebSvr() { | ||
if isMacos; then | ||
if [[ -f "$myDir/../scripts/stop-mendel-ui.sh" ]]; then | ||
$myDir/../scripts/stop-mendel-ui.sh # this is the dev version of the script | ||
else | ||
$myDir/stop-mendel-ui.sh | ||
fi | ||
else | ||
sudo initctl stop mendel-web-ui | ||
fi | ||
} | ||
|
||
startWebSvr() { | ||
if isMacos; then | ||
if [[ -f "$myDir/../scripts/start-mendel-ui.sh" ]]; then | ||
$myDir/../scripts/start-mendel-ui.sh # this is the dev version of the script | ||
else | ||
$myDir/start-mendel-ui.sh | ||
fi | ||
else | ||
sudo initctl start mendel-web-ui | ||
fi | ||
} | ||
|
||
confirmCmds jq base64 htpasswd | ||
|
||
set -e # stop if any cmd fails | ||
stopWebSvr || true # keep going | ||
|
||
#userid=$(jq ".users[] | select(.username==\"$username\").id" $dbFile) # get the id of this user | ||
#hashedPw=$(htpasswd -bnBC 10 "" $pw | tr -d ':\n') # mendel web ui expects the pw to be bcrypted and base64 encoded | ||
#encodedPw=$(echo "$hashedPw" | base64) | ||
#jq ".users[$userid].password=\"$encodedPw\" " $dbFile > $tempDbFile # put the pw in the db | ||
#mv $tempDbFile $dbFile | ||
|
||
MENDEL_DB_FILE=$dbFile $myDir/mendel-chg-pw "$username" "$pw" | ||
|
||
startWebSvr | ||
set +e |