From 7f7fd9395c199d5323ce7a8eb442647444336b1d Mon Sep 17 00:00:00 2001 From: GnomeZworc Date: Thu, 14 Mar 2024 14:01:58 +0100 Subject: [PATCH 01/14] v1.0.0: import: import code from accounts Signed-off-by: GnomeZworc --- cmd/login.go | 21 ++++++++++++ cmd/main.go | 64 ++++++++++++++++++++++++++++++++++++ go.mod | 22 +++++++++++++ go.sum | 39 ++++++++++++++++++++++ internal/createLogin.go | 70 +++++++++++++++++++++++++++++++++++++++ internal/struct.go | 13 ++++++++ lib/authMiddleware.go | 73 +++++++++++++++++++++++++++++++++++++++++ lib/initBiscuit.go | 67 +++++++++++++++++++++++++++++++++++++ 8 files changed, 369 insertions(+) create mode 100644 cmd/login.go create mode 100644 cmd/main.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 internal/createLogin.go create mode 100644 internal/struct.go create mode 100644 lib/authMiddleware.go create mode 100644 lib/initBiscuit.go diff --git a/cmd/login.go b/cmd/login.go new file mode 100644 index 0000000..d288c4f --- /dev/null +++ b/cmd/login.go @@ -0,0 +1,21 @@ +package main + +import ( + "net/http" + + "github.com/labstack/echo/v4" + logins "gitlab.g3e.fr/h6n/users/internal" +) + +func login(c echo.Context) error { + var request logins.RequestLogin + if err := c.Bind(&request); err != nil { + return c.JSON(http.StatusBadRequest, err) + } + + if response, err := logins.CreateLogin(db, request); err != nil { + return c.JSON(http.StatusBadRequest, "Not a valide user username or password") + } else { + return c.JSON(http.StatusOK, response) + } +} diff --git a/cmd/main.go b/cmd/main.go new file mode 100644 index 0000000..7c639bc --- /dev/null +++ b/cmd/main.go @@ -0,0 +1,64 @@ +package main + +import ( + "fmt" + "net/http" + + "github.com/labstack/echo/v4" + "github.com/labstack/echo/v4/middleware" + "gitlab.g3e.fr/h6n/users/lib" + + "database/sql" + + _ "github.com/lib/pq" +) + +var db *sql.DB = nil + +func logout(c echo.Context) error { + return c.NoContent(http.StatusNoContent) +} + +func isLoggedIn(c echo.Context) error { + return c.NoContent(http.StatusNoContent) +} + +func init_database() { + var err error = nil + + connStr := "postgres://acc:totor@postgres:5432/accounts?sslmode=disable" + + db, err = sql.Open("postgres", connStr) + if err != nil { + fmt.Println(err) + } +} + +func skip_auth(c echo.Context) bool { + if c.Request().Method == "POST" && c.Path() == "/" { + return true + } + return false +} + +func main() { + init_database() + if err := lib.InitLoginBiscuit(); err != nil { + return + } + e := echo.New() + + // Middleware + e.Use(middleware.Logger()) + e.Use(middleware.Recover()) + e.Use(middleware.CORS()) + e.Use(lib.AuthMiddleware(skip_auth)) + + // Routes + e.GET("/", isLoggedIn) + e.POST("/", login) + e.DELETE("/", logout) + + // Start server + e.Logger.Fatal(e.Start(":1222")) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..2eff39b --- /dev/null +++ b/go.mod @@ -0,0 +1,22 @@ +module gitlab.g3e.fr/h6n/users + +go 1.21.0 + +require ( + github.com/alecthomas/participle/v2 v2.0.0 // indirect + github.com/biscuit-auth/biscuit-go/v2 v2.2.0 // indirect + github.com/golang-jwt/jwt v3.2.2+incompatible // indirect + github.com/labstack/echo/v4 v4.11.4 // indirect + github.com/labstack/gommon v0.4.2 // indirect + github.com/lib/pq v1.10.9 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasttemplate v1.2.2 // indirect + golang.org/x/crypto v0.17.0 // indirect + golang.org/x/net v0.19.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/time v0.5.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..0b19315 --- /dev/null +++ b/go.sum @@ -0,0 +1,39 @@ +github.com/alecthomas/participle/v2 v2.0.0 h1:Fgrq+MbuSsJwIkw3fEj9h75vDP0Er5JzepJ0/HNHv0g= +github.com/alecthomas/participle/v2 v2.0.0/go.mod h1:rAKZdJldHu8084ojcWevWAL8KmEU+AT+Olodb+WoN2Y= +github.com/biscuit-auth/biscuit-go/v2 v2.2.0 h1:1zBfZ0ZCbxJbhtAhou6Fa07lBlJ+wcphBEPV/sENBvY= +github.com/biscuit-auth/biscuit-go/v2 v2.2.0/go.mod h1:c7AsMdr816vPd/4Psb3z6Xv2EKciKxSEayI8ueBaJio= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/labstack/echo/v4 v4.11.4 h1:vDZmA+qNeh1pd/cCkEicDMrjtrnMGQ1QFI9gWN1zGq8= +github.com/labstack/echo/v4 v4.11.4/go.mod h1:noh7EvLwqDsmh/X/HWKPUl1AjzJrhyptRyEbQJfxen8= +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/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +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.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +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/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= +github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= diff --git a/internal/createLogin.go b/internal/createLogin.go new file mode 100644 index 0000000..75efd85 --- /dev/null +++ b/internal/createLogin.go @@ -0,0 +1,70 @@ +package logins + +import ( + "database/sql" + "encoding/base64" + "encoding/hex" + "errors" + "time" + + "github.com/biscuit-auth/biscuit-go/v2" + "github.com/biscuit-auth/biscuit-go/v2/parser" + "gitlab.g3e.fr/h6n/users/lib" + "golang.org/x/crypto/bcrypt" +) + +func CheckPasswordHash(password, hash string) bool { + err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) + return err == nil +} + +func CreateLogin(db *sql.DB, request RequestLogin) (ResponseLogin, error) { + type ( + User struct { + Username string + EncryptedPassword string + } + ) + var user User + var response ResponseLogin + + if err := db.QueryRow("SELECT username, password FROM users WHERE email = $1", request.Username).Scan(&user.Username, &user.EncryptedPassword); err != nil { + return response, err + } + if !CheckPasswordHash(request.Password, user.EncryptedPassword) { + return response, errors.ErrUnsupported + } + now := time.Now() + ValidateTime := 14 + expire := now.AddDate(0, 0, ValidateTime) + + user_id := string(user.Username) + + auth := `user("` + user_id + `"); + check if time($time), $time <= ` + expire.Format("2006-01-02T15:04:05Z") + `; + ` + + authority, err := parser.FromStringBlockWithParams(auth, map[string]biscuit.Term{"read": biscuit.String("read"), "write": biscuit.String("write")}) + + if err != nil { + return response, err + } + + builder := biscuit.NewBuilder(lib.PrivateKey) + builder.AddBlock(authority) + + b, err := builder.Build() + if err != nil { + return response, err + } + + token, err := b.Serialize() + if err != nil { + return response, err + } + + response.Token = base64.URLEncoding.EncodeToString(token) + response.PublicKey = hex.EncodeToString(lib.PublicKey) + + return response, nil +} diff --git a/internal/struct.go b/internal/struct.go new file mode 100644 index 0000000..751ee07 --- /dev/null +++ b/internal/struct.go @@ -0,0 +1,13 @@ +package logins + +type ( + RequestLogin struct { + Username string `json:"username"` + Password string `json:"password"` + } + + ResponseLogin struct { + Token string `json:"token"` + PublicKey string `json:"publickey"` + } +) diff --git a/lib/authMiddleware.go b/lib/authMiddleware.go new file mode 100644 index 0000000..fd8e92b --- /dev/null +++ b/lib/authMiddleware.go @@ -0,0 +1,73 @@ +package lib + +import ( + "encoding/base64" + "fmt" + "net/http" + "strings" + "time" + + "github.com/biscuit-auth/biscuit-go/v2" + "github.com/biscuit-auth/biscuit-go/v2/parser" + "github.com/labstack/echo/v4" +) + +func queryUser(authorizer biscuit.Authorizer) (biscuit.FactSet, error) { + rule, err := parser.FromStringRule(`data($name) <- user($name)`) + if err != nil { + return nil, fmt.Errorf("failed to parse check: %v", err) + } + + return authorizer.Query(rule) +} + +func AuthMiddleware(skipper_auth func(echo.Context) bool) echo.MiddlewareFunc { + return func(next echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + if skipper_auth(c) { + return next(c) + } + tokens := strings.Split(c.Request().Header.Get("Authorization"), " ") + + if len(tokens) != 2 { + return c.String(http.StatusUnauthorized, "Header d'authentification manquant") + } + + c.Set("token", tokens[1]) + byteToken, _ := base64.URLEncoding.DecodeString(tokens[1]) + b, err := biscuit.Unmarshal(byteToken) + + if err != nil { + return c.JSON(http.StatusUnauthorized, err) + } + + authorizer, err := b.Authorizer(PublicKey) + + if err != nil { + return c.JSON(http.StatusUnauthorized, err) + } + + now := time.Now() + authorizerContents, err := parser.FromStringAuthorizerWithParams(` + time(`+now.Format("2006-01-02T15:04:05Z")+`); + allow if time($time), $time <= `+now.Format("2006-01-02T15:04:05Z")+`; + `, map[string]biscuit.Term{}) + if err != nil { + return c.JSON(http.StatusUnauthorized, err) + } + authorizer.AddAuthorizer(authorizerContents) + + if err := authorizer.Authorize(); err != nil { + return c.JSON(http.StatusUnauthorized, err) + } + + fact, err := queryUser(authorizer) + if err != nil { + return c.JSON(http.StatusUnauthorized, err) + } + c.Set("username", strings.Split(fact[0].IDs[0].String(), "\"")[1]) + + return next(c) + } + } +} diff --git a/lib/initBiscuit.go b/lib/initBiscuit.go new file mode 100644 index 0000000..d350696 --- /dev/null +++ b/lib/initBiscuit.go @@ -0,0 +1,67 @@ +package lib + +import ( + "crypto/ed25519" + "crypto/rand" + "io/ioutil" + "os" + "time" +) + +var PrivateKey ed25519.PrivateKey +var PublicKey ed25519.PublicKey +var filePrivateKey string = "/keys/privatekey.pem" +var filePublicKey string = "/keys/publickey.pem" + +func InitLoginBiscuit() error { + + if _, err := os.Stat(filePrivateKey); os.IsNotExist(err) { + rng := rand.Reader + PublicKey, PrivateKey, _ = ed25519.GenerateKey(rng) + if err := ioutil.WriteFile(filePrivateKey, PrivateKey, 0600); err != nil { + return err + } + if err := ioutil.WriteFile(filePublicKey, PublicKey, 0600); err != nil { + return err + } + } else { + var err error = nil + PrivateKey, err = ioutil.ReadFile(filePrivateKey) + if err != nil { + return err + } + PublicKey, err = ioutil.ReadFile(filePublicKey) + if err != nil { + return err + } + } + return nil +} + +func InitGlobalBiscuit() error { + for { + time.Sleep(1 * time.Second) + _, err := os.Stat(filePublicKey) + if err == nil { + break + } + } + for { + time.Sleep(1 * time.Second) + _, err := os.Stat(filePrivateKey) + if err == nil { + break + } + } + var err error = nil + PrivateKey, err = ioutil.ReadFile(filePrivateKey) + if err != nil { + return err + } + PublicKey, err = ioutil.ReadFile(filePublicKey) + if err != nil { + return err + } + + return nil +} From 360c46d4e7521fb1e910a26ba461478f40d8b7a6 Mon Sep 17 00:00:00 2001 From: GnomeZworc Date: Thu, 14 Mar 2024 14:03:14 +0100 Subject: [PATCH 02/14] v1.0.0: git: add gitignore Signed-off-by: GnomeZworc --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2db878e --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# build directory +build/ \ No newline at end of file From 1d75617c468796c6038c34cd476a19934629c1eb Mon Sep 17 00:00:00 2001 From: GnomeZworc Date: Thu, 14 Mar 2024 15:38:52 +0100 Subject: [PATCH 03/14] v1.0.0: error: add error print for main biscuit init Signed-off-by: GnomeZworc --- cmd/main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/main.go b/cmd/main.go index 7c639bc..cf8cc47 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -44,6 +44,7 @@ func skip_auth(c echo.Context) bool { func main() { init_database() if err := lib.InitLoginBiscuit(); err != nil { + fmt.Println("error : ", err) return } e := echo.New() From 2e2279f3c893fa4152d751cc3367826c7e4dc673 Mon Sep 17 00:00:00 2001 From: GnomeZworc Date: Thu, 14 Mar 2024 15:40:01 +0100 Subject: [PATCH 04/14] v1.0.0: docker: add docker file Signed-off-by: GnomeZworc --- Dockerfile | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a41f9ef --- /dev/null +++ b/Dockerfile @@ -0,0 +1,24 @@ +FROM golang:1.21-alpine AS develop + +# Changement du répertoire de travail +WORKDIR /app + +# pre-copy/cache go.mod for pre-downloading dependencies and only redownloading them in subsequent builds if they change +COPY go.mod go.sum ./ +RUN go mod download && go mod verify + +COPY . . + +CMD ["sh", "-c", "echo 'run application' && go run ./cmd/"] + +FROM develop AS build + +RUN CGO_ENABLED=0 go build -o ./build/app ./cmd/ + +FROM scratch AS release + +COPY --from=build /app/build/app /exec + +EXPOSE 1222 + +ENTRYPOINT ["/exec"] \ No newline at end of file From 45d671ec9798575645743016e2bb26a6efbdd9a9 Mon Sep 17 00:00:00 2001 From: GnomeZworc Date: Thu, 14 Mar 2024 15:53:41 +0100 Subject: [PATCH 05/14] v1.0.0: docker: add docker compose element Signed-off-by: GnomeZworc --- .gitignore | 6 +++++- README.md | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 2db878e..778b09e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ # build directory -build/ \ No newline at end of file +build/ + +# docker dev build +docker/ +docker-compose.yml diff --git a/README.md b/README.md index ba445fa..638245c 100644 --- a/README.md +++ b/README.md @@ -13,4 +13,37 @@ v0.0.0: version ## Developpement - Golang -- Docker \ No newline at end of file +- Docker + +### with docker compose + +```bash +cat < docker-compose.yml +version: '3.1' + +services: + postgres: + image: postgres:15.2-alpine3.17 + restart: unless-stopped + environment: + POSTGRES_USER: 'acc' + POSTGRES_PASSWORD: 'totor' + POSTGRES_DB: 'accounts' + healthcheck: + test: ["CMD-SHELL", "pg_isready"] + interval: 10s + timeout: 5s + retries: 5 + users: + build: + context: . + target: develop + ports: + - 127.0.0.1:2300:1222 + volumes: + - ./docker/keys:/keys + depends_on: + postgres: + condition: service_healthy +ENDFILE +``` \ No newline at end of file From 6aa8360920d2942995c3f15f93d8e84fddf9e4dc Mon Sep 17 00:00:00 2001 From: GnomeZworc Date: Thu, 14 Mar 2024 17:22:59 +0100 Subject: [PATCH 06/14] v1.0.0: ci: init ci Signed-off-by: GnomeZworc --- .gitlab-ci.yml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..c0cf90f --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,36 @@ +variables: + IMAGE_VERSION: $CI_COMMIT_SHORT_SHA + +default: + image: debian:11 + + + services: + - name: docker:24.0.7-dind + alias: docker + + +stages: + - build + - test + - release + - release-latest + +before_script: + - id + - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY + - docker login -u gnomezworc -p $DOCKERHUB_TOKEN + +build: + stage: build + image: docker:23.0.3-cli + artifacts: + paths: + - $IMAGE_TYPE-$IMAGE_VERSION-release.tar.gz + variables: + DOCKER_TLS_VERIFY: 1 + DOCKER_CERT_PATH: /certs/client + DOCKER_PATH: '.' + script: + - docker build --pull -t $CI_REGISTRY_IMAGE:$IMAGE_VERSION-release --target release $DOCKER_PATH + - docker save $CI_REGISTRY_IMAGE:$IMAGE_VERSION-release | gzip > $IMAGE_TYPE-$IMAGE_VERSION-release.tar.gz \ No newline at end of file From 0eb8c1d907eeb6a7f5eff8f15aa7dacd59c21f10 Mon Sep 17 00:00:00 2001 From: GnomeZworc Date: Thu, 14 Mar 2024 18:16:33 +0100 Subject: [PATCH 07/14] v1.0.0: test: add first test Signed-off-by: GnomeZworc --- cmd/001_basic_test.go | 9 +++++++++ cmd/skipCi_test.go | 12 ++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 cmd/001_basic_test.go create mode 100644 cmd/skipCi_test.go diff --git a/cmd/001_basic_test.go b/cmd/001_basic_test.go new file mode 100644 index 0000000..7396a90 --- /dev/null +++ b/cmd/001_basic_test.go @@ -0,0 +1,9 @@ +package main_test + +import ( + "testing" +) + +func TestBasic(t *testing.T) { + skipCI(t, "TestBasic") +} diff --git a/cmd/skipCi_test.go b/cmd/skipCi_test.go new file mode 100644 index 0000000..3a80710 --- /dev/null +++ b/cmd/skipCi_test.go @@ -0,0 +1,12 @@ +package main_test + +import ( + "os" + "testing" +) + +func skipCI(t *testing.T, test string) { + if os.Getenv(test) != "" { + t.Skipf("Skipping testing %v\n", test) + } +} From 024a9feda25df7c51379e5992b99f7dd99f666a5 Mon Sep 17 00:00:00 2001 From: GnomeZworc Date: Thu, 14 Mar 2024 18:36:45 +0100 Subject: [PATCH 08/14] v1.0.0: ci: add test Signed-off-by: GnomeZworc --- .gitlab-ci.yml | 23 ++++++++++++++++++++++- config/test.src | 0 scripts/prepar_test.sh | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 config/test.src create mode 100644 scripts/prepar_test.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c0cf90f..7721cf6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,6 @@ variables: IMAGE_VERSION: $CI_COMMIT_SHORT_SHA + IMAGE_TYPE: users default: image: debian:11 @@ -33,4 +34,24 @@ build: DOCKER_PATH: '.' script: - docker build --pull -t $CI_REGISTRY_IMAGE:$IMAGE_VERSION-release --target release $DOCKER_PATH - - docker save $CI_REGISTRY_IMAGE:$IMAGE_VERSION-release | gzip > $IMAGE_TYPE-$IMAGE_VERSION-release.tar.gz \ No newline at end of file + - docker save $CI_REGISTRY_IMAGE:$IMAGE_VERSION-release | gzip > $IMAGE_TYPE-$IMAGE_VERSION-release.tar.gz + +integration_test: + stage: test + image: golang:1.21-alpine + variables: + DOCKER_TLS_VERIFY: 1 + DOCKER_CERT_PATH: /certs/client + DOCKER_HOST: tcp://docker:2376/ + DOCKER_URL: docker + before_script: + - apk update && apk add --no-cache docker-cli + - apk add bash + - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY + - docker login -u gnomezworc -p $DOCKERHUB_TOKEN + script: + - bash -ex ./scripts/prepar_test.sh + - . ./config/test.src + - go test -v ./cmd/ + needs: + - build \ No newline at end of file diff --git a/config/test.src b/config/test.src new file mode 100644 index 0000000..e69de29 diff --git a/scripts/prepar_test.sh b/scripts/prepar_test.sh new file mode 100644 index 0000000..2db967f --- /dev/null +++ b/scripts/prepar_test.sh @@ -0,0 +1,42 @@ +#!/bin/bash + + +cat <> /etc/apk/repositories +http://ftp.halifax.rwth-aachen.de/alpine/v3.16/main +http://ftp.halifax.rwth-aachen.de/alpine/v3.16/community +ENDFILE +apk update +apk add docker docker-cli-compose +docker version +docker compose version +docker load --input "$IMAGE_TYPE-$IMAGE_VERSION-release.tar.gz" +docker tag $CI_REGISTRY_IMAGE:$IMAGE_VERSION-release $IMAGE_TYPE:latest + +cat < docker-compose.yml +version: '3.1' + +services: + postgres: + image: postgres:15.2-alpine3.17 + restart: unless-stopped + environment: + POSTGRES_USER: 'acc' + POSTGRES_PASSWORD: 'totor' + POSTGRES_DB: 'accounts' + healthcheck: + test: ["CMD-SHELL", "pg_isready"] + interval: 10s + timeout: 5s + retries: 5 + users: + image: $IMAGE_TYPE + volumes: + - ./docker/keys:/keys + depends_on: + postgres: + condition: service_healthy +ENDFILE + +docker compose pull --quiet --ignore-pull-failures +docker images +docker compose up -d \ No newline at end of file From 92c62aa993d4a39c2a2c6db5c3aa38936e018c32 Mon Sep 17 00:00:00 2001 From: GnomeZworc Date: Thu, 14 Mar 2024 19:05:22 +0100 Subject: [PATCH 09/14] v1.0.0: ci: add latest push Signed-off-by: GnomeZworc --- .gitlab-ci.yml | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7721cf6..f5873d3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,7 @@ variables: IMAGE_VERSION: $CI_COMMIT_SHORT_SHA IMAGE_TYPE: users + LATEST_NAME: main default: image: debian:11 @@ -54,4 +55,44 @@ integration_test: - . ./config/test.src - go test -v ./cmd/ needs: - - build \ No newline at end of file + - build + +release-latest: + stage: release-latest + image: docker:23.0.3-cli + variables: + DOCKER_TLS_VERIFY: 1 + DOCKER_CERT_PATH: /certs/client + script: + - docker load --input $IMAGE_TYPE-$IMAGE_VERSION-release.tar.gz + - docker images + - docker tag $CI_REGISTRY_IMAGE:$IMAGE_VERSION-release $CI_REGISTRY_IMAGE:latest + - docker push $CI_REGISTRY_IMAGE:latest + dependencies: + - build + rules: + - if: $CI_COMMIT_BRANCH == $LATEST_NAME + needs: + - build + - integration_test + +release-front: + stage: release + image: docker:23.0.3-cli + variables: + IMAGE_TYPE: front + DOCKER_TLS_VERIFY: 1 + DOCKER_CERT_PATH: /certs/client + script: + - docker load --input $IMAGE_TYPE-$IMAGE_VERSION-release.tar.gz + - docker images + - docker tag $CI_REGISTRY_IMAGE:$IMAGE_VERSION-release $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG + - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG + dependencies: + - build + only: + refs: + - tags + needs: + - build + - integration_test \ No newline at end of file From 1e31a6f80ead4a3c4caaf504361933e04bb745ff Mon Sep 17 00:00:00 2001 From: GnomeZworc Date: Thu, 14 Mar 2024 19:23:08 +0100 Subject: [PATCH 10/14] v1.0.0: test: add lint Signed-off-by: GnomeZworc --- .gitlab-ci.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f5873d3..cb4b3a2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,6 +2,7 @@ variables: IMAGE_VERSION: $CI_COMMIT_SHORT_SHA IMAGE_TYPE: users LATEST_NAME: main + GOLANGCI_LINT_VERSION: 'v1.56.2' default: image: debian:11 @@ -13,6 +14,7 @@ default: stages: + - check - build - test - release @@ -23,6 +25,18 @@ before_script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker login -u gnomezworc -p $DOCKERHUB_TOKEN +lint: + image: golangci/golangci-lint:$GOLANGCI_LINT_VERSION + stage: check + before_script: [] + script: + - golangci-lint run --issues-exit-code 1 --print-issued-lines=false --out-format code-climate:gl-code-quality-report.json,line-number + artifacts: + reports: + codequality: gl-code-quality-report.json + paths: + - gl-code-quality-report.json + build: stage: build image: docker:23.0.3-cli @@ -36,6 +50,8 @@ build: script: - docker build --pull -t $CI_REGISTRY_IMAGE:$IMAGE_VERSION-release --target release $DOCKER_PATH - docker save $CI_REGISTRY_IMAGE:$IMAGE_VERSION-release | gzip > $IMAGE_TYPE-$IMAGE_VERSION-release.tar.gz + needs: + - lint integration_test: stage: test From 51e4cb90271227c2d844db8afacaf649d448660e Mon Sep 17 00:00:00 2001 From: GnomeZworc Date: Thu, 14 Mar 2024 19:48:28 +0100 Subject: [PATCH 11/14] v1.0.0: lint: fix lint error Signed-off-by: GnomeZworc --- cmd/main.go | 2 +- internal/createLogin.go | 4 +++- lib/initBiscuit.go | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index cf8cc47..e799c8e 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -24,7 +24,7 @@ func isLoggedIn(c echo.Context) error { } func init_database() { - var err error = nil + var err error connStr := "postgres://acc:totor@postgres:5432/accounts?sslmode=disable" diff --git a/internal/createLogin.go b/internal/createLogin.go index 75efd85..140b350 100644 --- a/internal/createLogin.go +++ b/internal/createLogin.go @@ -51,7 +51,9 @@ func CreateLogin(db *sql.DB, request RequestLogin) (ResponseLogin, error) { } builder := biscuit.NewBuilder(lib.PrivateKey) - builder.AddBlock(authority) + if err = builder.AddBlock(authority); err != nil { + return response, err + } b, err := builder.Build() if err != nil { diff --git a/lib/initBiscuit.go b/lib/initBiscuit.go index d350696..71785d5 100644 --- a/lib/initBiscuit.go +++ b/lib/initBiscuit.go @@ -25,7 +25,7 @@ func InitLoginBiscuit() error { return err } } else { - var err error = nil + var err error PrivateKey, err = ioutil.ReadFile(filePrivateKey) if err != nil { return err @@ -53,7 +53,7 @@ func InitGlobalBiscuit() error { break } } - var err error = nil + var err error PrivateKey, err = ioutil.ReadFile(filePrivateKey) if err != nil { return err From 7588000af4ea789bec6abc6d25a648c84116544d Mon Sep 17 00:00:00 2001 From: GnomeZworc Date: Thu, 14 Mar 2024 19:54:15 +0100 Subject: [PATCH 12/14] v1.0.0: lint: fix deprecated library Signed-off-by: GnomeZworc --- lib/initBiscuit.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/initBiscuit.go b/lib/initBiscuit.go index 71785d5..5f63585 100644 --- a/lib/initBiscuit.go +++ b/lib/initBiscuit.go @@ -3,6 +3,7 @@ package lib import ( "crypto/ed25519" "crypto/rand" + "io" "io/ioutil" "os" "time" @@ -53,12 +54,21 @@ func InitGlobalBiscuit() error { break } } - var err error - PrivateKey, err = ioutil.ReadFile(filePrivateKey) + file, err := os.Open(filePrivateKey) if err != nil { return err } - PublicKey, err = ioutil.ReadFile(filePublicKey) + defer file.Close() + PrivateKey, err = io.ReadAll(file) + if err != nil { + return err + } + file, err = os.Open(filePublicKey) + if err != nil { + return err + } + defer file.Close() + PublicKey, err = io.ReadAll(file) if err != nil { return err } From 15b9d0c2e3e4d0592ca453e93bbbe79b3f8b1b91 Mon Sep 17 00:00:00 2001 From: GnomeZworc Date: Fri, 15 Mar 2024 18:07:19 +0100 Subject: [PATCH 13/14] v1.0.0: lint: remove io/utils Signed-off-by: GnomeZworc --- lib/initBiscuit.go | 75 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 22 deletions(-) diff --git a/lib/initBiscuit.go b/lib/initBiscuit.go index 5f63585..0853db2 100644 --- a/lib/initBiscuit.go +++ b/lib/initBiscuit.go @@ -4,7 +4,6 @@ import ( "crypto/ed25519" "crypto/rand" "io" - "io/ioutil" "os" "time" ) @@ -19,21 +18,51 @@ func InitLoginBiscuit() error { if _, err := os.Stat(filePrivateKey); os.IsNotExist(err) { rng := rand.Reader PublicKey, PrivateKey, _ = ed25519.GenerateKey(rng) - if err := ioutil.WriteFile(filePrivateKey, PrivateKey, 0600); err != nil { + + if file, err := os.Create(filePrivateKey); err != nil { return err + } else { + defer file.Close() + + if _, err = io.WriteString(file, string(PrivateKey)); err != nil { + return err + } + if err := file.Chmod(0600); err != nil { + return err + } } - if err := ioutil.WriteFile(filePublicKey, PublicKey, 0600); err != nil { + if file, err := os.Create(filePublicKey); err != nil { return err + } else { + defer file.Close() + + if _, err = io.WriteString(file, string(PublicKey)); err != nil { + return err + } + if err := file.Chmod(0600); err != nil { + return err + } } } else { - var err error - PrivateKey, err = ioutil.ReadFile(filePrivateKey) - if err != nil { + if file, err := os.Open(filePrivateKey); err != nil { return err + } else { + defer file.Close() + + PrivateKey, err = io.ReadAll(file) + if err != nil { + return err + } } - PublicKey, err = ioutil.ReadFile(filePublicKey) - if err != nil { + if file, err := os.Open(filePublicKey); err != nil { return err + } else { + defer file.Close() + + PublicKey, err = io.ReadAll(file) + if err != nil { + return err + } } } return nil @@ -54,23 +83,25 @@ func InitGlobalBiscuit() error { break } } - file, err := os.Open(filePrivateKey) - if err != nil { + if file, err := os.Open(filePrivateKey); err != nil { return err + } else { + defer file.Close() + + PrivateKey, err = io.ReadAll(file) + if err != nil { + return err + } } - defer file.Close() - PrivateKey, err = io.ReadAll(file) - if err != nil { - return err - } - file, err = os.Open(filePublicKey) - if err != nil { - return err - } - defer file.Close() - PublicKey, err = io.ReadAll(file) - if err != nil { + if file, err := os.Open(filePublicKey); err != nil { return err + } else { + defer file.Close() + + PublicKey, err = io.ReadAll(file) + if err != nil { + return err + } } return nil From df7a17cf9d1f817b31e3671a0f4d71d7199feaae Mon Sep 17 00:00:00 2001 From: GnomeZworc Date: Fri, 15 Mar 2024 18:08:25 +0100 Subject: [PATCH 14/14] v1.0.0: dev: add dev and test conseil Signed-off-by: GnomeZworc --- README.md | 5 +++++ config/db.sql | 7 +++++++ 2 files changed, 12 insertions(+) create mode 100644 config/db.sql diff --git a/README.md b/README.md index 638245c..f3552f3 100644 --- a/README.md +++ b/README.md @@ -41,9 +41,14 @@ services: ports: - 127.0.0.1:2300:1222 volumes: + - .:/app:ro - ./docker/keys:/keys depends_on: postgres: condition: service_healthy ENDFILE + +cat config/db.sql| docker compose exec -T postgres psql -U acc accounts + +curl -s http://127.0.0.1:2300/ -H "Content-Type: application/json" -d "{\"username\":\"root@root.fr\",\"password\":\"root\"}" | jq -r '.token' ``` \ No newline at end of file diff --git a/config/db.sql b/config/db.sql new file mode 100644 index 0000000..591d4d8 --- /dev/null +++ b/config/db.sql @@ -0,0 +1,7 @@ +CREATE TABLE users ( + username TEXT PRIMARY KEY, + email TEXT UNIQUE NOT NULL, + password TEXT NOT NULL +); + +INSERT INTO users(username, email, password) VALUES('0000000023', 'root@root.fr', '$2a$14$FU8FKR7pUq4akLThraD9kOu0zY0BuUFASo0xakgWEWbYF2gz20DuG'); \ No newline at end of file