diff --git a/.github/workflows/build-docker-container.yml b/.github/workflows/build-docker-container.yml index 1d306db..52f4967 100644 --- a/.github/workflows/build-docker-container.yml +++ b/.github/workflows/build-docker-container.yml @@ -1,8 +1,8 @@ -name: ci +name: docker-build on: - push: - branches: ["binary-release", "master", "devel"] + release: + types: [published] jobs: docker: @@ -20,3 +20,5 @@ jobs: with: push: true tags: hilkopterbob/packagelock:latest + build-args: | + APP_VERSION=${{ github.event.release.tag_name }} diff --git a/.github/workflows/unstable-build-docker-container.yml b/.github/workflows/unstable-build-docker-container.yml new file mode 100644 index 0000000..368beb2 --- /dev/null +++ b/.github/workflows/unstable-build-docker-container.yml @@ -0,0 +1,21 @@ +name: unstable-docker-build + +on: + push: + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + - name: Build and push + uses: docker/build-push-action@v6 + with: + push: true + tags: hilkopterbob/packagelock:unstable-${{ github.head_ref || github.ref_name }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..22d61ac --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +certs/** diff --git a/Dockerfile b/Dockerfile index 0fbe7c2..a725d4b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,8 +16,9 @@ RUN go mod download # Build - -RUN CGO_ENABLED=0 GOOS=linux go build -o /packagelock +ARG APP_VERSION="v0.1.0+hotfixes" +RUN \ + CGO_ENABLED=0 GOOS=linux go build -ldflags "-X 'main.AppVersion=$APP_VERSION'" -o /packagelock # Optional: # To bind to a TCP port, runtime parameters must be supplied to the docker command. diff --git a/README.md b/README.md index dc0fe74..0c7891c 100644 --- a/README.md +++ b/README.md @@ -133,7 +133,6 @@ TODO: explain usage - [ ] installable agent as background daemon - [ ] config management - [ ] TLS Encryption -- [ ] Secured API - [ ] Best Practice based Package Layout - [ ] Check Vars and Func-Names for naming convention - [ ] persistent storage diff --git a/config.yaml b/config.yaml index f43b98a..a1ced5a 100644 --- a/config.yaml +++ b/config.yaml @@ -5,7 +5,8 @@ network: forcehttp: true fqdn: 0.0.0.0 port: 8080 - ssl: + ssl: true + ssl-config: allowselfsigned: true - certificatepath: /etc/packagelock/ssl/cert.pem - privatekeypath: /etc/packagelock/ssl/privkey.pem + certificatepath: ./certs/testing.crt + privatekeypath: ./certs/testing.key diff --git a/config/conf-init.go b/config/conf-init.go index a521c19..fc48228 100644 --- a/config/conf-init.go +++ b/config/conf-init.go @@ -9,6 +9,8 @@ import ( "github.com/spf13/viper" ) +var Config ConfigProvider + type ConfigProvider interface { SetConfigName(name string) SetConfigType(fileext string) @@ -20,6 +22,8 @@ type ConfigProvider interface { ReadConfig(in io.Reader) error AllSettings() map[string]any GetString(string string) string + SetDefault(key string, value any) + Get(key string) any } // TODO: How to test? diff --git a/go.mod b/go.mod index d2c7c5a..22baf34 100644 --- a/go.mod +++ b/go.mod @@ -4,54 +4,45 @@ go 1.22.6 require ( github.com/fsnotify/fsnotify v1.7.0 - github.com/gin-gonic/gin v1.10.0 + github.com/gofiber/fiber/v2 v2.52.5 github.com/spf13/viper v1.19.0 - github.com/stretchr/testify v1.9.0 ) require ( - github.com/bytedance/sonic v1.12.1 // indirect - github.com/bytedance/sonic/loader v0.2.0 // indirect - github.com/cloudwego/base64x v0.1.4 // indirect - github.com/cloudwego/iasm v0.2.0 // indirect - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 // indirect - github.com/gabriel-vasile/mimetype v1.4.5 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect - github.com/go-playground/locales v0.14.1 // indirect - github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.22.0 // indirect - github.com/goccy/go-json v0.10.3 // indirect + github.com/MicahParks/keyfunc/v2 v2.1.0 // indirect + github.com/andybalholm/brotli v1.1.0 // indirect + github.com/gofiber/contrib/jwt v1.0.10 // indirect + github.com/gofiber/jwt/v3 v3.3.10 // indirect + github.com/gofiber/template v1.8.3 // indirect + github.com/gofiber/template/html/v2 v2.1.2 // indirect + github.com/gofiber/utils v1.1.0 // indirect + github.com/golang-jwt/jwt/v4 v4.5.0 // indirect + github.com/golang-jwt/jwt/v5 v5.2.1 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/cpuid/v2 v2.2.8 // indirect - github.com/leodido/go-urn v1.4.0 // indirect + github.com/klauspost/compress v1.17.9 // indirect github.com/magiconair/properties v1.8.7 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/rivo/uniseg v0.4.7 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect - github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.12 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasthttp v1.55.0 // indirect + github.com/valyala/tcplisten v1.0.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect - golang.org/x/arch v0.9.0 // indirect - golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/net v0.28.0 // indirect golang.org/x/sys v0.24.0 // indirect golang.org/x/text v0.17.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 3448d0b..9356de8 100644 --- a/go.sum +++ b/go.sum @@ -1,12 +1,9 @@ -github.com/bytedance/sonic v1.12.1 h1:jWl5Qz1fy7X1ioY74WqO0KjAMtAGQs4sYnjiEBiyX24= -github.com/bytedance/sonic v1.12.1/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= -github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= -github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= -github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= -github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= -github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= -github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= -github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/MicahParks/keyfunc/v2 v2.1.0 h1:6ZXKb9Rp6qp1bDbJefnG7cTH8yMN1IC/4nf+GVjO99k= +github.com/MicahParks/keyfunc/v2 v2.1.0/go.mod h1:rW42fi+xgLJ2FRRXAfNx9ZA8WpD4OeE/yHVMteCkw9k= +github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= +github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= +github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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= @@ -15,35 +12,37 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 h1:6VSn3hB5U5GeA6kQw4TwWIWbOhtvR2hmbBJnTOtqTWc= -github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6/go.mod h1:YxOVT5+yHzKvwhsiSIWmbAYM3Dr9AEEbER2dVayfBkg= -github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4= -github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= -github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= -github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= -github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= -github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= -github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= -github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao= -github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= -github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= -github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/gofiber/contrib/jwt v1.0.10 h1:/ilGepl6i0Bntl0Zcd+lAzagY8BiS1+fEiAj32HMApk= +github.com/gofiber/contrib/jwt v1.0.10/go.mod h1:1qBENE6sZ6PPT4xIpBzx1VxeyROQO7sj48OlM1I9qdU= +github.com/gofiber/fiber/v2 v2.45.0/go.mod h1:DNl0/c37WLe0g92U6lx1VMQuxGUQY5V7EIaVoEsUffc= +github.com/gofiber/fiber/v2 v2.52.5 h1:tWoP1MJQjGEe4GB5TUGOi7P2E0ZMMRx5ZTG4rT+yGMo= +github.com/gofiber/fiber/v2 v2.52.5/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ= +github.com/gofiber/jwt/v3 v3.3.10 h1:0bpWtFKaGepjwYTU4efHfy0o+matSqZwTxGMo5a+uuc= +github.com/gofiber/jwt/v3 v3.3.10/go.mod h1:GJorFVaDyfMPSK9RB8RG4NQ3s1oXKTmYaoL/ny08O1A= +github.com/gofiber/template v1.8.3 h1:hzHdvMwMo/T2kouz2pPCA0zGiLCeMnoGsQZBTSYgZxc= +github.com/gofiber/template v1.8.3/go.mod h1:bs/2n0pSNPOkRa5VJ8zTIvedcI/lEYxzV3+YPXdBvq8= +github.com/gofiber/template/html/v2 v2.1.2 h1:wkK/mYJ3nIhongTkG3t0QgV4ADdgOYJYVSAF2AHnh8Y= +github.com/gofiber/template/html/v2 v2.1.2/go.mod h1:E98Z/FzvpaSib06aWEgYk6GXNf3ctoyaJH8yW5ay5ak= +github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM= +github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 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/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= -github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= -github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4= +github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -51,30 +50,41 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= -github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 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/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= 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/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0= 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/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= 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/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= 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/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94/go.mod h1:90zrgN3D/WJsDd1iXHT96alCoN2KJo6/4x1DZC3wZs8= +github.com/savsgio/gotils v0.0.0-20220530130905-52f3993e8d6d/go.mod h1:Gy+0tqhJvgGlqnTF8CVGP0AaGRjwBtXs/a5PA0Y3+A4= +github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee/go.mod h1:qwtSXrKuJh/zsFQ12yEE89xfCrGKK63Rr7ctU/uCo4g= 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.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= @@ -88,42 +98,91 @@ github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= 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= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= -github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= -github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/tinylib/msgp v1.1.6/go.mod h1:75BAfg2hauQhs3qedfdDZmWAPcFMAvJE5b9rGOMufyw= +github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.47.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA= +github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA= +github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g= +github.com/valyala/fasthttp v1.55.0 h1:Zkefzgt6a7+bVKHnu/YaYSOPfNYNisSVBo/unVCf8k8= +github.com/valyala/fasthttp v1.55.0/go.mod h1:NkY9JtkrpPKmgwV3HTaS2HWaJss9RSIsRVfcxxoHiOM= +github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= -golang.org/x/arch v0.9.0 h1:ub9TgUInamJ8mrZIGlBG6/4TqWeMszd4N8lNorbrr6k= -golang.org/x/arch v0.9.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 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= @@ -132,4 +191,3 @@ 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= -nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= diff --git a/handler/UserGroup.go b/handler/UserGroup.go new file mode 100644 index 0000000..e7c62d7 --- /dev/null +++ b/handler/UserGroup.go @@ -0,0 +1,86 @@ +package handler + +import ( + "log" + "os" + "packagelock/config" + "packagelock/structs" + "time" + + "github.com/gofiber/fiber/v2" + "github.com/golang-jwt/jwt/v5" +) + +func LoginHandler(c *fiber.Ctx) error { + type LoginRequest struct { + Username string `json:"username"` + Password string `json:"password"` + } + + var loginReq LoginRequest + if err := c.BodyParser(&loginReq); err != nil { + return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ + "error": "Failed to parse request", + }) + } + + var user structs.User + // Find the user by username + for _, u := range Users { + if u.Username == loginReq.Username { + user = u + break + } + } + + // As 'user' is a struct, check for a must-have value (USerID) + // If UserID == "" the user couldn't be found -> doesn't exist! + if user.UserID == "" { + return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ + "error": "Invalid username or password", + }) + } + + // Validate the password + if user.Password != loginReq.Password { + return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ + "error": "Invalid username or password", + }) + } + + // Generate JWT token + token := jwt.New(jwt.SigningMethodRS256) + claims := token.Claims.(jwt.MapClaims) + claims["username"] = user.Username + claims["userID"] = user.UserID + claims["exp"] = time.Now().Add(time.Hour * 72).Unix() // 3 days expiry + + // Sign and get the encoded token + keyData, err := os.ReadFile(config.Config.GetString("network.ssl.privatekeypath")) + if err != nil { + log.Fatal(err) + } + + privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(keyData) + if err != nil { + log.Fatal(err) + } + + tokenString, err := token.SignedString(privateKey) + if err != nil { + log.Println("Failed to generate JWT token:", err) + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed to generate token", + }) + } + + // Add the token to the user's APIToken slice + user.APIToken = append(user.APIToken, tokenString) + + // Return the token and user information + return c.JSON(fiber.Map{ + "message": "Login successful", + "token": tokenString, + "username": user.Username, + }) +} diff --git a/handler/agentgroup.go b/handler/agentgroup.go index 53bc3d6..ee8a4dd 100644 --- a/handler/agentgroup.go +++ b/handler/agentgroup.go @@ -1,61 +1,70 @@ package handler import ( - "net/http" "packagelock/structs" "strconv" - "github.com/gin-gonic/gin" + "github.com/gofiber/fiber/v2" ) // GetAgentByID filters a slice of Agents for a matching Agent.Agent_ID. -// It returns IndentedJSON with: http.StatusOK or http.StatusNotFound. -func GetAgentByID(c *gin.Context) { - id := c.Param("id") +// It returns a JSON response with fiber.StatusOK or fiber.StatusNotFound. +func GetAgentByID(c *fiber.Ctx) error { + id := c.Params("id") for _, a := range Agents { if strconv.Itoa(a.Host_ID) == id { - c.IndentedJSON(http.StatusOK, a) - return + return c.Status(fiber.StatusOK).JSON(a) } } - c.IndentedJSON(http.StatusNotFound, gin.H{"message": "no agent under that id"}) + return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"message": "no agent under that id"}) } -// POST Functions -func RegisterAgent(c *gin.Context) { +// RegisterAgent handles POST requests to register a new agent. +func RegisterAgent(c *fiber.Ctx) error { var newAgent structs.Agent - if err := c.BindJSON(&newAgent); err != nil { + // Parse the JSON request body into newAgent + if err := c.BodyParser(&newAgent); err != nil { // TODO: Add logs - // TODO: Add errorhandling - return + // TODO: Add error handling + return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ + "error": "Cannot parse JSON", + }) } + // Add new agent to the Agents slice Agents = append(Agents, newAgent) - c.IndentedJSON(http.StatusCreated, newAgent) + + // Respond with the newly created agent + return c.Status(fiber.StatusCreated).JSON(newAgent) } -func GetHostByAgentID(c *gin.Context) { - var agent_by_id structs.Agent +// GetHostByAgentID finds the host for a given agent ID. +func GetHostByAgentID(c *fiber.Ctx) error { + var agentByID structs.Agent - // gets the value from /agent/:id/host - id := c.Param("id") + // Get the value from /agent/:id/host + id := c.Params("id") - // finds the agent by the URL-ID + // Find the agent by the URL-ID for _, a := range Agents { if strconv.Itoa(a.Host_ID) == id { - // c.IndentedJSON(http.StatusOK, a) - agent_by_id = a + agentByID = a + break } } - // finds host with same id as agent + if agentByID.Agent_ID == 0 { + return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"message": "no agent under that id"}) + } + + // Find the host with the same id as the agent for _, host := range Hosts { - if host.ID == agent_by_id.Agent_ID { - c.IndentedJSON(http.StatusOK, host) - return + if host.ID == agentByID.Agent_ID { + return c.Status(fiber.StatusOK).JSON(host) } } - c.IndentedJSON(http.StatusNotFound, gin.H{"message": "no agent under that id"}) + + return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"message": "no host found for that agent"}) } diff --git a/handler/generalgroup.go b/handler/generalgroup.go index f04eb91..cc03f83 100644 --- a/handler/generalgroup.go +++ b/handler/generalgroup.go @@ -1,15 +1,15 @@ package handler import ( - "net/http" - - "github.com/gin-gonic/gin" + "github.com/gofiber/fiber/v2" ) -func GetHosts(c *gin.Context) { - c.IndentedJSON(http.StatusOK, Hosts) +// GetHosts responds with a list of all hosts. +func GetHosts(c *fiber.Ctx) error { + return c.Status(fiber.StatusOK).JSON(Hosts) } -func GetAgents(c *gin.Context) { - c.IndentedJSON(http.StatusOK, Agents) +// GetAgents responds with a list of all agents. +func GetAgents(c *fiber.Ctx) error { + return c.Status(fiber.StatusOK).JSON(Agents) } diff --git a/handler/hostgroup.go b/handler/hostgroup.go index e62257e..7a3fdfe 100644 --- a/handler/hostgroup.go +++ b/handler/hostgroup.go @@ -1,21 +1,27 @@ package handler import ( - "net/http" "packagelock/structs" - "github.com/gin-gonic/gin" + "github.com/gofiber/fiber/v2" ) -func RegisterHost(c *gin.Context) { +// RegisterHost handles the registration of a new host. +func RegisterHost(c *fiber.Ctx) error { var newHost structs.Host - if err := c.BindJSON(&newHost); err != nil { + // Parse the JSON request body into newHost + if err := c.BodyParser(&newHost); err != nil { // TODO: Add logs - // TODO: Add errorhandling - return + // TODO: Add error handling + return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ + "error": "Cannot parse JSON", + }) } + // Append new host to the Hosts slice Hosts = append(Hosts, newHost) - c.IndentedJSON(http.StatusCreated, newHost) + + // Respond with the newly created host + return c.Status(fiber.StatusCreated).JSON(newHost) } diff --git a/handler/synth_data.go b/handler/synth_data.go index 7110159..c0031f3 100644 --- a/handler/synth_data.go +++ b/handler/synth_data.go @@ -13,3 +13,8 @@ var Agents = []structs.Agent{ {Agent_name: "Agent Host2", Agent_secret: "11:11:11:12", Host_ID: 2, Agent_ID: 2}, {Agent_name: "Agent Host3", Agent_secret: "11:11:11:13", Host_ID: 3, Agent_ID: 3}, } + +var Users = []structs.User{ + {Username: "JohnDoe", Password: "password123", UserID: "12345", APIToken: []string{"token1", "token2", "token3"}}, + {Username: "JaneDoe", Password: "password456", UserID: "67890", APIToken: []string{"token4", "token5", "token6"}}, +} diff --git a/main.go b/main.go index 419126f..4b135b8 100644 --- a/main.go +++ b/main.go @@ -3,7 +3,6 @@ package main import ( "context" "fmt" - "net/http" "os" "os/signal" "packagelock/config" @@ -15,13 +14,23 @@ import ( "github.com/spf13/viper" ) -// Data structs +// Linker Injections +// Version injection with Docker Build & ldflags +// Do not modify, init or change in code! +var AppVersion string // TODO: support for multiple network adapters. func main() { - Config := config.StartViper(viper.New()) - fmt.Println(Config.AllSettings()) + // Start Viper for config management + config.Config = config.StartViper(viper.New()) + + // If AppVersion is injected, set it in the configuration + if AppVersion != "" { + config.Config.SetDefault("general.app-version", AppVersion) + } + + fmt.Println(config.Config.AllSettings()) // Channel to signal the restart restartChan := make(chan struct{}) @@ -31,39 +40,51 @@ func main() { // Start the server in a goroutine go func() { for { - router := server.AddRoutes() - serverAddr := Config.GetString("network.fqdn") + ":" + Config.GetString("network.port") - srv := &http.Server{ - Addr: serverAddr, - Handler: router.Router.Handler(), - } + // Add Fiber routes + router := server.AddRoutes(config.Config) + + // Fiber does not use the standard http.Server + // Setup server address from config + serverAddr := config.Config.GetString("network.fqdn") + ":" + config.Config.GetString("network.port") + // Fiber specific server start go func() { - fmt.Printf("Starting server at %s...\n", serverAddr) - if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { - fmt.Printf("Server error: %s\n", err) + fmt.Printf("Starting Fiber HTTPS server at https://%s...\n", serverAddr) + + // start ssl session if ssl:true is set in config file, else start http + if config.Config.Get("network.ssl") == true { + if err := server.ListenAndServeTLS(router.Router, config.Config.GetString("network.ssl-config.certificatepath"), config.Config.GetString("network.ssl-config.privatekeypath"), serverAddr); err != nil { + fmt.Printf("Server error: %s\n", err) + } + } else { + fmt.Printf("Starting Fiber server at %s...\n", serverAddr) + if err := router.Router.Listen(serverAddr); err != nil { + fmt.Printf("Server error: %s\n", err) + } } }() // Wait for either a restart signal or termination signal select { case <-restartChan: - fmt.Println("Restarting server...") + fmt.Println("Restarting Fiber server...") - // Gracefully shutdown the server - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + // Gracefully shutdown the Fiber server + _, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - if err := srv.Shutdown(ctx); err != nil { + if err := router.Router.Shutdown(); err != nil { fmt.Printf("Server shutdown failed: %v\n", err) } else { fmt.Println("Server stopped.") } case <-quitChan: - fmt.Println("Shutting down server...") - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + fmt.Println("Shutting down Fiber server...") + + // Gracefully shutdown on quit signal + _, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - if err := srv.Shutdown(ctx); err != nil { + if err := router.Router.Shutdown(); err != nil { fmt.Printf("Server shutdown failed: %v\n", err) } else { fmt.Println("Server stopped gracefully.") @@ -74,12 +95,12 @@ func main() { }() // Watch for configuration changes - Config.OnConfigChange(func(e fsnotify.Event) { + config.Config.OnConfigChange(func(e fsnotify.Event) { fmt.Println("Config file changed:", e.Name) fmt.Println("Restarting to apply changes...") restartChan <- struct{}{} // Send signal to restart the server }) - Config.WatchConfig() + config.Config.WatchConfig() // Block until quit signal is received <-quitChan diff --git a/server/router.go b/server/router.go index bd4ad80..c93959c 100644 --- a/server/router.go +++ b/server/router.go @@ -1,50 +1,116 @@ package server import ( + "log" + "os" + "packagelock/config" "packagelock/handler" - "github.com/gin-gonic/gin" + "github.com/gofiber/fiber/v2" + "github.com/gofiber/fiber/v2/middleware/recover" + "github.com/gofiber/template/html/v2" + + jwtware "github.com/gofiber/contrib/jwt" + "github.com/golang-jwt/jwt/v5" ) -// 'Routes' holds the gin-Engine Pointer. +// Routes holds the Fiber app instance. type Routes struct { - Router *gin.Engine + Router *fiber.App +} + +// addAgentHandler sets up agent-related routes in Fiber. +func (r Routes) addAgentHandler(group fiber.Router) { + AgentGroup := group.Group("/agent") + + AgentGroup.Get("/:id", handler.GetAgentByID) + AgentGroup.Get("/:id/host", handler.GetHostByAgentID) + AgentGroup.Post("/register", handler.RegisterAgent) } -func (router Routes) addAgentHandler(rg *gin.RouterGroup) { - AgentGroup := rg.Group("/agent") +// addGeneralHandler sets up general-related routes in Fiber. +func (r Routes) addGeneralHandler(group fiber.Router) { + GeneralGroup := group.Group("/general") - AgentGroup.GET("/:id", handler.GetAgentByID) - AgentGroup.GET("/:id/host", handler.GetHostByAgentID) - AgentGroup.POST("/register", handler.RegisterAgent) + GeneralGroup.Get("/hosts", handler.GetHosts) + GeneralGroup.Get("/agents", handler.GetAgents) } -func (router Routes) addGeneralHandler(rg *gin.RouterGroup) { - GeneralGroup := rg.Group("/general") +// addHostHandler sets up host-related routes in Fiber. +func (r Routes) addHostHandler(group fiber.Router) { + HostGroup := group.Group("/host") - GeneralGroup.GET("/hosts", handler.GetHosts) - GeneralGroup.GET("/agents", handler.GetAgents) + HostGroup.Post("/register", handler.RegisterHost) } -func (router Routes) addHostHandler(rg *gin.RouterGroup) { - HostGroup := rg.Group("/host") +func (r Routes) addLoginHandler(group fiber.Router) { + LoginGroup := group.Group("/auth") - HostGroup.POST("/register", handler.RegisterHost) + LoginGroup.Post("/login", handler.LoginHandler) } -// AddRoutes adds all handler groups to the current router. -// Its Exported, used in main() and returns a Router typed Routes. -// AddRoutes calls all add_handlergroupname_Handler functions. -func AddRoutes() Routes { +// AddRoutes adds all handler groups to the current Fiber app. +// It's exported and used in main() to return the configured Router. +func AddRoutes(Config config.ConfigProvider) Routes { + // Initialize template engine + engine := html.New("./templates", ".html") + + // Initialize Fiber app router := Routes{ - Router: gin.Default(), + Router: fiber.New(fiber.Config{ + Views: engine, + }), + } + + router.addLoginHandler(router.Router) + + // Use JWT if in production + if Config.Get("general.production") == true { + // Read the private key for JWT + keyData, err := os.ReadFile(Config.GetString("network.ssl.privatekeypath")) + if err != nil { + log.Fatal(err) + } + privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(keyData) + if err != nil { + log.Fatal(err) + } + + // JWT Middleware to protect specific routes + jwtMiddleware := jwtware.New(jwtware.Config{ + SigningKey: jwtware.SigningKey{Key: privateKey}, + }) + + // Apply JWT protection to all routes in the "/v1" group + v1 := router.Router.Group("/v1", jwtMiddleware) + + // Add route handlers to the protected group + router.addGeneralHandler(v1) + router.addAgentHandler(v1) + router.addHostHandler(v1) + } else { + // Create the versioned route group without JWT protection (for non-production environments) + v1 := router.Router.Group("/v1") + + // Add route handlers without JWT protection + router.addGeneralHandler(v1) + router.addAgentHandler(v1) + router.addHostHandler(v1) } - v1 := router.Router.Group("/v1") + // Middleware to recover from panics + router.Router.Use(recover.New()) - router.addGeneralHandler(v1) - router.addAgentHandler(v1) - router.addHostHandler(v1) + // Add 404 handler + router.Router.Use(func(c *fiber.Ctx) error { + return c.Status(fiber.StatusNotFound).Render("404", fiber.Map{}) + }) return router } + +// ListenAndServeTLS starts the Fiber server using TLS (HTTPS) +func ListenAndServeTLS(router *fiber.App, certFile, keyFile, addr string) error { + // Start HTTPS server using the provided certificate and key files + return router.ListenTLS(addr, certFile, keyFile) +} diff --git a/structs/structs.go b/structs/structs.go index ea6d28f..a4d4350 100644 --- a/structs/structs.go +++ b/structs/structs.go @@ -30,3 +30,10 @@ type Agent struct { Host_ID int Agent_ID int } + +type User struct { + Username string + Password string + UserID string + APIToken []string +} diff --git a/templates/404.html b/templates/404.html new file mode 100644 index 0000000..8ff6f44 --- /dev/null +++ b/templates/404.html @@ -0,0 +1,202 @@ + + + +
+ + +Read the PackageLock Docs! 🚀
+