From 6d2dbf7e95fdb7352da38bb2224936178656780c Mon Sep 17 00:00:00 2001 From: Victor Lacasse-Beaudoin Date: Tue, 13 May 2025 13:27:13 -0400 Subject: [PATCH 1/5] =?UTF-8?q?chores:=20bump=20bottin=20=C3=A0=20v11?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.go | 2 +- go.mod | 35 +++++++++++-------------- go.sum | 76 +++++++++++++++++++++++------------------------------- handler.go | 2 +- main.go | 2 +- server.go | 2 +- 6 files changed, 51 insertions(+), 68 deletions(-) diff --git a/config.go b/config.go index b630b5f..77e0ea4 100644 --- a/config.go +++ b/config.go @@ -5,7 +5,7 @@ import ( "os" "strings" - "git.agecem.com/bottin/bottin/v10/pkg/bottin" + "git.agecem.com/bottin/bottin/v11" "github.com/spf13/cobra" "github.com/spf13/viper" ) diff --git a/go.mod b/go.mod index 14144f2..0f81fd1 100644 --- a/go.mod +++ b/go.mod @@ -4,44 +4,39 @@ go 1.23.6 require ( codeberg.org/vlbeaudoin/voki/v3 v3.0.1 - git.agecem.com/bottin/bottin/v10 v10.6.0 - github.com/jackc/pgx/v5 v5.7.2 + git.agecem.com/bottin/bottin/v11 v11.0.2 + github.com/jackc/pgx/v5 v5.7.4 github.com/labstack/echo/v4 v4.13.3 github.com/spf13/cobra v1.9.1 github.com/spf13/pflag v1.0.6 - github.com/spf13/viper v1.19.0 + github.com/spf13/viper v1.20.1 ) require ( - github.com/fsnotify/fsnotify v1.8.0 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/go-viper/mapstructure/v2 v2.2.1 // indirect github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1 // indirect - github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/labstack/gommon v0.4.2 // indirect - github.com/magiconair/properties v1.8.9 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/pelletier/go-toml/v2 v2.2.3 // indirect - github.com/sagikazarmark/locafero v0.7.0 // indirect - github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect + github.com/sagikazarmark/locafero v0.9.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect - github.com/spf13/afero v1.12.0 // indirect - github.com/spf13/cast v1.7.1 // indirect + github.com/spf13/afero v1.14.0 // indirect + github.com/spf13/cast v1.8.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.35.0 // indirect - golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa // indirect - golang.org/x/net v0.35.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/text v0.22.0 // indirect - golang.org/x/time v0.10.0 // indirect - gopkg.in/ini.v1 v1.67.0 // indirect + golang.org/x/crypto v0.38.0 // indirect + golang.org/x/net v0.40.0 // indirect + golang.org/x/sync v0.14.0 // indirect + golang.org/x/sys v0.33.0 // indirect + golang.org/x/text v0.25.0 // indirect + golang.org/x/time v0.11.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index c20a8c0..054eaae 100644 --- a/go.sum +++ b/go.sum @@ -1,30 +1,29 @@ codeberg.org/vlbeaudoin/voki/v3 v3.0.1 h1:pFjd/ZKsu4eOzRJYViE9F1S3RglSkAuIiqCo9IH9tUI= codeberg.org/vlbeaudoin/voki/v3 v3.0.1/go.mod h1:+6LMXosAu2ijNKV04sMwkeujpH+cghZU1fydqj2y95g= -git.agecem.com/bottin/bottin/v10 v10.6.0 h1:I9xQMizlqfWHrJ1ZL2PlX/EeTpRm+B7bsheaBOVChFM= -git.agecem.com/bottin/bottin/v10 v10.6.0/go.mod h1:KTwlqY5XdVi9F7cpwy3hxYN1DQm+74tBv7Wc9rfKXuM= +git.agecem.com/bottin/bottin/v11 v11.0.2 h1:QtbjTDln3jcd4Vkc66uil+YoLisOPaDy2SerZQ95weo= +git.agecem.com/bottin/bottin/v11 v11.0.2/go.mod h1:c0sV8VOTLtnwel3oCo8xyBTW9zdmrVRwiGEF5NyYjjY= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= -github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= +github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1 h1:FWNFq4fM1wPfcK40yHE5UO3RUdSNPaBC+j3PokzA6OQ= github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI= -github.com/jackc/pgx/v5 v5.7.2/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ= +github.com/jackc/pgx/v5 v5.7.4 h1:9wKznZrhWa2QiHL+NjTSPP6yjl3451BX3imWDnokYlg= +github.com/jackc/pgx/v5 v5.7.4/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -35,38 +34,31 @@ github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaa github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g= github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= -github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM= -github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= -github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo= -github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k= -github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= -github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/sagikazarmark/locafero v0.9.0 h1:GbgQGNtTrEmddYDSAH9QLRyfAHY12md+8YFTqyMTC9k= +github.com/sagikazarmark/locafero v0.9.0/go.mod h1:UBUyz37V+EdMS3hDF3QWIiVr/2dPrx49OMO0Bn0hJqk= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= -github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs= -github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4= -github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= -github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/afero v1.14.0 h1:9tH6MapGnn/j0eb0yIXiLjERO8RB6xIVZRDCX7PtqWA= +github.com/spf13/afero v1.14.0/go.mod h1:acJQ8t0ohCGuMN3O+Pv0V0hgMxNYDlvdk+VTfyZmbYo= +github.com/spf13/cast v1.8.0 h1:gEN9K4b8Xws4EX0+a0reLmhq8moKn7ntRlQYgjPeCDk= +github.com/spf13/cast v1.8.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= -github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= +github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4= +github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -80,26 +72,22 @@ github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQ github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= -golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= -golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa h1:t2QcU6V556bFjYgu4L6C+6VrCPyJZ+eyRsABUPs1mz4= -golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= +golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= +golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= +golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= +golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= +golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= -golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4= -golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= +golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= +golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= +golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/handler.go b/handler.go index 369ec02..e1743c9 100644 --- a/handler.go +++ b/handler.go @@ -6,7 +6,7 @@ import ( "log" "net/http" - "git.agecem.com/bottin/bottin/v10/pkg/bottin" + "git.agecem.com/bottin/bottin/v11" "github.com/labstack/echo/v4" ) diff --git a/main.go b/main.go index de0d965..805212c 100644 --- a/main.go +++ b/main.go @@ -6,7 +6,7 @@ import ( "net/http" "codeberg.org/vlbeaudoin/voki/v3" - "git.agecem.com/bottin/bottin/v10/pkg/bottin" + "git.agecem.com/bottin/bottin/v11" "github.com/jackc/pgx/v5/pgxpool" ) diff --git a/server.go b/server.go index 3c8a182..547773b 100644 --- a/server.go +++ b/server.go @@ -6,7 +6,7 @@ import ( "fmt" "net/http" - "git.agecem.com/bottin/bottin/v10/pkg/bottin" + "git.agecem.com/bottin/bottin/v11" "git.agecem.com/bottin/presences/ui" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" -- 2.47.2 From b3706080cdd310c6c53a9bb7349c6cf0a4b18401 Mon Sep 17 00:00:00 2001 From: Victor Lacasse-Beaudoin Date: Tue, 13 May 2025 13:28:04 -0400 Subject: [PATCH 2/5] chores(deploy): ajouter targets go et docker pour Makefile --- Makefile | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index b6e4afc..4e91951 100644 --- a/Makefile +++ b/Makefile @@ -4,13 +4,40 @@ .DEFAULT_GOAL := help +# splits current git annotated tag into 'MAJOR MINOR PATCH EXTRAS'. +# intended to be used as arguments for certain scripts requiring a semver as args +current_semver := $(shell git describe | tr -d 'v' | tr '.' ' ' | tr '-' ' ') + .PHONY: help help: ## Show this help - @egrep -h '\s##\s' $(MAKEFILE_LIST) | \ + @grep -E -h '\s##\s' $(MAKEFILE_LIST) | \ sort | \ awk \ 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' -.PHONY: build -build: ## Use `docker build` to build the container image - docker build . -f Dockerfile -t git.agecem.com/bottin/presences:latest +.PHONY: go-install +go-install: ## Use `go install` to build and link the executable + go install -a + +.PHONY: docker-build +docker-build: ## Build container image + #docker-compose build \ + #--build-arg bottin_version=`git describe` + docker-compose build + +.PHONY: docker-deploy +docker-deploy: ## Using `docker-compose up`, deploy the database and containers + docker-compose up -d + +.PHONY: docker-tag-from-git +docker-tag-from-git: ## Tag latest image according to annotated tag from `git describe` + ./scripts/docker-tag.sh $(current_semver) + +.PHONY: docker-push-from-git +docker-push-from-git: ## Push images to git.agecem.com according to annotated tag from `git describe` + ./scripts/docker-push.sh $(current_semver) + +## pipelines + +.PHONY: deploy +deploy: docker-build docker-deploy ## Build and deploy container image -- 2.47.2 From 2dcf0ec867a442b9adb900d42c79c5652283efe2 Mon Sep 17 00:00:00 2001 From: Victor Lacasse-Beaudoin Date: Tue, 13 May 2025 13:48:34 -0400 Subject: [PATCH 3/5] =?UTF-8?q?refactor:=20s=C3=A9parer=20executable=20et?= =?UTF-8?q?=20library?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 5 ++-- Makefile | 2 +- cmd.go | 50 ++++++++++++++++++++++++++++++++++- cmd/presences/main.go | 11 ++++++++ config.go | 2 +- db.go | 2 +- entity.go | 2 +- flag.go | 2 +- handler.go | 2 +- main.go | 61 ------------------------------------------- server.go | 2 +- 11 files changed, 70 insertions(+), 71 deletions(-) create mode 100644 cmd/presences/main.go delete mode 100644 main.go diff --git a/Dockerfile b/Dockerfile index fa0572a..c2840ea 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,15 +4,16 @@ LABEL author="vlbeaudoin" WORKDIR /go/src/app -COPY LICENSE cmd.go config.go db.go entity.go flag.go go.mod go.sum handler.go main.go server.go ./ +COPY LICENSE cmd.go config.go db.go entity.go flag.go go.mod go.sum handler.go server.go ./ +ADD cmd/ cmd/ ADD queries/ queries/ ADD ui/ ui/ RUN CGO_ENABLED=0 go build \ -a \ -o presences \ - ./ + ./cmd/presences/ # Alpine diff --git a/Makefile b/Makefile index 4e91951..4553995 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ help: ## Show this help .PHONY: go-install go-install: ## Use `go install` to build and link the executable - go install -a + go install -a ./cmd/presences/ .PHONY: docker-build docker-build: ## Build container image diff --git a/cmd.go b/cmd.go index 738a67b..538d035 100644 --- a/cmd.go +++ b/cmd.go @@ -1,11 +1,15 @@ -package main +package presences import ( "context" "encoding/json" "fmt" "log" + "net/http" + "codeberg.org/vlbeaudoin/voki/v3" + "git.agecem.com/bottin/bottin/v11" + "github.com/jackc/pgx/v5/pgxpool" "github.com/spf13/cobra" ) @@ -49,3 +53,47 @@ var rootCmd = &cobra.Command{ } }, } + +func run(ctx context.Context, cfg Config) error { + select { + case <-ctx.Done(): + return ctx.Err() + default: + bottinClient := bottin.APIClient{Caller: voki.New( + http.DefaultClient, + cfg.Bottin.Host, + cfg.Bottin.Key, + cfg.Bottin.Port, + func() string { + if cfg.Bottin.TLS.Enabled { + return "https" + } else { + return "http" + } + }(), + )} + + // connect to db + dbPool, err := pgxpool.New(ctx, + fmt.Sprintf("postgres://%s:%s@%s:%d/%s?sslmode=%s", + cfg.DB.Username, + cfg.DB.Password, + cfg.DB.Host, + cfg.DB.Port, + cfg.DB.Database, + cfg.DB.SSLMode, + )) + if err != nil { + return err + } + defer dbPool.Close() + + dbClient := DBClient{Pool: dbPool} + + if err := RunUIServer(ctx, cfg, &bottinClient, &dbClient); err != nil && err != http.ErrServerClosed { + return err + } + + return nil + } +} diff --git a/cmd/presences/main.go b/cmd/presences/main.go new file mode 100644 index 0000000..ae112db --- /dev/null +++ b/cmd/presences/main.go @@ -0,0 +1,11 @@ +package main + +import ( + "git.agecem.com/bottin/presences" +) + +// Entry +func main() { + // Start commandline parsing then call `run` + presences.Execute() +} diff --git a/config.go b/config.go index 77e0ea4..c3228ed 100644 --- a/config.go +++ b/config.go @@ -1,4 +1,4 @@ -package main +package presences import ( "fmt" diff --git a/db.go b/db.go index a24994f..2d6447e 100644 --- a/db.go +++ b/db.go @@ -1,4 +1,4 @@ -package main +package presences import ( "context" diff --git a/entity.go b/entity.go index cb4e53e..d7ca315 100644 --- a/entity.go +++ b/entity.go @@ -1,4 +1,4 @@ -package main +package presences import "time" diff --git a/flag.go b/flag.go index 64e7d0f..8a01a21 100644 --- a/flag.go +++ b/flag.go @@ -1,4 +1,4 @@ -package main +package presences import ( "github.com/spf13/pflag" diff --git a/handler.go b/handler.go index e1743c9..53127e8 100644 --- a/handler.go +++ b/handler.go @@ -1,4 +1,4 @@ -package main +package presences import ( "context" diff --git a/main.go b/main.go deleted file mode 100644 index 805212c..0000000 --- a/main.go +++ /dev/null @@ -1,61 +0,0 @@ -package main - -import ( - "context" - "fmt" - "net/http" - - "codeberg.org/vlbeaudoin/voki/v3" - "git.agecem.com/bottin/bottin/v11" - "github.com/jackc/pgx/v5/pgxpool" -) - -// Entry -func main() { - // Start commandline parsing then call `run` - Execute() -} - -func run(ctx context.Context, cfg Config) error { - select { - case <-ctx.Done(): - return ctx.Err() - default: - bottinClient := bottin.APIClient{Caller: voki.New( - http.DefaultClient, - cfg.Bottin.Host, - cfg.Bottin.Key, - cfg.Bottin.Port, - func() string { - if cfg.Bottin.TLS.Enabled { - return "https" - } else { - return "http" - } - }(), - )} - - // connect to db - dbPool, err := pgxpool.New(ctx, - fmt.Sprintf("postgres://%s:%s@%s:%d/%s?sslmode=%s", - cfg.DB.Username, - cfg.DB.Password, - cfg.DB.Host, - cfg.DB.Port, - cfg.DB.Database, - cfg.DB.SSLMode, - )) - if err != nil { - return err - } - defer dbPool.Close() - - dbClient := DBClient{Pool: dbPool} - - if err := RunUIServer(ctx, cfg, &bottinClient, &dbClient); err != nil && err != http.ErrServerClosed { - return err - } - - return nil - } -} diff --git a/server.go b/server.go index 547773b..59d809d 100644 --- a/server.go +++ b/server.go @@ -1,4 +1,4 @@ -package main +package presences import ( "context" -- 2.47.2 From 940c6d8a257896555dbfcf335b6d1f48b1bd1b80 Mon Sep 17 00:00:00 2001 From: Victor Lacasse-Beaudoin Date: Tue, 13 May 2025 16:15:05 -0400 Subject: [PATCH 4/5] feat: add DB flags, fix presence config, switch basicauth to map --- compose.yaml | 2 +- config.go | 11 +++--- flag.go | 99 ++++++++++++++++++++++++++++++++++++++++++++-------- server.go | 16 ++++----- 4 files changed, 98 insertions(+), 30 deletions(-) diff --git a/compose.yaml b/compose.yaml index 47ed675..b6de464 100644 --- a/compose.yaml +++ b/compose.yaml @@ -39,7 +39,7 @@ services: volumes: - 'presences-config:/etc/presences/' restart: 'unless-stopped' - command: ['presences', '--config', '/etc/presences/config.yaml', 'server'] + command: ['presences', '--config', '/etc/presences/config.yaml'] adminer: depends_on: diff --git a/config.go b/config.go index c3228ed..4ce0ba5 100644 --- a/config.go +++ b/config.go @@ -33,13 +33,12 @@ type Config struct { Key string } - // Credentials holds username-password pairs for basic authentication - // not part of minimum viable product - //Credentials map[string]string - UI struct { - Username string - Password string + //Username string + //Password string + + // Credentials holds username-password pairs for basic authentication + Credentials map[string]string } // Port holds the port on which to expose the user interface diff --git a/flag.go b/flag.go index 8a01a21..014b0c6 100644 --- a/flag.go +++ b/flag.go @@ -6,37 +6,106 @@ import ( ) const ( - configPort = "Port" - defaultPort = 8080 - flagPort = "port" + flagPortConfig = "Port" + flagPortDefault = 8080 + flagPort = "port" - configTLSCert = "TLS.Cert" - defaultTLSCert = "" - flagTLSCert = "tls-cert" + flagTLSCertConfig = "TLS.Cert" + flagTLSCertDefault = "" + flagTLSCert = "tls-cert" - configTLSKey = "TLS.Key" - defaultTLSKey = "" - flagTLSKey = "tls-key" + flagTLSKeyConfig = "TLS.Key" + flagTLSKeyDefault = "" + flagTLSKey = "tls-key" + + flagDBDatabaseConfig = "DB.Database" + flagDBDatabaseDefault = "presences" + flagDBDatabase = "db-database" + + flagDBHostConfig = "DB.Host" + flagDBHostDefault = "presences-db" + flagDBHost = "db-host" + + flagDBPasswordConfig = "DB.Password" + flagDBPasswordDefault = "presences" + flagDBPassword = "db-password" + + flagDBPortConfig = "DB.Port" + flagDBPortDefault = 5432 + flagDBPort = "db-port" + + flagDBSSLModeConfig = "DB.SSLMode" + flagDBSSLModeDefault = "prefer" + flagDBSSLMode = "db-sslmode" + + flagDBUsernameConfig = "DB.Username" + flagDBUsernameDefault = "presences" + flagDBUsername = "db-username" + + /* + flagUICredentialsConfig = "UI.Credentials" + //flagUICredentialsDefault = make(map[string]string) + flagUICredentials = "ui-credentials" + */ + + //TODO check if any necessary flags are missing ) // BindClientFlags declares client-related flags and config options in the specified *pflag.FlagSet func BindFlags(set *pflag.FlagSet) error { // Credentials -> seulement par config - set.Int(flagPort, defaultPort, "User interface port") - if err := viper.BindPFlag(configPort, set.Lookup(flagPort)); err != nil { + set.Int(flagPort, flagPortDefault, "User interface port") + if err := viper.BindPFlag(flagPortConfig, set.Lookup(flagPort)); err != nil { return err } - set.String(flagTLSKey, defaultTLSKey, "User interface TLS private key (or path to file)") - if err := viper.BindPFlag(configTLSKey, set.Lookup(flagTLSKey)); err != nil { + set.String(flagTLSKey, flagTLSKeyDefault, "User interface TLS private key (or path to file)") + if err := viper.BindPFlag(flagTLSKeyConfig, set.Lookup(flagTLSKey)); err != nil { return err } - set.String(flagTLSCert, defaultTLSCert, "User interface TLS certificate (or path to file)") - if err := viper.BindPFlag(configTLSCert, set.Lookup(flagTLSCert)); err != nil { + set.String(flagTLSCert, flagTLSCertDefault, "User interface TLS certificate (or path to file)") + if err := viper.BindPFlag(flagTLSCertConfig, set.Lookup(flagTLSCert)); err != nil { return err } + set.String(flagDBDatabase, flagDBDatabaseDefault, "PostgreSQL database") + if err := viper.BindPFlag(flagDBDatabaseConfig, set.Lookup(flagDBDatabase)); err != nil { + return err + } + + set.String(flagDBHost, flagDBHostDefault, "PostgreSQL host") + if err := viper.BindPFlag(flagDBHostConfig, set.Lookup(flagDBHost)); err != nil { + return err + } + + set.String(flagDBPassword, flagDBPasswordDefault, "PostgreSQL password") + if err := viper.BindPFlag(flagDBPasswordConfig, set.Lookup(flagDBPassword)); err != nil { + return err + } + + set.Int(flagDBPort, flagDBPortDefault, "PostgreSQL port") + if err := viper.BindPFlag(flagDBPortConfig, set.Lookup(flagDBPort)); err != nil { + return err + } + + set.String(flagDBSSLMode, flagDBSSLModeDefault, "PostgreSQL ssl mode") + if err := viper.BindPFlag(flagDBSSLModeConfig, set.Lookup(flagDBSSLMode)); err != nil { + return err + } + + set.String(flagDBUsername, flagDBUsernameDefault, "PostgreSQL username") + if err := viper.BindPFlag(flagDBUsernameConfig, set.Lookup(flagDBUsername)); err != nil { + return err + } + + /* + set.StringToString(flagUICredentials, nil, "Sets of credentials for the UI console") + if err := viper.BindPFlag(flagUICredentialsConfig, set.Lookup(flagUICredentials)); err != nil { + return err + } + */ + return nil } diff --git a/server.go b/server.go index 59d809d..fdd02a3 100644 --- a/server.go +++ b/server.go @@ -41,19 +41,19 @@ func RunUIServer(ctx context.Context, cfg Config, bottinClient *bottin.APIClient e.Pre(middleware.AddTrailingSlash()) - // basic auth - if cfg.UI.Username == "" || cfg.UI.Password == "" { - return fmt.Errorf("UI username and password cannot be empty, please set UI.Password and UI.Username (PRESENCES_UI_PASSWORD and PRESENCES_UI_USERNAME") + if len(cfg.UI.Credentials) == 0 { + return fmt.Errorf("UI.Credentials config file option of type map[string]string must contain at least one username-password key-value pair. Note that there is no flag or ENV counterpart, this must be done through a config file.") } e.Pre(middleware.BasicAuth( func(username, password string, c echo.Context) (bool, error) { - userOK := subtle.ConstantTimeCompare([]byte(username), []byte(cfg.UI.Username)) == 1 - passOK := subtle.ConstantTimeCompare([]byte(password), []byte(cfg.UI.Password)) == 1 - if userOK && passOK { - return true, nil + rightPassword, userExists := cfg.UI.Credentials[username] + if !userExists { + return false, nil } - return false, nil + + passwordOK := subtle.ConstantTimeCompare([]byte(password), []byte(rightPassword)) == 1 + return passwordOK, nil }), ) -- 2.47.2 From 47b8c2b766bb807d55a365a040c7760c63125cf1 Mon Sep 17 00:00:00 2001 From: Victor Lacasse-Beaudoin Date: Tue, 13 May 2025 16:43:27 -0400 Subject: [PATCH 5/5] =?UTF-8?q?feat:=20autog=C3=A9n=C3=A9rer=20certificat?= =?UTF-8?q?=20TLS=20si=20non-fourni?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 2 +- server.go | 29 +++++++++++++++++++-- x509.go | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 x509.go diff --git a/Dockerfile b/Dockerfile index c2840ea..07cf33f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ LABEL author="vlbeaudoin" WORKDIR /go/src/app -COPY LICENSE cmd.go config.go db.go entity.go flag.go go.mod go.sum handler.go server.go ./ +COPY LICENSE cmd.go config.go db.go entity.go flag.go go.mod go.sum handler.go server.go x509.go ./ ADD cmd/ cmd/ ADD queries/ queries/ diff --git a/server.go b/server.go index fdd02a3..e583d80 100644 --- a/server.go +++ b/server.go @@ -3,7 +3,9 @@ package presences import ( "context" "crypto/subtle" + "crypto/tls" "fmt" + "log" "net/http" "git.agecem.com/bottin/bottin/v11" @@ -69,7 +71,30 @@ func RunUIServer(ctx context.Context, cfg Config, bottinClient *bottin.APIClient address := fmt.Sprintf(":%d", cfg.Port) - return e.StartTLS(address, cfg.TLS.Cert, cfg.TLS.Key) - } + switch { + case cfg.TLS.Cert != "" && cfg.TLS.Key != "": + return e.StartTLS(address, cfg.TLS.Cert, cfg.TLS.Key) + case cfg.TLS.Cert != "" && cfg.TLS.Key == "": + return fmt.Errorf("found TLS certificate but missing associated TLS private key") + case cfg.TLS.Cert == "" && cfg.TLS.Key != "": + return fmt.Errorf("found TLS private key but missing associated TLS certificate") + default: + log.Println("No TLS pair was provided. Generating self-signed pair.") + tlsPair, err := newTLSPair() + if err != nil { + return err + } + + server := &http.Server{ + Addr: address, + Handler: e, + TLSConfig: &tls.Config{ + Certificates: []tls.Certificate{tlsPair}, + }, + } + + return server.ListenAndServeTLS("", "") + } + } } diff --git a/x509.go b/x509.go new file mode 100644 index 0000000..434c720 --- /dev/null +++ b/x509.go @@ -0,0 +1,74 @@ +package presences + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/tls" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "fmt" + "math/big" + "time" +) + +func newTLSPair() (tls.Certificate, error) { + //TODO revise this code to make sure it is satisfying + + // Generate an ECDSA private key using P256. + priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + return tls.Certificate{}, fmt.Errorf("Failed to generate private key: %v", err) + } + + // Generate a random serial number. + serialNumber, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128)) + if err != nil { + return tls.Certificate{}, fmt.Errorf("Failed to generate serial number: %v", err) + } + + // Create a certificate template. + template := x509.Certificate{ + SerialNumber: serialNumber, + Subject: pkix.Name{ + Organization: []string{"AGECEM-bottin-presences"}, + CommonName: "localhost", // common name localhost for local development + }, + NotBefore: time.Now().Add(-time.Hour), // valid from 1 hour ago + NotAfter: time.Now().Add(365 * 24 * time.Hour), // valid for 1 year + KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + BasicConstraintsValid: true, + IsCA: true, // self-signed, so we can mark it as CA (optional) + } + + // Self-sign the certificate. + derCert, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) + if err != nil { + return tls.Certificate{}, fmt.Errorf("Failed to create certificate: %v", err) + } + + // Encode the certificate PEM block. + certPEM := pem.EncodeToMemory(&pem.Block{ + Type: "CERTIFICATE", + Bytes: derCert, + }) + // Encode the private key PEM block. + keyBytes, err := x509.MarshalECPrivateKey(priv) + if err != nil { + return tls.Certificate{}, fmt.Errorf("Unable to marshal ECDSA private key: %v", err) + } + keyPEM := pem.EncodeToMemory(&pem.Block{ + Type: "EC PRIVATE KEY", + Bytes: keyBytes, + }) + + // Load the generated certificate into a tls.Certificate. + tlsCert, err := tls.X509KeyPair(certPEM, keyPEM) + if err != nil { + return tls.Certificate{}, fmt.Errorf("failed to load X509 key pair: %v", err) + } + + return tlsCert, nil +} -- 2.47.2