From 5af1629cc5b8c711879f7e764a2f0a85647ee0a9 Mon Sep 17 00:00:00 2001 From: Peter Rounce Date: Tue, 21 Feb 2023 12:44:27 +0000 Subject: [PATCH 1/4] partial --- docs/INSTALL.md | 4 +- .../createboltcard.go | 0 internalapi/updateboltcard.go | 100 ++++++++++++++++++ .../wipeboltcard.go | 0 s_build => script/s_build | 0 s_create_db => script/s_create_db | 0 s_launch => script/s_launch | 0 s_restart => script/s_restart | 0 sql/create_db.sql | 2 +- 9 files changed, 103 insertions(+), 3 deletions(-) rename createboltcard.go => internalapi/createboltcard.go (100%) create mode 100644 internalapi/updateboltcard.go rename wipeboltcard.go => internalapi/wipeboltcard.go (100%) rename s_build => script/s_build (100%) rename s_create_db => script/s_create_db (100%) rename s_launch => script/s_launch (100%) rename s_restart => script/s_restart (100%) diff --git a/docs/INSTALL.md b/docs/INSTALL.md index a06521c..faca21e 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -50,10 +50,10 @@ edit `Caddyfile` to set the boltcard domain name ### database creation edit `create_db.sql` to set the cardapp password `$ sudo -u postgres createuser -s ubuntu` -`$ ./s_create_db` +`$ script/s_create_db` ### boltcard service install -`$ ./s_build` +`$ script/s_build` `$ sudo systemctl enable boltcard` `$ sudo systemctl status boltcard` diff --git a/createboltcard.go b/internalapi/createboltcard.go similarity index 100% rename from createboltcard.go rename to internalapi/createboltcard.go diff --git a/internalapi/updateboltcard.go b/internalapi/updateboltcard.go new file mode 100644 index 0000000..4fde0dd --- /dev/null +++ b/internalapi/updateboltcard.go @@ -0,0 +1,100 @@ +package main + +import ( + "crypto/rand" + "encoding/hex" + "github.com/boltcard/boltcard/db" + "github.com/boltcard/boltcard/resp_err" + log "github.com/sirupsen/logrus" + "net/http" + "strconv" + "strings" +) + +func updateboltcard(w http.ResponseWriter, r *http.Request) { + if db.Get_setting("FUNCTION_INTERNAL_API") != "ENABLE" { + msg := "updateboltcard: internal API function is not enabled" + log.Debug(msg) + resp_err.Write_message(w, msg) + return + } + + tx_max_str := r.URL.Query().Get("tx_max") + tx_max, err := strconv.Atoi(tx_max_str) + if err != nil { + msg := "updateboltcard: tx_max is not a valid integer" + log.Warn(msg) + resp_err.Write_message(w, msg) + return + } + + enable_flag_str := r.URL.Query().Get("enable") + enable_flag, err := strconv.ParseBool(enable_flag_str) + if err != nil { + msg := "updateboltcard: enable is not a valid boolean" + log.Warn(msg) + resp_err.Write_message(w, msg) + return + } + + card_name := r.URL.Query().Get("card_name") + + // check if card_name already exists +//TODO: allow multiple deactivated cards with the same card_name + card_count, err := db.Get_card_name_count(card_name) + if err != nil { + log.Warn(err.Error()) + return + } + + if card_count == 0 { + msg := "updateboltcard: the card name does not exist in the database" + log.Warn(msg) + resp_err.Write_message(w, msg) + return + } + + // log the request + + log.WithFields(log.Fields{ + "card_name": card_name, "tx_max": tx_max, + "enable": enable_flag}).Info("createboltcard API request") + + // create the keys + + one_time_code := random_hex() + k0_auth_key := random_hex() + k2_cmac_key := random_hex() + k3 := random_hex() + k4 := random_hex() + + // update the card record + + err = db.Update_card(card_name, tx_max, enable_flag) + if err != nil { + log.Warn(err.Error()) + return + } + + // return the URI + one_time_code + + hostdomain := db.Get_setting("HOST_DOMAIN") + url := "" + if strings.HasSuffix(hostdomain, ".onion") { + url = "http://" + hostdomain + "/new?a=" + one_time_code + } else { + url = "https://" + hostdomain + "/new?a=" + one_time_code + } + + // log the response + + log.WithFields(log.Fields{ + "card_name": card_name, "url": url}).Info("updateboltcard API response") + + jsonData := []byte(`{"status":"OK",` + + `"url":"` + url + `"}`) + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(jsonData) +} diff --git a/wipeboltcard.go b/internalapi/wipeboltcard.go similarity index 100% rename from wipeboltcard.go rename to internalapi/wipeboltcard.go diff --git a/s_build b/script/s_build similarity index 100% rename from s_build rename to script/s_build diff --git a/s_create_db b/script/s_create_db similarity index 100% rename from s_create_db rename to script/s_create_db diff --git a/s_launch b/script/s_launch similarity index 100% rename from s_launch rename to script/s_launch diff --git a/s_restart b/script/s_restart similarity index 100% rename from s_restart rename to script/s_restart diff --git a/sql/create_db.sql b/sql/create_db.sql index f50285b..20cf9d5 100644 --- a/sql/create_db.sql +++ b/sql/create_db.sql @@ -20,7 +20,7 @@ CREATE TABLE cards ( tx_limit_sats INT NOT NULL, day_limit_sats INT NOT NULL, lnurlp_enable CHAR(1) NOT NULL DEFAULT 'N', - card_name VARCHAR(100) UNIQUE NOT NULL DEFAULT '', + card_name VARCHAR(100) NOT NULL DEFAULT '', email_address VARCHAR(100) DEFAULT '', email_enable CHAR(1) NOT NULL DEFAULT 'N', uid_privacy CHAR(1) NOT NULL DEFAULT 'N', From dadc76f0d3722abbcf22a585e267ec1edc2d8e3b Mon Sep 17 00:00:00 2001 From: Peter Rounce Date: Wed, 22 Feb 2023 08:11:52 +0000 Subject: [PATCH 2/4] add Updateboltcard() --- db/db.go | 37 ++++++++++++++++++++++++++++++++++ internalapi/createboltcard.go | 4 ++-- internalapi/ping.go | 12 +++++++++++ internalapi/updateboltcard.go | 38 ++++++----------------------------- internalapi/wipeboltcard.go | 4 ++-- main.go | 8 +++++--- ping.go | 10 +-------- sql/create_db.sql | 2 +- 8 files changed, 66 insertions(+), 49 deletions(-) create mode 100644 internalapi/ping.go diff --git a/db/db.go b/db/db.go index 4a868fd..58a1148 100644 --- a/db/db.go +++ b/db/db.go @@ -834,3 +834,40 @@ func Wipe_card(card_name string) (*Card_wipe_info, error) { return &card_wipe_info, nil } + +func Update_card(card_name string, tx_max int, lnurlw_enable bool) error { + + lnurlw_enable_yn := "N" + if lnurlw_enable { + lnurlw_enable_yn = "Y" + } + + db, err := open() + + if err != nil { + return err + } + + defer db.Close() + + sqlStatement := `UPDATE cards SET tx_max = $2, lnurlw_enable = $3 ` + + `WHERE card_name = $1;` + + res, err := db.Exec(sqlStatement, card_name, tx_max, lnurlw_enable_yn) + + if err != nil { + return err + } + + count, err := res.RowsAffected() + + if err != nil { + return err + } + + if count != 1 { + return errors.New("not one card record updated") + } + + return nil +} diff --git a/internalapi/createboltcard.go b/internalapi/createboltcard.go index c2d291d..cee8db2 100644 --- a/internalapi/createboltcard.go +++ b/internalapi/createboltcard.go @@ -1,4 +1,4 @@ -package main +package internalapi import ( "crypto/rand" @@ -22,7 +22,7 @@ func random_hex() string { return hex.EncodeToString(b) } -func createboltcard(w http.ResponseWriter, r *http.Request) { +func Createboltcard(w http.ResponseWriter, r *http.Request) { if db.Get_setting("FUNCTION_INTERNAL_API") != "ENABLE" { msg := "createboltcard: internal API function is not enabled" log.Debug(msg) diff --git a/internalapi/ping.go b/internalapi/ping.go new file mode 100644 index 0000000..9a3d9d5 --- /dev/null +++ b/internalapi/ping.go @@ -0,0 +1,12 @@ +package internalapi + +import ( + "net/http" +) + +func Internal_ping(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + jsonData := []byte(`{"status":"OK","pong":"internal API"}`) + w.Write(jsonData) +} diff --git a/internalapi/updateboltcard.go b/internalapi/updateboltcard.go index 4fde0dd..6d9e59e 100644 --- a/internalapi/updateboltcard.go +++ b/internalapi/updateboltcard.go @@ -1,17 +1,14 @@ -package main +package internalapi import ( - "crypto/rand" - "encoding/hex" "github.com/boltcard/boltcard/db" "github.com/boltcard/boltcard/resp_err" log "github.com/sirupsen/logrus" "net/http" "strconv" - "strings" ) -func updateboltcard(w http.ResponseWriter, r *http.Request) { +func Updateboltcard(w http.ResponseWriter, r *http.Request) { if db.Get_setting("FUNCTION_INTERNAL_API") != "ENABLE" { msg := "updateboltcard: internal API function is not enabled" log.Debug(msg) @@ -39,8 +36,8 @@ func updateboltcard(w http.ResponseWriter, r *http.Request) { card_name := r.URL.Query().Get("card_name") - // check if card_name already exists -//TODO: allow multiple deactivated cards with the same card_name + // check if card_name exists + card_count, err := db.Get_card_name_count(card_name) if err != nil { log.Warn(err.Error()) @@ -60,14 +57,6 @@ func updateboltcard(w http.ResponseWriter, r *http.Request) { "card_name": card_name, "tx_max": tx_max, "enable": enable_flag}).Info("createboltcard API request") - // create the keys - - one_time_code := random_hex() - k0_auth_key := random_hex() - k2_cmac_key := random_hex() - k3 := random_hex() - k4 := random_hex() - // update the card record err = db.Update_card(card_name, tx_max, enable_flag) @@ -76,24 +65,9 @@ func updateboltcard(w http.ResponseWriter, r *http.Request) { return } - // return the URI + one_time_code - - hostdomain := db.Get_setting("HOST_DOMAIN") - url := "" - if strings.HasSuffix(hostdomain, ".onion") { - url = "http://" + hostdomain + "/new?a=" + one_time_code - } else { - url = "https://" + hostdomain + "/new?a=" + one_time_code - } - - // log the response - - log.WithFields(log.Fields{ - "card_name": card_name, "url": url}).Info("updateboltcard API response") - - jsonData := []byte(`{"status":"OK",` + - `"url":"` + url + `"}`) + // send a response + jsonData := []byte(`{"status":"OK"}`) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) w.Write(jsonData) diff --git a/internalapi/wipeboltcard.go b/internalapi/wipeboltcard.go index 3fa52fe..2166f85 100644 --- a/internalapi/wipeboltcard.go +++ b/internalapi/wipeboltcard.go @@ -1,4 +1,4 @@ -package main +package internalapi import ( "github.com/boltcard/boltcard/db" @@ -8,7 +8,7 @@ import ( "strconv" ) -func wipeboltcard(w http.ResponseWriter, r *http.Request) { +func Wipeboltcard(w http.ResponseWriter, r *http.Request) { if db.Get_setting("FUNCTION_INTERNAL_API") != "ENABLE" { msg := "wipeboltcard: internal API function is not enabled" log.Debug(msg) diff --git a/main.go b/main.go index 40a0ed0..46a895c 100644 --- a/main.go +++ b/main.go @@ -4,6 +4,7 @@ import ( "github.com/boltcard/boltcard/db" "github.com/boltcard/boltcard/lnurlp" "github.com/boltcard/boltcard/lnurlw" + "github.com/boltcard/boltcard/internalapi" "github.com/gorilla/mux" log "github.com/sirupsen/logrus" "net/http" @@ -50,9 +51,10 @@ func main() { // this has no authentication and is not to be exposed publicly // it exists for use on a private virtual network within a docker container - internal_router.Path("/ping").Methods("GET").HandlerFunc(internal_ping) - internal_router.Path("/createboltcard").Methods("GET").HandlerFunc(createboltcard) - internal_router.Path("/wipeboltcard").Methods("GET").HandlerFunc(wipeboltcard) + internal_router.Path("/ping").Methods("GET").HandlerFunc(internalapi.Internal_ping) + internal_router.Path("/createboltcard").Methods("GET").HandlerFunc(internalapi.Createboltcard) + internal_router.Path("/updateboltcard").Methods("GET").HandlerFunc(internalapi.Updateboltcard) + internal_router.Path("/wipeboltcard").Methods("GET").HandlerFunc(internalapi.Wipeboltcard) port := db.Get_setting("HOST_PORT") if port == "" { diff --git a/ping.go b/ping.go index d42eabe..0119b7a 100644 --- a/ping.go +++ b/ping.go @@ -5,16 +5,8 @@ import ( ) func external_ping(w http.ResponseWriter, req *http.Request) { - ping(w, "external API") -} - -func internal_ping(w http.ResponseWriter, req *http.Request) { - ping(w, "internal API") -} - -func ping(w http.ResponseWriter, message string) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - jsonData := []byte(`{"status":"OK","pong":"` + message + `"}`) + jsonData := []byte(`{"status":"OK","pong":"external API"}`) w.Write(jsonData) } diff --git a/sql/create_db.sql b/sql/create_db.sql index 20cf9d5..f50285b 100644 --- a/sql/create_db.sql +++ b/sql/create_db.sql @@ -20,7 +20,7 @@ CREATE TABLE cards ( tx_limit_sats INT NOT NULL, day_limit_sats INT NOT NULL, lnurlp_enable CHAR(1) NOT NULL DEFAULT 'N', - card_name VARCHAR(100) NOT NULL DEFAULT '', + card_name VARCHAR(100) UNIQUE NOT NULL DEFAULT '', email_address VARCHAR(100) DEFAULT '', email_enable CHAR(1) NOT NULL DEFAULT 'N', uid_privacy CHAR(1) NOT NULL DEFAULT 'N', From 5c3bb689953f85d8332b96f156503b2a12c6b496 Mon Sep 17 00:00:00 2001 From: Peter Rounce Date: Wed, 22 Feb 2023 08:13:01 +0000 Subject: [PATCH 3/4] fix formatting --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 46a895c..3456d93 100644 --- a/main.go +++ b/main.go @@ -2,9 +2,9 @@ package main import ( "github.com/boltcard/boltcard/db" + "github.com/boltcard/boltcard/internalapi" "github.com/boltcard/boltcard/lnurlp" "github.com/boltcard/boltcard/lnurlw" - "github.com/boltcard/boltcard/internalapi" "github.com/gorilla/mux" log "github.com/sirupsen/logrus" "net/http" From 775996c8e471a10aff56758fc811f987ed418d5a Mon Sep 17 00:00:00 2001 From: Peter Rounce Date: Wed, 22 Feb 2023 12:38:56 +0000 Subject: [PATCH 4/4] working /updateboltcard --- boltcard.service | 2 +- db/db.go | 6 +++--- internalapi/updateboltcard.go | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/boltcard.service b/boltcard.service index 01d8d37..6ab02b1 100644 --- a/boltcard.service +++ b/boltcard.service @@ -17,7 +17,7 @@ Environment="DB_USER=cardapp" Environment="DB_PASSWORD=database_password" Environment="DB_NAME=card_db" -ExecStart=/bin/bash /home/ubuntu/boltcard/s_launch +ExecStart=/bin/bash /home/ubuntu/boltcard/script/s_launch [Install] WantedBy=multi-user.target diff --git a/db/db.go b/db/db.go index 58a1148..8a6f3b7 100644 --- a/db/db.go +++ b/db/db.go @@ -835,7 +835,7 @@ func Wipe_card(card_name string) (*Card_wipe_info, error) { return &card_wipe_info, nil } -func Update_card(card_name string, tx_max int, lnurlw_enable bool) error { +func Update_card(card_name string, tx_limit_sats int, lnurlw_enable bool) error { lnurlw_enable_yn := "N" if lnurlw_enable { @@ -850,10 +850,10 @@ func Update_card(card_name string, tx_max int, lnurlw_enable bool) error { defer db.Close() - sqlStatement := `UPDATE cards SET tx_max = $2, lnurlw_enable = $3 ` + + sqlStatement := `UPDATE cards SET tx_limit_sats = $2, lnurlw_enable = $3 ` + `WHERE card_name = $1;` - res, err := db.Exec(sqlStatement, card_name, tx_max, lnurlw_enable_yn) + res, err := db.Exec(sqlStatement, card_name, tx_limit_sats, lnurlw_enable_yn) if err != nil { return err diff --git a/internalapi/updateboltcard.go b/internalapi/updateboltcard.go index 6d9e59e..1df3e67 100644 --- a/internalapi/updateboltcard.go +++ b/internalapi/updateboltcard.go @@ -16,10 +16,10 @@ func Updateboltcard(w http.ResponseWriter, r *http.Request) { return } - tx_max_str := r.URL.Query().Get("tx_max") - tx_max, err := strconv.Atoi(tx_max_str) + tx_limit_sats_str := r.URL.Query().Get("tx_limit_sats") + tx_limit_sats, err := strconv.Atoi(tx_limit_sats_str) if err != nil { - msg := "updateboltcard: tx_max is not a valid integer" + msg := "updateboltcard: tx_limit_sats is not a valid integer" log.Warn(msg) resp_err.Write_message(w, msg) return @@ -54,12 +54,12 @@ func Updateboltcard(w http.ResponseWriter, r *http.Request) { // log the request log.WithFields(log.Fields{ - "card_name": card_name, "tx_max": tx_max, - "enable": enable_flag}).Info("createboltcard API request") + "card_name": card_name, "tx_limit_sats": tx_limit_sats, + "enable": enable_flag}).Info("updateboltcard API request") // update the card record - err = db.Update_card(card_name, tx_max, enable_flag) + err = db.Update_card(card_name, tx_limit_sats, enable_flag) if err != nil { log.Warn(err.Error()) return