diff --git a/assignment-2/Dockerfile b/assignment-2/Dockerfile new file mode 100644 index 0000000..4c63ebc --- /dev/null +++ b/assignment-2/Dockerfile @@ -0,0 +1,13 @@ +FROM golang:1.20 AS builder +WORKDIR /app +COPY . . + +FROM alpine:3.13 +WORKDIR /app +COPY --from=builder /app/deploy/hacktiv-assignment-2 . +COPY --from=builder /app/template /app/template/. +RUN ls +EXPOSE 8080 + +ENV APP_NAME=hacktiv-assignment-2 +CMD ["./hacktiv-assignment-2"] diff --git a/assignment-2/Makefile b/assignment-2/Makefile new file mode 100644 index 0000000..ad1430d --- /dev/null +++ b/assignment-2/Makefile @@ -0,0 +1,34 @@ +.PHONY: migration +migration: + migrate create -ext sql -dir db/migrations/$(module) $(name) + +.PHONY: migrate +migrate: + migrate -path db/migrations/$(module) -database "postgres://postgresuser:postgrespassword@127.0.0.1:5432/postgres?sslmode=disable&search_path=public" -verbose up + +.PHONY: rollback +rollback: + migrate -path db/migrations/$(module) -database "postgres://postgresuser:postgrespassword@127.0.0.1:5432/postgres?sslmode=disable&search_path=public" -verbose down 1 + +.PHONY: rollback-all +rollback-all: + migrate -path db/migrations/$(module) -database "postgres://postgresuser:postgrespassword@127.0.0.1:5432/postgres?sslmode=disable&search_path=public" -verbose down -all + +.PHONY: force-migrate +force-migrate: + migrate -path db/migrations/$(module) -database "postgres://postgresuser:postgrespassword@127.0.0.1:5432/postgres?sslmode=disable&search_path=public" -verbose force $(version) + +.PHONY: compile-server +compile-server: + GO111MODULE=on CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-extldflags "-static"' -o deploy/hacktiv-assignment-2 main.go + +.PHONY: docker-build-server +docker-build-server: + docker build --no-cache -t hacktiv-assignment-2:latest -f Dockerfile . + +.PHONY: run +run: + docker-compose up + +.PHONY: compile-build-run +compile-build-run: compile-server docker-build-server run \ No newline at end of file diff --git a/assignment-2/README.md b/assignment-2/README.md new file mode 100644 index 0000000..960ff51 --- /dev/null +++ b/assignment-2/README.md @@ -0,0 +1,12 @@ +# Assignment 2 Hacktiv +Simple login-logout page with gorilla session stored on postgres db + +# Dependencies +- [Docker](https://docs.docker.com/engine/install/ubuntu/) +- [Docker-compose](https://docs.docker.com/compose/install/) + +# How To Run +1. Compile server to generate executable file `make compile-server` +2. Build docker image `make docker-build-server` +3. Run docker image `make run` +4. Alternatively, you can use this shortcut to automatically run 3 above steps `make compile-build-run` diff --git a/assignment-2/db/migrations/users/20221114032114_create_table_user.down.sql b/assignment-2/db/migrations/users/20221114032114_create_table_user.down.sql new file mode 100644 index 0000000..1dac82b --- /dev/null +++ b/assignment-2/db/migrations/users/20221114032114_create_table_user.down.sql @@ -0,0 +1,5 @@ +BEGIN; + +DROP TABLE users; + +COMMIT; \ No newline at end of file diff --git a/assignment-2/db/migrations/users/20221114032114_create_table_user.up.sql b/assignment-2/db/migrations/users/20221114032114_create_table_user.up.sql new file mode 100644 index 0000000..a08b7e3 --- /dev/null +++ b/assignment-2/db/migrations/users/20221114032114_create_table_user.up.sql @@ -0,0 +1,11 @@ +BEGIN; + +CREATE TABLE users ( + id serial not null, + username varchar(50) unique not null, + first_name varchar(200) not null, + last_name varchar(200) not null, + password varchar(120) not null +); + +COMMIT; \ No newline at end of file diff --git a/assignment-2/deploy/hacktiv-assignment-2 b/assignment-2/deploy/hacktiv-assignment-2 new file mode 100755 index 0000000..830f74f Binary files /dev/null and b/assignment-2/deploy/hacktiv-assignment-2 differ diff --git a/assignment-2/docker-compose.yaml b/assignment-2/docker-compose.yaml new file mode 100644 index 0000000..28d99db --- /dev/null +++ b/assignment-2/docker-compose.yaml @@ -0,0 +1,24 @@ +version: '3' + +services: + postgres: + image: postgres:13.2-alpine + environment: + - POSTGRES_USER=postgresuser + - POSTGRES_PASSWORD=postgrespassword + - POSTGRES_DB=postgres + ports: + - 5432:5432 + networks: + - assignment-2 + server: + image: hacktiv-assignment-2:latest + ports: + - 8080:8080 + depends_on: + - postgres + networks: + - assignment-2 + +networks: + assignment-2: \ No newline at end of file diff --git a/assignment-2/driver/pgx.go b/assignment-2/driver/pgx.go new file mode 100644 index 0000000..7d958a8 --- /dev/null +++ b/assignment-2/driver/pgx.go @@ -0,0 +1,11 @@ +package driver + +import ( + "context" + + "github.com/jackc/pgx/v4" +) + +func NewPostgresConn(ctx context.Context) (*pgx.Conn, error) { + return pgx.Connect(ctx, POSTGRES_URL) +} diff --git a/assignment-2/driver/renderer.go b/assignment-2/driver/renderer.go new file mode 100644 index 0000000..5e790d8 --- /dev/null +++ b/assignment-2/driver/renderer.go @@ -0,0 +1,41 @@ +package driver + +import ( + "html/template" + "io" + + "github.com/labstack/echo" +) + +type Renderer struct { + template *template.Template + debug bool + location string +} + +func NewRenderer(location string, debug bool) *Renderer { + tpl := new(Renderer) + tpl.location = location + tpl.debug = debug + + tpl.ReloadTemplates() + + return tpl +} + +func (t *Renderer) ReloadTemplates() { + t.template = template.Must(template.ParseGlob(t.location)) +} + +func (t *Renderer) Render( + w io.Writer, + name string, + data interface{}, + c echo.Context, +) error { + if t.debug { + t.ReloadTemplates() + } + + return t.template.ExecuteTemplate(w, name, data) +} diff --git a/assignment-2/driver/session_store.go b/assignment-2/driver/session_store.go new file mode 100644 index 0000000..3f09b62 --- /dev/null +++ b/assignment-2/driver/session_store.go @@ -0,0 +1,36 @@ +package driver + +import ( + "log" + + "github.com/antonlindstrom/pgstore" + "github.com/gorilla/sessions" +) + +const ( + SESSION_ID = "test-id" + POSTGRES_URL = "postgres://postgresuser:postgrespassword@postgres:5432/postgres?sslmode=disable" +) + +var ( + SESSION_AUTH_KEY = []byte("my-auth-key-very-secret") + SESSION_ENCRYPTION_KEY = []byte("my-encryption-key-very-secret123") +) + +func NewPostgresStore() *pgstore.PGStore { + store, err := pgstore.NewPGStore(POSTGRES_URL, SESSION_AUTH_KEY, SESSION_ENCRYPTION_KEY) + if err != nil { + log.Fatalln("ERROR", err) + } + + return store +} + +func NewCookieStore() *sessions.CookieStore { + store := sessions.NewCookieStore(SESSION_AUTH_KEY, SESSION_ENCRYPTION_KEY) + store.Options.Path = "/" + store.Options.MaxAge = 86400 * 7 + store.Options.HttpOnly = true + + return store +} diff --git a/assignment-2/entity/user.go b/assignment-2/entity/user.go new file mode 100644 index 0000000..4213de3 --- /dev/null +++ b/assignment-2/entity/user.go @@ -0,0 +1,9 @@ +package entity + +type User struct { + ID int `json:"id"` + Username string `json:"username"` + FirstName string `json:"first_name"` + LastName string `json:"last_name"` + Password string `json:"password"` +} diff --git a/assignment-2/handler/common.go b/assignment-2/handler/common.go new file mode 100644 index 0000000..ce37eb2 --- /dev/null +++ b/assignment-2/handler/common.go @@ -0,0 +1,21 @@ +package handler + +import ( + "net/http" + + "github.com/antonlindstrom/pgstore" + "github.com/ibrahimker/golang-intermediate/assignment-2/driver" + "github.com/labstack/echo" +) + +func storeSessionHelper(c echo.Context, pgs *pgstore.PGStore, username string) error { + session, err := pgs.Get(c.Request(), driver.SESSION_ID) + if err != nil { + return c.String(http.StatusInternalServerError, err.Error()) + } + session.Values["username"] = username + if err = session.Save(c.Request(), c.Response()); err != nil { + return c.String(http.StatusInternalServerError, err.Error()) + } + return nil +} diff --git a/assignment-2/handler/login_handler.go b/assignment-2/handler/login_handler.go new file mode 100644 index 0000000..ecb80e1 --- /dev/null +++ b/assignment-2/handler/login_handler.go @@ -0,0 +1,87 @@ +package handler + +import ( + "net/http" + + "github.com/antonlindstrom/pgstore" + "github.com/gorilla/sessions" + "github.com/ibrahimker/golang-intermediate/assignment-2/driver" + "github.com/ibrahimker/golang-intermediate/assignment-2/entity" + "github.com/ibrahimker/golang-intermediate/assignment-2/repository" + "github.com/labstack/echo" + log "github.com/sirupsen/logrus" +) + +type HTMLTemplate struct { + User entity.User + Err string +} + +type Login struct { + cs *sessions.CookieStore + pgStore *pgstore.PGStore + ur *repository.User +} + +func NewLoginHandler(cs *sessions.CookieStore, pgs *pgstore.PGStore, ur *repository.User) *Login { + return &Login{ + cs: cs, + pgStore: pgs, + ur: ur, + } +} + +func (l *Login) LoginHandler(c echo.Context) error { + log.Info("Start Login Handler") + // authenticate in db + user, err := l.ur.GetByUsernamePassword(c.Request().Context(), c.FormValue("username"), c.FormValue("password")) + if err != nil { + log.Warn(err) + return c.Render(http.StatusOK, "login.html", HTMLTemplate{ + User: entity.User{}, + Err: "Error when login", + }) + } + log.Info("Successfully authenticate user", user) + + // store username in session + if err = storeSessionHelper(c, l.pgStore, user.Username); err != nil { + log.Warn("error when store session") + return c.Render(http.StatusOK, "login.html", HTMLTemplate{ + User: entity.User{}, + Err: "Error when store session", + }) + } + + return c.Redirect(http.StatusTemporaryRedirect, "/home") +} + +func (l *Login) HomeHandler(c echo.Context) error { + log.Info("Start Home Handler") + + session, err := l.pgStore.Get(c.Request(), driver.SESSION_ID) + if err != nil { + log.WithError(err).Warn("error when retrieve session") + return c.Redirect(http.StatusTemporaryRedirect, "/login") + } + + if len(session.Values) == 0 { + log.Info("no session values available") + return c.Redirect(http.StatusTemporaryRedirect, "/login") + } + + log.Info("Session exists, render html") + return c.Render(http.StatusOK, "home.html", HTMLTemplate{ + User: entity.User{Username: session.Values["username"].(string)}, + Err: "", + }) +} + +func (l *Login) LogoutHandler(c echo.Context) error { + log.Info("Start Logout Handler") + session, _ := l.pgStore.Get(c.Request(), driver.SESSION_ID) + session.Options.MaxAge = -1 + session.Save(c.Request(), c.Response()) + + return c.Redirect(http.StatusTemporaryRedirect, "/home") +} diff --git a/assignment-2/handler/register_handler.go b/assignment-2/handler/register_handler.go new file mode 100644 index 0000000..43a3eb0 --- /dev/null +++ b/assignment-2/handler/register_handler.go @@ -0,0 +1,51 @@ +package handler + +import ( + "net/http" + + "github.com/antonlindstrom/pgstore" + "github.com/gorilla/sessions" + "github.com/ibrahimker/golang-intermediate/assignment-2/entity" + "github.com/ibrahimker/golang-intermediate/assignment-2/repository" + "github.com/labstack/echo" + log "github.com/sirupsen/logrus" +) + +type Register struct { + cs *sessions.CookieStore + pgs *pgstore.PGStore + ur *repository.User +} + +func NewRegisterHandler(cs *sessions.CookieStore, pgs *pgstore.PGStore, ur *repository.User) *Register { + return &Register{ + cs: cs, + pgs: pgs, + ur: ur, + } +} + +func (r *Register) RegisterHandler(c echo.Context) error { + data := "Hello from /html" + u := &entity.User{ + Username: c.FormValue("username"), + FirstName: c.FormValue("firstname"), + LastName: c.FormValue("lastname"), + Password: c.FormValue("password"), + } + log.Info("user", u) + if u.Username == "" || u.Password == "" { + log.Warn("username password cannot be empty") + return c.Redirect(http.StatusTemporaryRedirect, "/home") + } + if err := r.ur.Insert(c.Request().Context(), u); err != nil { + return c.Render(http.StatusOK, "login.html", data) + } + + // store username in session + if err := storeSessionHelper(c, r.pgs, u.Username); err != nil { + return c.String(http.StatusInternalServerError, err.Error()) + } + + return c.Redirect(http.StatusTemporaryRedirect, "/home") +} diff --git a/assignment-2/main.go b/assignment-2/main.go new file mode 100644 index 0000000..a1afdce --- /dev/null +++ b/assignment-2/main.go @@ -0,0 +1,44 @@ +package main + +import ( + "context" + "log" + "net/http" + + "github.com/ibrahimker/golang-intermediate/assignment-2/driver" + "github.com/ibrahimker/golang-intermediate/assignment-2/handler" + "github.com/ibrahimker/golang-intermediate/assignment-2/repository" + "github.com/labstack/echo" +) + +func main() { + e := echo.New() + e.Renderer = driver.NewRenderer("template/*.html", true) + ctx := context.Background() + store := driver.NewPostgresStore() + pgPool, err := driver.NewPostgresConn(ctx) + if err != nil { + log.Fatal(err) + } + + userRepo := repository.NewUser(pgPool) + + loginHandler := handler.NewLoginHandler(nil, store, userRepo) + registerHandler := handler.NewRegisterHandler(nil, store, userRepo) + + e.GET("/", func(ctx echo.Context) error { + return ctx.Redirect(http.StatusTemporaryRedirect, "/home") + }) + + e.GET("/login", loginHandler.LoginHandler) + e.POST("/login", loginHandler.LoginHandler) + + e.GET("/home", loginHandler.HomeHandler) + e.POST("/home", loginHandler.HomeHandler) + + e.POST("/register", registerHandler.RegisterHandler) + + e.POST("/logout", loginHandler.LogoutHandler) + + e.Start(":8080") +} diff --git a/assignment-2/repository/common.go b/assignment-2/repository/common.go new file mode 100644 index 0000000..26484ce --- /dev/null +++ b/assignment-2/repository/common.go @@ -0,0 +1,18 @@ +package repository + +import ( + "context" + + "github.com/jackc/pgconn" + "github.com/jackc/pgx/v4" +) + +// PgxPoolIface defines a little interface for pgxpool functionality. +// Since in the real implementation we can use pgxpool.Pool, +// this interface exists mostly for testing purpose. +type PgxPoolIface interface { + Exec(ctx context.Context, sql string, arguments ...interface{}) (pgconn.CommandTag, error) + Query(ctx context.Context, sql string, args ...interface{}) (pgx.Rows, error) + QueryRow(ctx context.Context, sql string, args ...interface{}) pgx.Row + Ping(ctx context.Context) error +} diff --git a/assignment-2/repository/users.go b/assignment-2/repository/users.go new file mode 100644 index 0000000..3d60d7a --- /dev/null +++ b/assignment-2/repository/users.go @@ -0,0 +1,59 @@ +package repository + +import ( + "context" + + "github.com/ibrahimker/golang-intermediate/assignment-2/entity" + log "github.com/sirupsen/logrus" +) + +// User is responsible to connect user entity with users table in PostgreSQL. +type User struct { + pool PgxPoolIface +} + +// NewUser creates an instance of User. +func NewUser(pool PgxPoolIface) *User { + return &User{pool: pool} +} + +// Insert inserts the user into the users table and return the user id. +func (u *User) Insert(ctx context.Context, user *entity.User) error { + query := "INSERT INTO " + + "users (username, first_name, last_name, password) " + + "VALUES ($1, $2, $3, $4) " + + "RETURNING id" + + row := u.pool.QueryRow(ctx, query, + user.Username, + user.FirstName, + user.LastName, + user.Password, + ) + + if err := row.Scan(&user.ID); err != nil { + log.Warn("Error when scan rows") + return err + } + + return nil +} + +// GetByUsernamePassword gets a user from PostgreSQL. +// If there isn't any data, it returns error. +func (u *User) GetByUsernamePassword(ctx context.Context, username, password string) (*entity.User, error) { + log.Info("Start GetByUsernamePassword", username, password) + query := "SELECT id,username,first_name,last_name,password " + + "FROM users WHERE username = $1 AND password = $2" + + row := u.pool.QueryRow(ctx, query, username, password) + + user := entity.User{} + err := row.Scan(&user.ID, &user.Username, &user.FirstName, &user.LastName, &user.Password) + if err != nil { + log.WithError(err).Warn("Error when scan rows") + return nil, err + } + log.Infof("Success retrieve user %+v\n", user) + return &user, nil +} diff --git a/assignment-2/template/home.html b/assignment-2/template/home.html new file mode 100644 index 0000000..6cc869a --- /dev/null +++ b/assignment-2/template/home.html @@ -0,0 +1,18 @@ + + + Assignment 2 - Home + + + + +
+
+

Halo, {{.User.Username}}

+

...

+
+ +
+
+
+ + \ No newline at end of file diff --git a/assignment-2/template/login.html b/assignment-2/template/login.html new file mode 100644 index 0000000..7c68a81 --- /dev/null +++ b/assignment-2/template/login.html @@ -0,0 +1,51 @@ + + + Assignment 2 - Login + + + + +
+ +
+

Register Form

+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+
+
+
+

Login Form

+
+ + +
+
+ + +
+
+ +
+
+
+ + \ No newline at end of file diff --git a/final-project/index.html b/final-project/index.html new file mode 100644 index 0000000..ffd825b --- /dev/null +++ b/final-project/index.html @@ -0,0 +1,125 @@ + + + + WebSocket + + + + +
+ +
+
+
+ +
+ + +
+
+ + + + \ No newline at end of file diff --git a/final-project/main.go b/final-project/main.go new file mode 100644 index 0000000..438524b --- /dev/null +++ b/final-project/main.go @@ -0,0 +1,115 @@ +package main + +import ( + "fmt" + "io/ioutil" + "log" + "net/http" + "strings" + + "github.com/gorilla/websocket" +) + +type M map[string]interface{} + +const MESSAGE_NEW_USER = "New User" +const MESSAGE_CHAT = "Chat" +const MESSAGE_LEAVE = "Leave" + +var connections = make([]*WebSocketConnection, 0) + +type SocketPayload struct { + Message string +} + +type SocketResponse struct { + From string + Type string + Message string +} + +type WebSocketConnection struct { + *websocket.Conn + Username string + Age string +} + +func main() { + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + content, err := ioutil.ReadFile("index.html") + if err != nil { + http.Error(w, "Could not open requested file", http.StatusInternalServerError) + return + } + + fmt.Fprintf(w, "%s", content) + }) + + http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) { + currentGorillaConn, err := websocket.Upgrade(w, r, w.Header(), 1024, 1024) + if err != nil { + http.Error(w, "Could not open websocket connection", http.StatusBadRequest) + } + + username := r.URL.Query().Get("username") + age := r.URL.Query().Get("age") + currentConn := WebSocketConnection{Conn: currentGorillaConn, Username: username, Age: age} + connections = append(connections, ¤tConn) + + go handleIO(¤tConn, connections) + }) + + fmt.Println("Server starting at :8080") + http.ListenAndServe(":8080", nil) +} + +func handleIO(currentConn *WebSocketConnection, connections []*WebSocketConnection) { + defer func() { + if r := recover(); r != nil { + log.Println("ERROR", fmt.Sprintf("%v", r)) + } + }() + + broadcastMessage(currentConn, MESSAGE_NEW_USER, "") + + for { + payload := SocketPayload{} + err := currentConn.ReadJSON(&payload) + if err != nil { + if strings.Contains(err.Error(), "websocket: close") { + broadcastMessage(currentConn, MESSAGE_LEAVE, "") + ejectConnection(currentConn) + return + } + + log.Println("ERROR", err.Error()) + continue + } + + broadcastMessage(currentConn, MESSAGE_CHAT, payload.Message) + } +} + +func ejectConnection(currentConn *WebSocketConnection) { + var newConn []*WebSocketConnection + for _, conn := range connections { + if conn != currentConn { + newConn = append(newConn, conn) + } + } + connections = newConn +} + +func broadcastMessage(currentConn *WebSocketConnection, kind, message string) { + for _, eachConn := range connections { + if eachConn == currentConn { + continue + } + + eachConn.WriteJSON(SocketResponse{ + From: fmt.Sprintf(currentConn.Username + " Age: " + currentConn.Age), + Type: kind, + Message: message, + }) + } +} diff --git a/go.mod b/go.mod index dd19778..ecc4607 100644 --- a/go.mod +++ b/go.mod @@ -1,33 +1,85 @@ module github.com/ibrahimker/golang-intermediate -go 1.18 +go 1.20 require ( + github.com/antonlindstrom/pgstore v0.0.0-20220421113606-e3a6e3fed12a + github.com/crewjam/saml v0.4.12 + github.com/go-ldap/ldap v3.0.3+incompatible + github.com/go-playground/validator v9.31.0+incompatible github.com/golang/protobuf v1.5.2 github.com/gorilla/mux v1.8.0 + github.com/gorilla/sessions v1.2.1 + github.com/gorilla/websocket v1.5.0 + github.com/grpc-ecosystem/grpc-gateway/v2 v2.13.0 + github.com/jackc/pgconn v1.13.0 + github.com/jackc/pgx/v4 v4.17.2 + github.com/labstack/echo v3.3.10+incompatible + github.com/pkg/sftp v1.13.5 + github.com/sirupsen/logrus v1.9.0 + github.com/spf13/viper v1.15.0 + github.com/stretchr/testify v1.8.1 github.com/swaggo/http-swagger v1.3.3 github.com/swaggo/swag v1.8.7 - google.golang.org/grpc v1.50.1 + golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa + google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef + google.golang.org/grpc v1.52.0 google.golang.org/protobuf v1.28.1 ) require ( github.com/KyleBanks/depth v1.2.1 // indirect - github.com/go-ldap/ldap v3.0.3+incompatible // indirect + github.com/beevik/etree v1.1.0 // indirect + github.com/crewjam/httperr v0.2.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonreference v0.20.0 // indirect - github.com/go-openapi/spec v0.20.7 // indirect - github.com/go-openapi/swag v0.22.3 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.13.0 // indirect + github.com/go-openapi/spec v0.20.6 // indirect + github.com/go-openapi/swag v0.19.15 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.0 // indirect + github.com/golang-jwt/jwt/v4 v4.4.3 // indirect + github.com/gorilla/securecookie v1.1.1 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/jackc/chunkreader/v2 v2.0.1 // indirect + github.com/jackc/pgio v1.0.0 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgproto3/v2 v2.3.1 // indirect + github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect + github.com/jackc/pgtype v1.12.0 // indirect + github.com/jonboulle/clockwork v0.2.2 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/sirupsen/logrus v1.9.0 // indirect - github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a // indirect - golang.org/x/net v0.1.0 // indirect - golang.org/x/sys v0.1.0 // indirect - golang.org/x/text v0.4.0 // indirect - golang.org/x/tools v0.2.0 // indirect - google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c // indirect + github.com/kr/fs v0.1.0 // indirect + github.com/labstack/gommon v0.4.0 // indirect + github.com/leodido/go-urn v1.2.1 // indirect + github.com/lib/pq v1.10.5 // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/mailru/easyjson v0.7.6 // indirect + github.com/mattermost/xml-roundtrip-validator v0.1.0 // indirect + github.com/mattn/go-colorable v0.1.12 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/pelletier/go-toml/v2 v2.0.6 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/russellhaering/goxmldsig v1.2.0 // indirect + github.com/spf13/afero v1.9.3 // indirect + github.com/spf13/cast v1.5.0 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/subosito/gotenv v1.4.2 // indirect + github.com/swaggo/files v0.0.0-20220610200504-28940afbdbfe // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasttemplate v1.2.2 // indirect + golang.org/x/net v0.4.0 // indirect + golang.org/x/sys v0.3.0 // indirect + golang.org/x/text v0.5.0 // indirect + golang.org/x/tools v0.1.12 // indirect gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect + gopkg.in/go-playground/assert.v1 v1.2.1 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 0bf8aab..d120b97 100644 --- a/go.sum +++ b/go.sum @@ -1,83 +1,704 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/antonlindstrom/pgstore v0.0.0-20220421113606-e3a6e3fed12a h1:dIdcLbck6W67B5JFMewU5Dba1yKZA3MsT67i4No/zh0= +github.com/antonlindstrom/pgstore v0.0.0-20220421113606-e3a6e3fed12a/go.mod h1:Sdr/tmSOLEnncCuXS5TwZRxuk7deH1WXVY8cve3eVBM= +github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs= +github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/crewjam/httperr v0.2.0 h1:b2BfXR8U3AlIHwNeFFvZ+BV1LFvKLlzMjzaTnZMybNo= +github.com/crewjam/httperr v0.2.0/go.mod h1:Jlz+Sg/XqBQhyMjdDiC+GNNRzZTD7x39Gu3pglZ5oH4= +github.com/crewjam/saml v0.4.12 h1:66Gsd+9iA/8ZGl8W+7DDTlJGWe3RneBFo+Uu/gvlB0w= +github.com/crewjam/saml v0.4.12/go.mod h1:igEejV+fihTIlHXYP8zOec3V5A8y3lws5bQBFsTm4gA= 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/dchest/uniuri v1.2.0/go.mod h1:fSzm4SLHzNZvWLvWJew423PhAzkpNQYq+uNLq4kxhkY= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-ldap/ldap v3.0.3+incompatible h1:HTeSZO8hWMS1Rgb2Ziku6b8a7qRIZZMHjsvuZyatzwk= github.com/go-ldap/ldap v3.0.3+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= -github.com/go-openapi/spec v0.20.7 h1:1Rlu/ZrOCCob0n+JKKJAWhNWMPW8bOZRg8FJaY+0SKI= -github.com/go-openapi/spec v0.20.7/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= +github.com/go-openapi/spec v0.20.6 h1:ich1RQ3WDbfoeTqTAb+5EIxNmpKVJZWBNah9RAT0jIQ= +github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM= github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +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.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= +github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-playground/validator v9.31.0+incompatible h1:UA72EPEogEnq76ehGdEDp4Mit+3FDh548oRqwVgNsHA= +github.com/go-playground/validator v9.31.0+incompatible/go.mod h1:yrEkQXlcI+PugkyDjY2bRrL/UBU4f3rvrgkN3V8JEig= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= +github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/golang-jwt/jwt/v4 v4.4.3 h1:Hxl6lhQFj4AnOX6MLrsCb/+7tCj7DxP7VA+2rDIq5AU= +github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= 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/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/grpc-gateway/v2 v2.13.0 h1:fi9bGIUJOGzzrHBbP8NWbTfNC5fKO6X7kFw40TOqGB8= github.com/grpc-ecosystem/grpc-gateway/v2 v2.13.0/go.mod h1:uY3Aurq+SxwQCpdX91xZ9CgxIMT1EsYtcidljXufYIY= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +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/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= +github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= +github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= +github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= +github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= +github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= +github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= +github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= +github.com/jackc/pgconn v1.13.0 h1:3L1XMNV2Zvca/8BYhzcRFS70Lr0WlDg16Di6SFGAbys= +github.com/jackc/pgconn v1.13.0/go.mod h1:AnowpAqO4CMIIJNZl2VJp+KrkAZciAkhEl0W0JIobpI= +github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= +github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= +github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= +github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= +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/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= +github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.3.1 h1:nwj7qwf0S+Q7ISFfBndqeLwSwxs+4DPsbRFjECT1Y4Y= +github.com/jackc/pgproto3/v2 v2.3.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= +github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= +github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= +github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= +github.com/jackc/pgtype v1.12.0 h1:Dlq8Qvcch7kiehm8wPGIW0W3KsCCHJnRacKW0UM8n5w= +github.com/jackc/pgtype v1.12.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= +github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= +github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= +github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= +github.com/jackc/pgx/v4 v4.17.2 h1:0Ut0rpeKwvIVbMQ1KbMBU4h6wxehBI535LK6Flheh8E= +github.com/jackc/pgx/v4 v4.17.2/go.mod h1:lcxIZN44yMIrWI78a5CpucdD14hX0SBDbNRvjDBItsw= +github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= +github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= 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/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg= +github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s= +github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= +github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= +github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= +github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.5 h1:J+gdV2cUmX7ZqL2B0lFcW0m+egaHC2V3lpO8nWxyYiQ= +github.com/lib/pq v1.10.5/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattermost/xml-roundtrip-validator v0.1.0 h1:RXbVD2UAl7A7nOTR4u7E3ILa4IbtvKBHw64LDsmu9hU= +github.com/mattermost/xml-roundtrip-validator v0.1.0/go.mod h1:qccnGMcpgwcNaBnxqpJpWWUiPNr5H3O8eDgGV9gT5To= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +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/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= +github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= +github.com/pkg/sftp v1.13.5 h1:a3RLUqkyjYRtBTZJZ1VRrKbN3zhuPLlUc3sphVz81go= +github.com/pkg/sftp v1.13.5/go.mod h1:wHDZ0IZX6JcBYRK1TH9bcVq8G7TLpVHYIGJRFnmPfxg= 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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +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/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= +github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= +github.com/russellhaering/goxmldsig v1.2.0 h1:Y6GTTc9Un5hCxSzVz4UIWQ/zuVwDvzJk80guqzwx6Vg= +github.com/russellhaering/goxmldsig v1.2.0/go.mod h1:gM4MDENBQf7M+V824SGfyIUVFWydB7n0KkEubVJl+Tw= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk= +github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= +github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= +github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= +github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +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/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= -github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a h1:kAe4YSu0O0UFn1DowNo2MY5p6xzqtJ/wQ7LZynSvGaY= -github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w= +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 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= +github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/swaggo/files v0.0.0-20220610200504-28940afbdbfe h1:K8pHPVoTgxFJt1lXuIzzOX7zZhZFldJQK/CgKx9BFIc= +github.com/swaggo/files v0.0.0-20220610200504-28940afbdbfe/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w= github.com/swaggo/http-swagger v1.3.3 h1:Hu5Z0L9ssyBLofaama21iYaF2VbWyA8jdohaaCGpHsc= github.com/swaggo/http-swagger v1.3.3/go.mod h1:sE+4PjD89IxMPm77FnkDz0sdO+p5lbXzrVWT6OTVVGo= github.com/swaggo/swag v1.8.7 h1:2K9ivTD3teEO+2fXV6zrZKDqk5IuU2aJtBDo8U7omWU= github.com/swaggo/swag v1.8.7/go.mod h1:ezQVUUhly8dludpVk+/PuwJWvLLanB13ygV5Pr9enSk= -golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= +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.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= +github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +github.com/zenazn/goji v1.0.1/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +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-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220128200615-198e4374d7ed/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/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-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/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-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= -golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +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-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= -google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c h1:QgY/XxIAIeccR+Ca/rDdKubLIU9rcJ3xfy1DC/Wd2Oo= -google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= -google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY= -google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef h1:uQ2vjV/sHTsWSqdKeLqmwitzgvjMl7o4IdtHwUDXSJY= +google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.52.0 h1:kd48UiU7EHsV4rnLyOJRuP/Il/UHE7gdDAQ+SZI7nZk= +google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= @@ -88,10 +709,30 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= +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.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/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= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/session-10/config.go b/session-10/config.go new file mode 100644 index 0000000..800d4ca --- /dev/null +++ b/session-10/config.go @@ -0,0 +1,12 @@ +package main + +import "fmt" + +var ( + samlCertificatePath = "./myservice.cert" + samlPrivateKeyPath = "./myservice.key" + samlIDPMetadata = "https://samltest.id/saml/idp" + + webserverPort = 9000 + webserverRootURL = fmt.Sprintf("http://localhost:%d", webserverPort) +) diff --git a/session-10/main.go b/session-10/main.go new file mode 100644 index 0000000..a1a5736 --- /dev/null +++ b/session-10/main.go @@ -0,0 +1,36 @@ +package main + +import ( + "fmt" + "log" + "net/http" + + "github.com/crewjam/saml/samlsp" +) + +func landingHandler(w http.ResponseWriter, r *http.Request) { + name := samlsp.AttributeFromContext(r.Context(), "displayName") + w.Write([]byte(fmt.Sprintf("Welcome, %s!", name))) +} +func helloHandler(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("Hello!")) +} + +func main() { + sp, err := newSamlMiddleware() + if err != nil { + log.Fatal(err.Error()) + } + http.Handle("/saml/", sp) + + http.Handle("/index", sp.RequireAccount( + http.HandlerFunc(landingHandler), + )) + http.Handle("/hello", sp.RequireAccount( + http.HandlerFunc(helloHandler), + )) + + portString := fmt.Sprintf(":%d", webserverPort) + fmt.Println("server started at", portString) + http.ListenAndServe(portString, nil) +} diff --git a/session-10/metadata b/session-10/metadata new file mode 100644 index 0000000..64a0cd2 --- /dev/null +++ b/session-10/metadata @@ -0,0 +1,19 @@ + + + + + + MIIDCTCCAfGgAwIBAgIUfYfQd8O9qWWnhhBO7yFjWlm6sbIwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIyMTEzMDAyMTkzNFoXDTIzMTEzMDAyMTkzNFowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxWk3irjmg2J5GatxVCBbq8CI5WThzUqncV22mANlxGJin89zS9Anf2E6yzlE+li1EL8bv9ndrRTkXN+HTImhU+62/83OXAz5PJAxq22eMVMmAcRxVxq7zKqcEwk5uPe2wdKclhIfE1/hca3042LR1p+l3/PMv7IaUUlIiqLQxMDeb+nhB3z7afwUQhL4NQt21fz1G5NPrzIXzj+baCdyrvtugO10haWOvtu5YsKj/bAYi90lsgawgmonf3/sfNwUMWiD0esL1Mq2YclDgC72j84Yb8zhGxaQJkbeq1BSofsax2GiIPMjEGMVefZas6zaa7knTwa71vL6lu/tPq7cgwIDAQABo1MwUTAdBgNVHQ4EFgQUP0j91usGpXqmwgbKRd1Knd1PuRowHwYDVR0jBBgwFoAUP0j91usGpXqmwgbKRd1Knd1PuRowDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAYpx/dwBWbOo1TbnXv1xgQrYD4HVoqsKd5kWNDZB79BtOQ4XdHUWBAySvDrYTC83UO7vWtAJRW3UI6CrbgOpzSJFcRiwv8/Noj7N8WXiq+UuVtaUdMpHNStt57NfgGlJ8Bf9EnhFhRcfgkTuIIwPb4W/4+6yF0AS6b+VUERYPSVig2ZveUsldt2ZHjOGmi55NUTGdtVX3H4QFfMcWNGaESGdohqn2t3AfEk83boiSBXBtC9gv9hRBZa9i89Qd0H12T0cx0UJYQYRni2Zy3rfT0AKtQtY0fIkigt24c8hDUePKBezx3Qilq3q+bnON6MUdi80+GvJutl1GtevGrGXlvw== + + + + + + + + + + + + + \ No newline at end of file diff --git a/session-10/myservice.cert b/session-10/myservice.cert new file mode 100644 index 0000000..724a95f --- /dev/null +++ b/session-10/myservice.cert @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDCTCCAfGgAwIBAgIUfYfQd8O9qWWnhhBO7yFjWlm6sbIwDQYJKoZIhvcNAQEL +BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIyMTEzMDAyMTkzNFoXDTIzMTEz +MDAyMTkzNFowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAxWk3irjmg2J5GatxVCBbq8CI5WThzUqncV22mANlxGJi +n89zS9Anf2E6yzlE+li1EL8bv9ndrRTkXN+HTImhU+62/83OXAz5PJAxq22eMVMm +AcRxVxq7zKqcEwk5uPe2wdKclhIfE1/hca3042LR1p+l3/PMv7IaUUlIiqLQxMDe +b+nhB3z7afwUQhL4NQt21fz1G5NPrzIXzj+baCdyrvtugO10haWOvtu5YsKj/bAY +i90lsgawgmonf3/sfNwUMWiD0esL1Mq2YclDgC72j84Yb8zhGxaQJkbeq1BSofsa +x2GiIPMjEGMVefZas6zaa7knTwa71vL6lu/tPq7cgwIDAQABo1MwUTAdBgNVHQ4E +FgQUP0j91usGpXqmwgbKRd1Knd1PuRowHwYDVR0jBBgwFoAUP0j91usGpXqmwgbK +Rd1Knd1PuRowDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAYpx/ +dwBWbOo1TbnXv1xgQrYD4HVoqsKd5kWNDZB79BtOQ4XdHUWBAySvDrYTC83UO7vW +tAJRW3UI6CrbgOpzSJFcRiwv8/Noj7N8WXiq+UuVtaUdMpHNStt57NfgGlJ8Bf9E +nhFhRcfgkTuIIwPb4W/4+6yF0AS6b+VUERYPSVig2ZveUsldt2ZHjOGmi55NUTGd +tVX3H4QFfMcWNGaESGdohqn2t3AfEk83boiSBXBtC9gv9hRBZa9i89Qd0H12T0cx +0UJYQYRni2Zy3rfT0AKtQtY0fIkigt24c8hDUePKBezx3Qilq3q+bnON6MUdi80+ +GvJutl1GtevGrGXlvw== +-----END CERTIFICATE----- diff --git a/session-10/myservice.key b/session-10/myservice.key new file mode 100644 index 0000000..b40ef89 --- /dev/null +++ b/session-10/myservice.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDFaTeKuOaDYnkZ +q3FUIFurwIjlZOHNSqdxXbaYA2XEYmKfz3NL0Cd/YTrLOUT6WLUQvxu/2d2tFORc +34dMiaFT7rb/zc5cDPk8kDGrbZ4xUyYBxHFXGrvMqpwTCTm497bB0pyWEh8TX+Fx +rfTjYtHWn6Xf88y/shpRSUiKotDEwN5v6eEHfPtp/BRCEvg1C3bV/PUbk0+vMhfO +P5toJ3Ku+26A7XSFpY6+27liwqP9sBiL3SWyBrCCaid/f+x83BQxaIPR6wvUyrZh +yUOALvaPzhhvzOEbFpAmRt6rUFKh+xrHYaIg8yMQYxV59lqzrNpruSdPBrvW8vqW +7+0+rtyDAgMBAAECggEAEfMiOLvdQd8HUd0z3clfbHuCNxF4MplyJi22N5Y/f57O +hudu/Vq87Kkjlmzrp7O/KvmlhUlDDcTTitpMTBpLj/0pqJLHC7mmQ+p8ibDa7HM6 +BnkdMSVeJBrzPAvfssDbXj5PPJoDN1jFf/eoR7CpkdFMXNOnL1r7Z565ONnbD7is +mVJf6VIlBf1hgbfohh/SJY+P9qJyK6ZxepZ6Z16fFGsq2njyWSzzOb02PfNrezr5 +RNWpeyZOOV55T8iEUX4Dm1g5c/2y1EN9plwLlk7dP+8yw0mE3DZrTIYrS68d95Pn +4K9YRheAcrNEEJ8gmAdSa0Ov5hVs6f9ONzzXyUbY4QKBgQD8W+xqHPu2MCsOpxNj +KiyWYZr3/Fs3XOML1SxTLRcPl7AigXhRRDZZy6RBeBLcA3TDMvF18gY9+5v1cITu +A0Je750HkFZa/N2Dn78qzjfcaJXoH6PB4u6pix+EYJ6Rti0leIp6/JNPxJGPgO8A +fZMwssA1yrhNUeTv7+BTHfx20wKBgQDIQlhmu60IN2+yFiXDcCfww1sts5YOsb1y +8oEWv0BltbiIdVlZo1Pz6/AGwKSiyffHST4+FdhvcoqMAZWPgiKeNwTjkPb91G7b +ICKsCJi8zyy7OcQouaBA3jHMvn9VUaAvn2GdkI7M+OrhRKFmBMkX4+2YTFu03tUR +M8DP3abVkQKBgQDvzF2rO51IMx9HDiYTDelOgLMkQE1hH0e0X7190BPgwjAhqctt +1Zab3zFW8MVjAXm7XrYpcHDUBznckS4PiVNRKPmbTWFxlmTbhTm/cDOOomcIKsCO +JZjJzKSHQtSK+4SM3a0hTs6gdtYmecsiOTFbjg+tTdOxzUbxZIxSDuVu9wKBgExQ +tD2aQcuCzMcSF5wODrp6yDF3YbUB2Q+ICNexVIouIT+ncMBvNJwdCqCYI2WCEDHa +4KRqUMvP26qVI/jHgAfJMczDPszmesR4z529vO8fCI3k6rMWYlK2GkZLRl0uORxM +4bdZEoJcTa5BKDynkDbRfobuenhH/uyKS20rq9txAoGBAOx23uUCsf10udtLNeQL +x1k3nKEBXQzHzO26AoD0J8dhf9ilnzqtOoAM8br2Z8dw8KUWEu8w7iNo9AiAMUp0 +Wb/MuGJh1Cqsd4bcVbmaIh2s3aN6rUc403NIUFcl2WC4TljYPewn5hdEe1BWjsoz +ocWQKoHw9qiqpjv0CbvLfnFT +-----END PRIVATE KEY----- diff --git a/session-10/saml_middleware.go b/session-10/saml_middleware.go new file mode 100644 index 0000000..1e85822 --- /dev/null +++ b/session-10/saml_middleware.go @@ -0,0 +1,50 @@ +package main + +import ( + "context" + "crypto/rsa" + "crypto/tls" + "crypto/x509" + "net/http" + "net/url" + + "github.com/crewjam/saml/samlsp" +) + +func newSamlMiddleware() (*samlsp.Middleware, error) { + keyPair, err := tls.LoadX509KeyPair(samlCertificatePath, samlPrivateKeyPath) + if err != nil { + return nil, err + } + keyPair.Leaf, err = x509.ParseCertificate(keyPair.Certificate[0]) + if err != nil { + return nil, err + } + + idpMetadataURL, err := url.Parse(samlIDPMetadata) + if err != nil { + return nil, err + } + idpMetadata, err := samlsp.FetchMetadata(context.Background(), http.DefaultClient, + *idpMetadataURL) + if err != nil { + return nil, err + } + + rootURL, err := url.Parse(webserverRootURL) + if err != nil { + return nil, err + } + + sp, err := samlsp.New(samlsp.Options{ + URL: *rootURL, + Key: keyPair.PrivateKey.(*rsa.PrivateKey), + Certificate: keyPair.Leaf, + IDPMetadata: idpMetadata, + }) + if err != nil { + return nil, err + } + + return sp, nil +} diff --git a/session-11/main.go b/session-11/main.go new file mode 100644 index 0000000..382c771 --- /dev/null +++ b/session-11/main.go @@ -0,0 +1,28 @@ +package main + +import ( + "errors" + "fmt" +) + +func main() { + fmt.Println(LuasPersegi(4)) +} + +func LuasPersegi(sisi int) int { + return sisi * sisi +} + +func Register(username, password string) error { + if username == "" { + return errors.New("username tidak boleh kosong") + } + if password == "" { + return errors.New("password tidak boleh kosong") + } + + // ceritanya masukin ke db + + // kalo sukses return nil + return nil +} diff --git a/session-11/main_test.go b/session-11/main_test.go new file mode 100644 index 0000000..a8e06bc --- /dev/null +++ b/session-11/main_test.go @@ -0,0 +1,33 @@ +package main + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestLuasPersegi(t *testing.T) { + t.Run("case sisi 4", func(t *testing.T) { + luas := LuasPersegi(4) + require.Equal(t, 16, luas) + }) + t.Run("case sisi 6", func(t *testing.T) { + luas := LuasPersegi(6) + require.Equal(t, 36, luas) + }) +} + +func TestRegister(t *testing.T) { + t.Run("case username kosong", func(t *testing.T) { + err := Register("", "password") + require.Error(t, err) + }) + t.Run("case password kosong", func(t *testing.T) { + err := Register("username", "") + require.Error(t, err) + }) + t.Run("case sukses", func(t *testing.T) { + err := Register("username", "password") + require.NoError(t, err) + }) +} diff --git a/session-3/clientserver/Makefile b/session-3/clientserver/Makefile index 6dd183f..871b465 100644 --- a/session-3/clientserver/Makefile +++ b/session-3/clientserver/Makefile @@ -1,3 +1,3 @@ .PHONY: generate-proto generate-proto: - protoc --proto_path=common/model --go_out=plugins=grpc:common/model/. --go_opt=paths=source_relative common/model/*.proto \ No newline at end of file + protoc -I common/model/google/api --proto_path=common/model --go_out=plugins=grpc:common/model/. --go_opt=paths=source_relative common/model/*.proto \ No newline at end of file diff --git a/session-3/clientserver/common/model/user.pb.go b/session-3/clientserver/common/model/user.pb.go index 0fbcbca..91b43a7 100644 --- a/session-3/clientserver/common/model/user.pb.go +++ b/session-3/clientserver/common/model/user.pb.go @@ -220,8 +220,8 @@ var file_common_model_user_proto_rawDesc = []byte{ 0x6e, 0x33, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x22, 0x14, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x22, 0x09, 0x2f, 0x76, 0x31, 0x2f, - 0x75, 0x73, 0x65, 0x72, 0x73, 0x3a, 0x01, 0x2a, 0x12, 0x58, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, + 0x74, 0x79, 0x22, 0x14, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x3a, 0x01, 0x2a, 0x22, 0x09, 0x2f, + 0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x12, 0x58, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x25, 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x33, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, diff --git a/session-3/todo/buf.gen.yaml b/session-3/todo/buf.gen.yaml new file mode 100644 index 0000000..abced21 --- /dev/null +++ b/session-3/todo/buf.gen.yaml @@ -0,0 +1,16 @@ +version: v1 +plugins: + - name: go + out: . + opt: + - paths=source_relative + - name: go-grpc + out: . + opt: + - paths=source_relative + - name: grpc-gateway + out: . + opt: + - paths=source_relative + - name: openapiv2 + out: docs/openapiv2 \ No newline at end of file diff --git a/session-3/todo/buf.lock b/session-3/todo/buf.lock new file mode 100644 index 0000000..f5c25d7 --- /dev/null +++ b/session-3/todo/buf.lock @@ -0,0 +1,7 @@ +# Generated by buf. DO NOT EDIT. +version: v1 +deps: + - remote: buf.build + owner: googleapis + repository: googleapis + commit: 783e4b5374fa488ab068d08af9658438 diff --git a/session-3/todo/buf.yaml b/session-3/todo/buf.yaml new file mode 100644 index 0000000..8134aa3 --- /dev/null +++ b/session-3/todo/buf.yaml @@ -0,0 +1,4 @@ +version: v1 +name: buf.build/yourorg/myprotos +deps: + - buf.build/googleapis/googleapis \ No newline at end of file diff --git a/session-3/todo/common/model/todo.pb.go b/session-3/todo/common/model/todo.pb.go new file mode 100644 index 0000000..2c0bde8 --- /dev/null +++ b/session-3/todo/common/model/todo.pb.go @@ -0,0 +1,657 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc (unknown) +// source: common/model/todo.proto + +package model + +import ( + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Todo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *Todo) Reset() { + *x = Todo{} + if protoimpl.UnsafeEnabled { + mi := &file_common_model_todo_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Todo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Todo) ProtoMessage() {} + +func (x *Todo) ProtoReflect() protoreflect.Message { + mi := &file_common_model_todo_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Todo.ProtoReflect.Descriptor instead. +func (*Todo) Descriptor() ([]byte, []int) { + return file_common_model_todo_proto_rawDescGZIP(), []int{0} +} + +func (x *Todo) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Todo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type GetAllResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Data []*Todo `protobuf:"bytes,1,rep,name=data,proto3" json:"data,omitempty"` +} + +func (x *GetAllResponse) Reset() { + *x = GetAllResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_common_model_todo_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAllResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAllResponse) ProtoMessage() {} + +func (x *GetAllResponse) ProtoReflect() protoreflect.Message { + mi := &file_common_model_todo_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAllResponse.ProtoReflect.Descriptor instead. +func (*GetAllResponse) Descriptor() ([]byte, []int) { + return file_common_model_todo_proto_rawDescGZIP(), []int{1} +} + +func (x *GetAllResponse) GetData() []*Todo { + if x != nil { + return x.Data + } + return nil +} + +type GetAllRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Data []*Todo `protobuf:"bytes,1,rep,name=data,proto3" json:"data,omitempty"` +} + +func (x *GetAllRequest) Reset() { + *x = GetAllRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_common_model_todo_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAllRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAllRequest) ProtoMessage() {} + +func (x *GetAllRequest) ProtoReflect() protoreflect.Message { + mi := &file_common_model_todo_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAllRequest.ProtoReflect.Descriptor instead. +func (*GetAllRequest) Descriptor() ([]byte, []int) { + return file_common_model_todo_proto_rawDescGZIP(), []int{2} +} + +func (x *GetAllRequest) GetData() []*Todo { + if x != nil { + return x.Data + } + return nil +} + +type GetByIDRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *GetByIDRequest) Reset() { + *x = GetByIDRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_common_model_todo_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetByIDRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetByIDRequest) ProtoMessage() {} + +func (x *GetByIDRequest) ProtoReflect() protoreflect.Message { + mi := &file_common_model_todo_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetByIDRequest.ProtoReflect.Descriptor instead. +func (*GetByIDRequest) Descriptor() ([]byte, []int) { + return file_common_model_todo_proto_rawDescGZIP(), []int{3} +} + +func (x *GetByIDRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type GetByIDResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Data *Todo `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` +} + +func (x *GetByIDResponse) Reset() { + *x = GetByIDResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_common_model_todo_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetByIDResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetByIDResponse) ProtoMessage() {} + +func (x *GetByIDResponse) ProtoReflect() protoreflect.Message { + mi := &file_common_model_todo_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetByIDResponse.ProtoReflect.Descriptor instead. +func (*GetByIDResponse) Descriptor() ([]byte, []int) { + return file_common_model_todo_proto_rawDescGZIP(), []int{4} +} + +func (x *GetByIDResponse) GetData() *Todo { + if x != nil { + return x.Data + } + return nil +} + +type MutationResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Success string `protobuf:"bytes,1,opt,name=success,proto3" json:"success,omitempty"` +} + +func (x *MutationResponse) Reset() { + *x = MutationResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_common_model_todo_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MutationResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MutationResponse) ProtoMessage() {} + +func (x *MutationResponse) ProtoReflect() protoreflect.Message { + mi := &file_common_model_todo_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MutationResponse.ProtoReflect.Descriptor instead. +func (*MutationResponse) Descriptor() ([]byte, []int) { + return file_common_model_todo_proto_rawDescGZIP(), []int{5} +} + +func (x *MutationResponse) GetSuccess() string { + if x != nil { + return x.Success + } + return "" +} + +type UpdateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *UpdateRequest) Reset() { + *x = UpdateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_common_model_todo_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateRequest) ProtoMessage() {} + +func (x *UpdateRequest) ProtoReflect() protoreflect.Message { + mi := &file_common_model_todo_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateRequest.ProtoReflect.Descriptor instead. +func (*UpdateRequest) Descriptor() ([]byte, []int) { + return file_common_model_todo_proto_rawDescGZIP(), []int{6} +} + +func (x *UpdateRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type DeleteRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *DeleteRequest) Reset() { + *x = DeleteRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_common_model_todo_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteRequest) ProtoMessage() {} + +func (x *DeleteRequest) ProtoReflect() protoreflect.Message { + mi := &file_common_model_todo_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteRequest.ProtoReflect.Descriptor instead. +func (*DeleteRequest) Descriptor() ([]byte, []int) { + return file_common_model_todo_proto_rawDescGZIP(), []int{7} +} + +func (x *DeleteRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +var File_common_model_todo_proto protoreflect.FileDescriptor + +var file_common_model_todo_proto_rawDesc = []byte{ + 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2f, 0x74, + 0x6f, 0x64, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x73, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x33, 0x2e, 0x74, 0x6f, 0x64, 0x6f, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0x1c, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, + 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x2a, 0x0a, 0x04, 0x54, 0x6f, 0x64, + 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3f, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x33, + 0x2e, 0x74, 0x6f, 0x64, 0x6f, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x54, 0x6f, 0x64, 0x6f, + 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x3e, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x33, + 0x2e, 0x74, 0x6f, 0x64, 0x6f, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x54, 0x6f, 0x64, 0x6f, + 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x20, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x42, 0x79, 0x49, + 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x40, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x42, + 0x79, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x33, 0x2e, 0x74, 0x6f, 0x64, 0x6f, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, + 0x54, 0x6f, 0x64, 0x6f, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x2c, 0x0a, 0x10, 0x4d, 0x75, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, + 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x33, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x1f, 0x0a, + 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x32, 0x85, + 0x04, 0x0a, 0x0b, 0x54, 0x6f, 0x64, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x55, + 0x0a, 0x06, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x1a, 0x23, 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x33, 0x2e, 0x74, 0x6f, 0x64, 0x6f, + 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x0e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x08, 0x12, 0x06, 0x2f, + 0x74, 0x6f, 0x64, 0x6f, 0x73, 0x12, 0x69, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x42, 0x79, 0x49, 0x44, + 0x12, 0x23, 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x33, 0x2e, 0x74, 0x6f, 0x64, 0x6f, + 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x33, + 0x2e, 0x74, 0x6f, 0x64, 0x6f, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x47, 0x65, 0x74, 0x42, + 0x79, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x13, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x0d, 0x12, 0x0b, 0x2f, 0x74, 0x6f, 0x64, 0x6f, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, + 0x12, 0x5d, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x33, 0x2e, 0x74, 0x6f, 0x64, 0x6f, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, + 0x2e, 0x54, 0x6f, 0x64, 0x6f, 0x1a, 0x25, 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x33, + 0x2e, 0x74, 0x6f, 0x64, 0x6f, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x4d, 0x75, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x11, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x0b, 0x3a, 0x01, 0x2a, 0x22, 0x06, 0x2f, 0x74, 0x6f, 0x64, 0x6f, 0x73, 0x12, + 0x6b, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x22, 0x2e, 0x73, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x33, 0x2e, 0x74, 0x6f, 0x64, 0x6f, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x33, 0x2e, 0x74, 0x6f, 0x64, 0x6f, 0x2e, 0x6d, 0x6f, + 0x64, 0x65, 0x6c, 0x2e, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x3a, 0x01, 0x2a, 0x1a, + 0x0b, 0x2f, 0x74, 0x6f, 0x64, 0x6f, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x68, 0x0a, 0x06, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x22, 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x33, 0x2e, 0x74, 0x6f, 0x64, 0x6f, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x33, 0x2e, 0x74, 0x6f, 0x64, 0x6f, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, + 0x2e, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x13, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0d, 0x2a, 0x0b, 0x2f, 0x74, 0x6f, 0x64, 0x6f, + 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x62, 0x72, 0x61, 0x68, 0x69, 0x6d, 0x6b, 0x65, 0x72, 0x2f, + 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, + 0x61, 0x74, 0x65, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2d, 0x33, 0x2f, 0x74, 0x6f, + 0x64, 0x6f, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_common_model_todo_proto_rawDescOnce sync.Once + file_common_model_todo_proto_rawDescData = file_common_model_todo_proto_rawDesc +) + +func file_common_model_todo_proto_rawDescGZIP() []byte { + file_common_model_todo_proto_rawDescOnce.Do(func() { + file_common_model_todo_proto_rawDescData = protoimpl.X.CompressGZIP(file_common_model_todo_proto_rawDescData) + }) + return file_common_model_todo_proto_rawDescData +} + +var file_common_model_todo_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_common_model_todo_proto_goTypes = []interface{}{ + (*Todo)(nil), // 0: session3.todo.model.Todo + (*GetAllResponse)(nil), // 1: session3.todo.model.GetAllResponse + (*GetAllRequest)(nil), // 2: session3.todo.model.GetAllRequest + (*GetByIDRequest)(nil), // 3: session3.todo.model.GetByIDRequest + (*GetByIDResponse)(nil), // 4: session3.todo.model.GetByIDResponse + (*MutationResponse)(nil), // 5: session3.todo.model.MutationResponse + (*UpdateRequest)(nil), // 6: session3.todo.model.UpdateRequest + (*DeleteRequest)(nil), // 7: session3.todo.model.DeleteRequest + (*emptypb.Empty)(nil), // 8: google.protobuf.Empty +} +var file_common_model_todo_proto_depIdxs = []int32{ + 0, // 0: session3.todo.model.GetAllResponse.data:type_name -> session3.todo.model.Todo + 0, // 1: session3.todo.model.GetAllRequest.data:type_name -> session3.todo.model.Todo + 0, // 2: session3.todo.model.GetByIDResponse.data:type_name -> session3.todo.model.Todo + 8, // 3: session3.todo.model.TodoService.GetAll:input_type -> google.protobuf.Empty + 3, // 4: session3.todo.model.TodoService.GetByID:input_type -> session3.todo.model.GetByIDRequest + 0, // 5: session3.todo.model.TodoService.Create:input_type -> session3.todo.model.Todo + 6, // 6: session3.todo.model.TodoService.Update:input_type -> session3.todo.model.UpdateRequest + 7, // 7: session3.todo.model.TodoService.Delete:input_type -> session3.todo.model.DeleteRequest + 1, // 8: session3.todo.model.TodoService.GetAll:output_type -> session3.todo.model.GetAllResponse + 4, // 9: session3.todo.model.TodoService.GetByID:output_type -> session3.todo.model.GetByIDResponse + 5, // 10: session3.todo.model.TodoService.Create:output_type -> session3.todo.model.MutationResponse + 5, // 11: session3.todo.model.TodoService.Update:output_type -> session3.todo.model.MutationResponse + 5, // 12: session3.todo.model.TodoService.Delete:output_type -> session3.todo.model.MutationResponse + 8, // [8:13] is the sub-list for method output_type + 3, // [3:8] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_common_model_todo_proto_init() } +func file_common_model_todo_proto_init() { + if File_common_model_todo_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_common_model_todo_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Todo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_model_todo_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAllResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_model_todo_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAllRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_model_todo_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetByIDRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_model_todo_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetByIDResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_model_todo_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MutationResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_model_todo_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_model_todo_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_common_model_todo_proto_rawDesc, + NumEnums: 0, + NumMessages: 8, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_common_model_todo_proto_goTypes, + DependencyIndexes: file_common_model_todo_proto_depIdxs, + MessageInfos: file_common_model_todo_proto_msgTypes, + }.Build() + File_common_model_todo_proto = out.File + file_common_model_todo_proto_rawDesc = nil + file_common_model_todo_proto_goTypes = nil + file_common_model_todo_proto_depIdxs = nil +} diff --git a/session-3/todo/common/model/todo.pb.gw.go b/session-3/todo/common/model/todo.pb.gw.go new file mode 100644 index 0000000..e3dd037 --- /dev/null +++ b/session-3/todo/common/model/todo.pb.gw.go @@ -0,0 +1,566 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: common/model/todo.proto + +/* +Package model is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package model + +import ( + "context" + "io" + "net/http" + + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/emptypb" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = metadata.Join + +func request_TodoService_GetAll_0(ctx context.Context, marshaler runtime.Marshaler, client TodoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + + msg, err := client.GetAll(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_TodoService_GetAll_0(ctx context.Context, marshaler runtime.Marshaler, server TodoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + + msg, err := server.GetAll(ctx, &protoReq) + return msg, metadata, err + +} + +func request_TodoService_GetByID_0(ctx context.Context, marshaler runtime.Marshaler, client TodoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetByIDRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := client.GetByID(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_TodoService_GetByID_0(ctx context.Context, marshaler runtime.Marshaler, server TodoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetByIDRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := server.GetByID(ctx, &protoReq) + return msg, metadata, err + +} + +func request_TodoService_Create_0(ctx context.Context, marshaler runtime.Marshaler, client TodoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq Todo + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.Create(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_TodoService_Create_0(ctx context.Context, marshaler runtime.Marshaler, server TodoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq Todo + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.Create(ctx, &protoReq) + return msg, metadata, err + +} + +func request_TodoService_Update_0(ctx context.Context, marshaler runtime.Marshaler, client TodoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpdateRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := client.Update(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_TodoService_Update_0(ctx context.Context, marshaler runtime.Marshaler, server TodoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpdateRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := server.Update(ctx, &protoReq) + return msg, metadata, err + +} + +func request_TodoService_Delete_0(ctx context.Context, marshaler runtime.Marshaler, client TodoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := client.Delete(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_TodoService_Delete_0(ctx context.Context, marshaler runtime.Marshaler, server TodoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := server.Delete(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterTodoServiceHandlerServer registers the http handlers for service TodoService to "mux". +// UnaryRPC :call TodoServiceServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterTodoServiceHandlerFromEndpoint instead. +func RegisterTodoServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server TodoServiceServer) error { + + mux.Handle("GET", pattern_TodoService_GetAll_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/session3.todo.model.TodoService/GetAll", runtime.WithHTTPPathPattern("/todos")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_TodoService_GetAll_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_TodoService_GetAll_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_TodoService_GetByID_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/session3.todo.model.TodoService/GetByID", runtime.WithHTTPPathPattern("/todos/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_TodoService_GetByID_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_TodoService_GetByID_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_TodoService_Create_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/session3.todo.model.TodoService/Create", runtime.WithHTTPPathPattern("/todos")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_TodoService_Create_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_TodoService_Create_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("PUT", pattern_TodoService_Update_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/session3.todo.model.TodoService/Update", runtime.WithHTTPPathPattern("/todos/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_TodoService_Update_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_TodoService_Update_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("DELETE", pattern_TodoService_Delete_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/session3.todo.model.TodoService/Delete", runtime.WithHTTPPathPattern("/todos/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_TodoService_Delete_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_TodoService_Delete_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterTodoServiceHandlerFromEndpoint is same as RegisterTodoServiceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterTodoServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterTodoServiceHandler(ctx, mux, conn) +} + +// RegisterTodoServiceHandler registers the http handlers for service TodoService to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterTodoServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterTodoServiceHandlerClient(ctx, mux, NewTodoServiceClient(conn)) +} + +// RegisterTodoServiceHandlerClient registers the http handlers for service TodoService +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "TodoServiceClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "TodoServiceClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "TodoServiceClient" to call the correct interceptors. +func RegisterTodoServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client TodoServiceClient) error { + + mux.Handle("GET", pattern_TodoService_GetAll_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/session3.todo.model.TodoService/GetAll", runtime.WithHTTPPathPattern("/todos")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_TodoService_GetAll_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_TodoService_GetAll_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_TodoService_GetByID_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/session3.todo.model.TodoService/GetByID", runtime.WithHTTPPathPattern("/todos/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_TodoService_GetByID_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_TodoService_GetByID_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_TodoService_Create_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/session3.todo.model.TodoService/Create", runtime.WithHTTPPathPattern("/todos")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_TodoService_Create_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_TodoService_Create_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("PUT", pattern_TodoService_Update_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/session3.todo.model.TodoService/Update", runtime.WithHTTPPathPattern("/todos/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_TodoService_Update_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_TodoService_Update_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("DELETE", pattern_TodoService_Delete_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/session3.todo.model.TodoService/Delete", runtime.WithHTTPPathPattern("/todos/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_TodoService_Delete_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_TodoService_Delete_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_TodoService_GetAll_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0}, []string{"todos"}, "")) + + pattern_TodoService_GetByID_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1}, []string{"todos", "id"}, "")) + + pattern_TodoService_Create_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0}, []string{"todos"}, "")) + + pattern_TodoService_Update_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1}, []string{"todos", "id"}, "")) + + pattern_TodoService_Delete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1}, []string{"todos", "id"}, "")) +) + +var ( + forward_TodoService_GetAll_0 = runtime.ForwardResponseMessage + + forward_TodoService_GetByID_0 = runtime.ForwardResponseMessage + + forward_TodoService_Create_0 = runtime.ForwardResponseMessage + + forward_TodoService_Update_0 = runtime.ForwardResponseMessage + + forward_TodoService_Delete_0 = runtime.ForwardResponseMessage +) diff --git a/session-3/todo/common/model/todo.proto b/session-3/todo/common/model/todo.proto new file mode 100644 index 0000000..5bfea0b --- /dev/null +++ b/session-3/todo/common/model/todo.proto @@ -0,0 +1,76 @@ +syntax = "proto3"; + +package session3.todo.model; + +option go_package = "github.com/ibrahimker/golang-intermediate/session-3/todo/model"; + +import "google/api/annotations.proto"; +import "google/protobuf/empty.proto"; + +service TodoService { + rpc GetAll(google.protobuf.Empty) returns (GetAllResponse) { + option (google.api.http) = { + get : "/todos", + }; + } + + rpc GetByID(GetByIDRequest) returns (GetByIDResponse) { + option (google.api.http) = { + get : "/todos/{id}", + }; + } + + rpc Create(Todo) returns (MutationResponse) { + option (google.api.http) = { + post : "/todos", + body : "*", + }; + } + + rpc Update(UpdateRequest) returns (MutationResponse) { + option (google.api.http) = { + put : "/todos/{id}", + body : "*", + }; + } + + rpc Delete(DeleteRequest) returns (MutationResponse) { + option (google.api.http) = { + delete : "/todos/{id}", + }; + } +} + +message Todo { + string id = 1; + string name = 2; +} + +message GetAllResponse { + repeated Todo data = 1; +} + +message GetAllRequest { + repeated Todo data = 1; +} + +message GetByIDRequest { + string id = 1; +} + +message GetByIDResponse { + Todo data = 1; +} + +message MutationResponse { + string success = 1; +} + +message UpdateRequest { + string id = 1; + string name = 2; +} + +message DeleteRequest { + string id = 1; +} \ No newline at end of file diff --git a/session-3/todo/common/model/todo_grpc.pb.go b/session-3/todo/common/model/todo_grpc.pb.go new file mode 100644 index 0000000..d67867b --- /dev/null +++ b/session-3/todo/common/model/todo_grpc.pb.go @@ -0,0 +1,250 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc (unknown) +// source: common/model/todo.proto + +package model + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// TodoServiceClient is the client API for TodoService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type TodoServiceClient interface { + GetAll(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*GetAllResponse, error) + GetByID(ctx context.Context, in *GetByIDRequest, opts ...grpc.CallOption) (*GetByIDResponse, error) + Create(ctx context.Context, in *Todo, opts ...grpc.CallOption) (*MutationResponse, error) + Update(ctx context.Context, in *UpdateRequest, opts ...grpc.CallOption) (*MutationResponse, error) + Delete(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*MutationResponse, error) +} + +type todoServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewTodoServiceClient(cc grpc.ClientConnInterface) TodoServiceClient { + return &todoServiceClient{cc} +} + +func (c *todoServiceClient) GetAll(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*GetAllResponse, error) { + out := new(GetAllResponse) + err := c.cc.Invoke(ctx, "/session3.todo.model.TodoService/GetAll", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *todoServiceClient) GetByID(ctx context.Context, in *GetByIDRequest, opts ...grpc.CallOption) (*GetByIDResponse, error) { + out := new(GetByIDResponse) + err := c.cc.Invoke(ctx, "/session3.todo.model.TodoService/GetByID", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *todoServiceClient) Create(ctx context.Context, in *Todo, opts ...grpc.CallOption) (*MutationResponse, error) { + out := new(MutationResponse) + err := c.cc.Invoke(ctx, "/session3.todo.model.TodoService/Create", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *todoServiceClient) Update(ctx context.Context, in *UpdateRequest, opts ...grpc.CallOption) (*MutationResponse, error) { + out := new(MutationResponse) + err := c.cc.Invoke(ctx, "/session3.todo.model.TodoService/Update", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *todoServiceClient) Delete(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*MutationResponse, error) { + out := new(MutationResponse) + err := c.cc.Invoke(ctx, "/session3.todo.model.TodoService/Delete", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// TodoServiceServer is the server API for TodoService service. +// All implementations must embed UnimplementedTodoServiceServer +// for forward compatibility +type TodoServiceServer interface { + GetAll(context.Context, *emptypb.Empty) (*GetAllResponse, error) + GetByID(context.Context, *GetByIDRequest) (*GetByIDResponse, error) + Create(context.Context, *Todo) (*MutationResponse, error) + Update(context.Context, *UpdateRequest) (*MutationResponse, error) + Delete(context.Context, *DeleteRequest) (*MutationResponse, error) + mustEmbedUnimplementedTodoServiceServer() +} + +// UnimplementedTodoServiceServer must be embedded to have forward compatible implementations. +type UnimplementedTodoServiceServer struct { +} + +func (UnimplementedTodoServiceServer) GetAll(context.Context, *emptypb.Empty) (*GetAllResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAll not implemented") +} +func (UnimplementedTodoServiceServer) GetByID(context.Context, *GetByIDRequest) (*GetByIDResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetByID not implemented") +} +func (UnimplementedTodoServiceServer) Create(context.Context, *Todo) (*MutationResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Create not implemented") +} +func (UnimplementedTodoServiceServer) Update(context.Context, *UpdateRequest) (*MutationResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Update not implemented") +} +func (UnimplementedTodoServiceServer) Delete(context.Context, *DeleteRequest) (*MutationResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented") +} +func (UnimplementedTodoServiceServer) mustEmbedUnimplementedTodoServiceServer() {} + +// UnsafeTodoServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to TodoServiceServer will +// result in compilation errors. +type UnsafeTodoServiceServer interface { + mustEmbedUnimplementedTodoServiceServer() +} + +func RegisterTodoServiceServer(s grpc.ServiceRegistrar, srv TodoServiceServer) { + s.RegisterService(&TodoService_ServiceDesc, srv) +} + +func _TodoService_GetAll_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TodoServiceServer).GetAll(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/session3.todo.model.TodoService/GetAll", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TodoServiceServer).GetAll(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _TodoService_GetByID_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetByIDRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TodoServiceServer).GetByID(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/session3.todo.model.TodoService/GetByID", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TodoServiceServer).GetByID(ctx, req.(*GetByIDRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _TodoService_Create_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Todo) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TodoServiceServer).Create(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/session3.todo.model.TodoService/Create", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TodoServiceServer).Create(ctx, req.(*Todo)) + } + return interceptor(ctx, in, info, handler) +} + +func _TodoService_Update_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TodoServiceServer).Update(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/session3.todo.model.TodoService/Update", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TodoServiceServer).Update(ctx, req.(*UpdateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _TodoService_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TodoServiceServer).Delete(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/session3.todo.model.TodoService/Delete", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TodoServiceServer).Delete(ctx, req.(*DeleteRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// TodoService_ServiceDesc is the grpc.ServiceDesc for TodoService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var TodoService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "session3.todo.model.TodoService", + HandlerType: (*TodoServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetAll", + Handler: _TodoService_GetAll_Handler, + }, + { + MethodName: "GetByID", + Handler: _TodoService_GetByID_Handler, + }, + { + MethodName: "Create", + Handler: _TodoService_Create_Handler, + }, + { + MethodName: "Update", + Handler: _TodoService_Update_Handler, + }, + { + MethodName: "Delete", + Handler: _TodoService_Delete_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "common/model/todo.proto", +} diff --git a/session-3/todo/docs/openapiv2/common/model/todo.swagger.json b/session-3/todo/docs/openapiv2/common/model/todo.swagger.json new file mode 100644 index 0000000..746bc05 --- /dev/null +++ b/session-3/todo/docs/openapiv2/common/model/todo.swagger.json @@ -0,0 +1,238 @@ +{ + "swagger": "2.0", + "info": { + "title": "common/model/todo.proto", + "version": "version not set" + }, + "tags": [ + { + "name": "TodoService" + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": { + "/todos": { + "get": { + "operationId": "TodoService_GetAll", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/modelGetAllResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "tags": [ + "TodoService" + ] + }, + "post": { + "operationId": "TodoService_Create", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/modelMutationResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/modelTodo" + } + } + ], + "tags": [ + "TodoService" + ] + } + }, + "/todos/{id}": { + "get": { + "operationId": "TodoService_GetByID", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/modelGetByIDResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "TodoService" + ] + }, + "delete": { + "operationId": "TodoService_Delete", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/modelMutationResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "TodoService" + ] + }, + "put": { + "operationId": "TodoService_Update", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/modelMutationResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + } + } + ], + "tags": [ + "TodoService" + ] + } + } + }, + "definitions": { + "modelGetAllResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/modelTodo" + } + } + } + }, + "modelGetByIDResponse": { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/modelTodo" + } + } + }, + "modelMutationResponse": { + "type": "object", + "properties": { + "success": { + "type": "string" + } + } + }, + "modelTodo": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "protobufAny": { + "type": "object", + "properties": { + "@type": { + "type": "string" + } + }, + "additionalProperties": {} + }, + "rpcStatus": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "$ref": "#/definitions/protobufAny" + } + } + } + } + } +} diff --git a/session-3/todo/main.go b/session-3/todo/main.go new file mode 100644 index 0000000..8b56773 --- /dev/null +++ b/session-3/todo/main.go @@ -0,0 +1,87 @@ +package main + +import ( + "context" + "errors" + "flag" + "net" + "net/http" + + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/ibrahimker/golang-intermediate/session-3/todo/common/config" + "github.com/ibrahimker/golang-intermediate/session-3/todo/common/model" + log "github.com/sirupsen/logrus" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/protobuf/types/known/emptypb" +) + +type TodoServer struct { + model.UnimplementedTodoServiceServer +} + +var Todos = make(map[string]*model.Todo) + +func main() { + srv := grpc.NewServer() + userSrv := new(TodoServer) + model.RegisterTodoServiceServer(srv, userSrv) + + log.Println("Starting Todo Server at ", config.SERVICE_TODO_PORT) + + listener, err := net.Listen("tcp", config.SERVICE_TODO_PORT) + if err != nil { + log.Fatalf("could not listen. Err: %+v\n", err) + } + + // setup http proxy + go func() { + mux := runtime.NewServeMux() + opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())} + grpcServerEndpoint := flag.String("grpc-server-endpoint", "localhost"+config.SERVICE_TODO_PORT, "gRPC server endpoint") + _ = model.RegisterTodoServiceHandlerFromEndpoint(context.Background(), r, *grpcServerEndpoint, opts) + log.Println("Starting Todo Server HTTP at 9001 ") + http.ListenAndServe(":9001", mux) + }() + + log.Fatalln(srv.Serve(listener)) +} + +func (t *TodoServer) GetAll(ctx context.Context, req *emptypb.Empty) (*model.GetAllResponse, error) { + var todos []*model.Todo + for _, v := range Todos { + todos = append(todos, &model.Todo{ + Id: v.GetId(), + Name: v.GetName(), + }) + } + return &model.GetAllResponse{Data: todos}, nil +} +func (t *TodoServer) GetByID(ctx context.Context, req *model.GetByIDRequest) (*model.GetByIDResponse, error) { + todo, ok := Todos[req.GetId()] + if !ok { + return nil, errors.New("not found") + } + return &model.GetByIDResponse{Data: todo}, nil +} +func (t *TodoServer) Create(ctx context.Context, req *model.Todo) (*model.MutationResponse, error) { + Todos[req.GetId()] = &model.Todo{ + Id: req.GetId(), + Name: req.GetName(), + } + msg := req.GetId() + "successfully appended" + return &model.MutationResponse{Success: msg}, nil +} +func (t *TodoServer) Update(ctx context.Context, req *model.UpdateRequest) (*model.MutationResponse, error) { + Todos[req.GetId()] = &model.Todo{ + Id: req.GetId(), + Name: req.GetName(), + } + msg := req.GetId() + "successfully appended" + return &model.MutationResponse{Success: msg}, nil +} +func (t *TodoServer) Delete(ctx context.Context, req *model.DeleteRequest) (*model.MutationResponse, error) { + delete(Todos, req.GetId()) + msg := req.GetId() + "successfully deleted" + return &model.MutationResponse{Success: msg}, nil +} diff --git a/session-4/login.html b/session-4/login.html new file mode 100644 index 0000000..2834e67 --- /dev/null +++ b/session-4/login.html @@ -0,0 +1,18 @@ + + + Template + + +
+
+ + +
+
+ + +
+ +
+ + \ No newline at end of file diff --git a/session-4/main.go b/session-4/main.go index 3b159e3..f0799c8 100644 --- a/session-4/main.go +++ b/session-4/main.go @@ -2,79 +2,45 @@ package main import ( "fmt" - "html/template" "net/http" + "github.com/go-ldap/ldap" + "github.com/ibrahimker/golang-intermediate/session-4/config" + "github.com/ibrahimker/golang-intermediate/session-4/repository" + "github.com/ibrahimker/golang-intermediate/session-4/router" + "github.com/ibrahimker/golang-intermediate/session-4/service" log "github.com/sirupsen/logrus" "github.com/gorilla/mux" - "github.com/ibrahimker/golang-intermediate/session-4/ldap" ) const ( port = "9000" baseURL = "0.0.0.0:" + port - view = ` - - - Template - - -
-
- - -
-
- - -
- -
- - - ` ) func main() { log.SetReportCaller(true) - r := mux.NewRouter() - r.HandleFunc("/", handleRoute) - r.HandleFunc("/login", handleLogin) - log.Infoln("Listening at ", baseURL) - log.Fatal(http.ListenAndServe(baseURL, r)) -} - -func handleRoute(w http.ResponseWriter, r *http.Request) { - tmpl := template.Must(template.New("main-template").Parse(view)) - if err := tmpl.Execute(w, nil); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return + // init ldap connection + ldapConn, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", config.LdapServer, config.LdapPort)) + if err != nil { + panic(err) } -} - -func handleLogin(w http.ResponseWriter, r *http.Request) { - if err := r.ParseForm(); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return + defer ldapConn.Close() + // bind to ldap server + if err = ldapConn.Bind(config.LdapBindDN, config.LdapPassword); err != nil { + panic(err) } - username := r.PostFormValue("username") - password := r.PostFormValue("password") + ldapRepo := repository.NewLDAPRepo(ldapConn) + loginService := service.NewLoginService(ldapRepo) - ok, data, err := ldap.AuthUsingLDAP(username, password) - if !ok { - log.Error("auth using ldap not ok") - http.Error(w, "invalid username/password", http.StatusUnauthorized) - return - } - if err != nil { - log.Error(err) - http.Error(w, err.Error(), http.StatusUnauthorized) - return - } + r := mux.NewRouter() + routerHandler := router.NewRouterHandler(loginService) + r.HandleFunc("/", routerHandler.ServeHTML) + r.HandleFunc("/login", routerHandler.HandleLogin) - message := fmt.Sprintf("Welcome %s\n", data.FullName) - w.Write([]byte(message)) + log.Infoln("Listening at ", baseURL) + log.Fatal(http.ListenAndServe(baseURL, r)) } diff --git a/session-4/ldap/ldap.go b/session-4/repository/ldap.go similarity index 57% rename from session-4/ldap/ldap.go rename to session-4/repository/ldap.go index 980c027..11dcbbd 100644 --- a/session-4/ldap/ldap.go +++ b/session-4/repository/ldap.go @@ -1,22 +1,15 @@ -package ldap +package repository import ( "errors" "fmt" + "github.com/ibrahimker/golang-intermediate/session-4/config" log "github.com/sirupsen/logrus" "github.com/go-ldap/ldap" ) -const ( - ldapServer = "ldap.forumsys.com" - ldapPort = 389 - ldapBindDN = "cn=read-only-admin,dc=example,dc=com" - ldapPassword = "password" - ldapSearchDN = "dc=example,dc=com" -) - type UserLDAPData struct { ID string Email string @@ -24,23 +17,17 @@ type UserLDAPData struct { FullName string } -func AuthUsingLDAP(username, password string) (bool, *UserLDAPData, error) { - - // init ldap connection - l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort)) - if err != nil { - log.Error(err) - return false, nil, err - } - defer l.Close() +type LDAPRepo struct { + conn *ldap.Conn +} - // bind to ldap server - if err = l.Bind(ldapBindDN, ldapPassword); err != nil { - return false, nil, err - } +func NewLDAPRepo(conn *ldap.Conn) *LDAPRepo { + return &LDAPRepo{conn: conn} +} +func (r *LDAPRepo) AuthUsingLDAP(username, password string) (bool, *UserLDAPData, error) { searchRequest := ldap.NewSearchRequest( - ldapSearchDN, + config.LdapSearchDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, @@ -51,7 +38,7 @@ func AuthUsingLDAP(username, password string) (bool, *UserLDAPData, error) { nil, ) - sr, err := l.Search(searchRequest) + sr, err := r.conn.Search(searchRequest) if err != nil { log.Error(err) return false, nil, err @@ -62,7 +49,7 @@ func AuthUsingLDAP(username, password string) (bool, *UserLDAPData, error) { } entry := sr.Entries[0] - if err = l.Bind(entry.DN, password); err != nil { + if err = r.conn.Bind(entry.DN, password); err != nil { log.Error(err) return false, nil, err } diff --git a/session-4/router/router.go b/session-4/router/router.go new file mode 100644 index 0000000..6219081 --- /dev/null +++ b/session-4/router/router.go @@ -0,0 +1,44 @@ +package router + +import ( + "fmt" + "html/template" + "net/http" + + "github.com/ibrahimker/golang-intermediate/session-4/service" +) + +type RouterHandler struct { + loginService *service.LoginSvc +} + +func NewRouterHandler(loginService *service.LoginSvc) *RouterHandler { + return &RouterHandler{loginService: loginService} +} + +func (rh *RouterHandler) ServeHTML(w http.ResponseWriter, r *http.Request) { + parsedTemplate, _ := template.ParseFiles("login.html") + if err := parsedTemplate.Execute(w, nil); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} + +func (rh *RouterHandler) HandleLogin(w http.ResponseWriter, r *http.Request) { + if err := r.ParseForm(); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + username := r.PostFormValue("username") + password := r.PostFormValue("password") + + data, err := rh.loginService.Authenticate(username, password) + if err != nil { + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + + message := fmt.Sprintf("Welcome Name: %s, FullName: %s, Email: %s\n", data.Name, data.FullName, data.Email) + w.Write([]byte(message)) +} diff --git a/session-4/service/login.go b/session-4/service/login.go new file mode 100644 index 0000000..82358af --- /dev/null +++ b/session-4/service/login.go @@ -0,0 +1,31 @@ +package service + +import ( + "errors" + + "github.com/ibrahimker/golang-intermediate/session-4/repository" + log "github.com/sirupsen/logrus" +) + +type LoginSvc struct { + loginRepo *repository.LDAPRepo +} + +func NewLoginService(loginRepo *repository.LDAPRepo) *LoginSvc { + return &LoginSvc{loginRepo: loginRepo} +} + +func (s *LoginSvc) Authenticate(username, password string) (*repository.UserLDAPData, error) { + ok, data, err := s.loginRepo.AuthUsingLDAP(username, password) + if !ok { + err := errors.New("auth using ldap not ok") + log.Error("auth using ldap not ok") + return nil, err + } + if err != nil { + log.Error(err) + return nil, err + } + + return data, nil +} diff --git a/session-5/main.go b/session-5/main.go new file mode 100644 index 0000000..1d60855 --- /dev/null +++ b/session-5/main.go @@ -0,0 +1,106 @@ +package main + +import ( + "fmt" + "net/http" + "strings" + + "github.com/go-playground/validator" + "github.com/labstack/echo" +) + +type M map[string]interface{} + +type User struct { + Name string `json:"name" form:"name" query:"name" validate:"required"` + Email string `json:"email" form:"email" query:"email" validate:"required,email"` +} + +type CustomValidator struct { + validator *validator.Validate +} + +func (cv *CustomValidator) Validate(i interface{}) error { + return cv.validator.Struct(i) +} + +func main() { + r := echo.New() + r.Validator = &CustomValidator{validator: validator.New()} + + r.GET("/", func(ctx echo.Context) error { + data := "Hello from /index" + return ctx.String(http.StatusOK, data) + }) + + r.GET("/index", func(ctx echo.Context) error { + data := "Hello from /index" + return ctx.String(http.StatusOK, data) + }) + + r.GET("/html", func(ctx echo.Context) error { + data := "Hello from /html" + return ctx.HTML(http.StatusOK, data) + }) + + r.GET("/index", func(ctx echo.Context) error { + return ctx.Redirect(http.StatusTemporaryRedirect, "/") + }) + + r.GET("/json", func(ctx echo.Context) error { + data := M{"Message": "Hello", "Counter": 2} + return ctx.JSON(http.StatusOK, data) + }) + + r.GET("/page1", func(ctx echo.Context) error { + name := ctx.QueryParam("name") + data := fmt.Sprintf("Hello %s", name) + + return ctx.String(http.StatusOK, data) + }) + + r.GET("/page2/:name", func(ctx echo.Context) error { + name := ctx.Param("name") + data := fmt.Sprintf("Hello %s", name) + + return ctx.String(http.StatusOK, data) + }) + + r.GET("/page3/:name/*", func(ctx echo.Context) error { + name := ctx.Param("name") + message := ctx.Param("*") + + data := fmt.Sprintf("Hello %s, I have message for you: %s", name, message) + + return ctx.String(http.StatusOK, data) + }) + + r.POST("/page4", func(ctx echo.Context) error { + name := ctx.FormValue("name") + message := ctx.FormValue("message") + + data := fmt.Sprintf( + "Hello %s, I have message for you: %s", + name, + strings.Replace(message, "/", "", 1), + ) + + return ctx.String(http.StatusOK, data) + }) + + r.POST("/user", func(ctx echo.Context) error { + u := new(User) + + if err := ctx.Bind(u); err != nil { + return ctx.String(http.StatusInternalServerError, err.Error()) + } + + if err := ctx.Validate(u); err != nil { + return ctx.String(http.StatusBadRequest, err.Error()) + } + + return ctx.JSON(http.StatusOK, u) + }) + + r.Start(":9000") +} diff --git a/session-6/docker-compose.yaml b/session-6/docker-compose.yaml new file mode 100644 index 0000000..165a29a --- /dev/null +++ b/session-6/docker-compose.yaml @@ -0,0 +1,11 @@ +version: '3' + +services: + postgres: + image: postgres:13.2-alpine + environment: + - POSTGRES_USER=postgresuser + - POSTGRES_PASSWORD=postgrespassword + - POSTGRES_DB=postgres + ports: + - 5432:5432 diff --git a/session-6/main.go b/session-6/main.go new file mode 100644 index 0000000..7d513f4 --- /dev/null +++ b/session-6/main.go @@ -0,0 +1,88 @@ +package main + +import ( + "fmt" + "log" + "net/http" + "os" + + "github.com/antonlindstrom/pgstore" + "github.com/gorilla/sessions" + "github.com/labstack/echo" +) + +const SESSION_ID = "test-session-id" + +func newPostgresStore() *pgstore.PGStore { + url := "postgres://postgresuser:postgrespassword@127.0.0.1:5432/postgres?sslmode=disable" + authKey := []byte("my-auth-key-very-secret") + encryptionKey := []byte("my-encryption-key-very-secret123") + + store, err := pgstore.NewPGStore(url, authKey, encryptionKey) + if err != nil { + log.Println("ERROR", err) + os.Exit(0) + } + + return store +} + +func newCookieStore() *sessions.CookieStore { + authKey := []byte("my-auth-key-very-secret") + encryptionKey := []byte("my-encryption-key-very-secret123") + + store := sessions.NewCookieStore(authKey, encryptionKey) + store.Options.Path = "/" + store.Options.MaxAge = 86400 * 7 + store.Options.HttpOnly = true + + return store +} + +func main() { + e := echo.New() + store := newPostgresStore() + + e.GET("/", func(ctx echo.Context) error { + data := "Hello from /index" + return ctx.String(http.StatusOK, data) + }) + + e.GET("/set", func(c echo.Context) error { + session, err := store.Get(c.Request(), SESSION_ID) + if err != nil { + return c.String(http.StatusInternalServerError, err.Error()) + } + session.Values["message1"] = "hello" + session.Values["message2"] = "world" + if err := session.Save(c.Request(), c.Response()); err != nil { + return c.String(http.StatusInternalServerError, err.Error()) + } + + return c.Redirect(http.StatusTemporaryRedirect, "/get") + }) + + e.GET("/get", func(c echo.Context) error { + session, _ := store.Get(c.Request(), SESSION_ID) + + if len(session.Values) == 0 { + return c.String(http.StatusOK, "empty result") + } + + return c.String(http.StatusOK, fmt.Sprintf( + "%s %s", + session.Values["message1"], + session.Values["message2"], + )) + }) + + e.GET("/delete", func(c echo.Context) error { + session, _ := store.Get(c.Request(), SESSION_ID) + session.Options.MaxAge = -1 + session.Save(c.Request(), c.Response()) + + return c.Redirect(http.StatusTemporaryRedirect, "/get") + }) + + e.Start(":9000") +} diff --git a/session-7/main.go b/session-7/main.go new file mode 100644 index 0000000..a6a5bd2 --- /dev/null +++ b/session-7/main.go @@ -0,0 +1,124 @@ +package main + +import ( + "io" + "log" + "os" + + "github.com/pkg/sftp" + "golang.org/x/crypto/ssh" +) + +func main() { + const SSH_ADDRESS = "0.0.0.0:22" + const SSH_USERNAME = "user" + const SSH_PASSWORD = "password" + + sshConfig := &ssh.ClientConfig{ + User: SSH_USERNAME, + HostKeyCallback: ssh.InsecureIgnoreHostKey(), + Auth: []ssh.AuthMethod{ + ssh.Password(SSH_PASSWORD), + }, + } + + // dial ssh + client, err := ssh.Dial("tcp", SSH_ADDRESS, sshConfig) + if client != nil { + defer client.Close() + } + if err != nil { + log.Fatal("Failed to dial. " + err.Error()) + } + + // create session + session, err := client.NewSession() + if err != nil { + log.Fatal("Failed to create session. " + err.Error()) + } + //session.Stdin = os.Stdin + session.Stdout = os.Stdout + session.Stderr = os.Stderr + + // test session + stdinBuf, _ := session.StdinPipe() + if err := session.Shell(); err != nil { + panic(err) + } + stdinBuf.Write([]byte("echo hello\n")) + stdinBuf.Write([]byte("ls -l ~/\n")) + //err = session.Run("ls -l ~/") + //if err != nil { + // log.Fatal("Command execution error. " + err.Error()) + //} + + // test StdinPipe + //var stdout, stderr bytes.Buffer + //session.Stdout = &stdout + //session.Stderr = &stderr + // + //stdin, err := session.StdinPipe() + //if err != nil { + // log.Fatal("Error getting stdin pipe. " + err.Error()) + //} + // + //err = session.Start("/bin/bash") + //if err != nil { + // log.Fatal("Error starting bash. " + err.Error()) + //} + // + //commands := []string{ + // "cd /where/is/the/path", + // "cd src/myproject", + // "ls", + // "exit", + //} + //for _, cmd := range commands { + // if _, err = fmt.Fprintln(stdin, cmd); err != nil { + // log.Fatal(err) + // } + //} + // + //err = session.Wait() + //if err != nil { + // log.Fatal(err) + //} + // + //outputErr := stderr.String() + //fmt.Println("============== ERROR") + //fmt.Println(strings.TrimSpace(outputErr)) + // + //outputString := stdout.String() + //fmt.Println("============== OUTPUT") + //fmt.Println(strings.TrimSpace(outputString)) + + // test sftp + sftpClient, err := sftp.NewClient(client) + if err != nil { + log.Fatal("Failed create client sftp client. " + err.Error()) + } + + //err = session.Run("touch ~/test-file.txt") + //if err != nil { + // log.Fatal("Command execution error. " + err.Error()) + //} + //session.Close() + fDestination, err := sftpClient.Create("/home/user/test-file.txt") + if err != nil { + log.Fatal("Failed to create destination file. " + err.Error()) + } + + fSource, err := os.Open("/home/ibam/Documents/code/golang-intermediate/session-7/test-file.txt") + if err != nil { + log.Fatal("Failed to read source file. " + err.Error()) + } + + _, err = io.Copy(fDestination, fSource) + if err != nil { + log.Fatal("Failed copy source file into destination file. " + err.Error()) + } + + log.Println("File copied.") + + // create new session +} diff --git a/session-7/test-file.txt b/session-7/test-file.txt new file mode 100644 index 0000000..9f6398f --- /dev/null +++ b/session-7/test-file.txt @@ -0,0 +1 @@ +hai \ No newline at end of file diff --git a/session-8/main.go b/session-8/main.go new file mode 100644 index 0000000..3705a20 --- /dev/null +++ b/session-8/main.go @@ -0,0 +1,107 @@ +package main + +import ( + "fmt" + "net/http" + "time" + + "github.com/ibrahimker/golang-intermediate/session-8/middleware" + "github.com/labstack/echo" + echoMiddleware "github.com/labstack/echo/middleware" + "github.com/sirupsen/logrus" + "github.com/spf13/viper" +) + +func main() { + viper.AddConfigPath("./config") + viper.SetConfigName("config.yaml") + viper.SetConfigType("yaml") + if err := viper.ReadInConfig(); err != nil { + panic(err) + } + + e := echo.New() + e.Use(middlewareOne) + e.Use(middlewareTwo) + e.Use(echo.WrapMiddleware(middlewareSomething)) + //e.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{ + // Format: "method=${method}, uri=${uri}, status=${status}\n", + //})) + + // with logrus + e.Use(middlewareLogging) + e.HTTPErrorHandler = errorHandler + + // middleware here + + e.GET("/index", func(c echo.Context) (err error) { + fmt.Println("threeeeee!") + + return c.JSON(http.StatusOK, true) + }) + + private := e.Group("/private") + private.Use(echoMiddleware.BasicAuth(middleware.BasicAuthMiddleware)) + private.GET("/index", func(c echo.Context) (err error) { + fmt.Println("threeeeee!") + + return c.JSON(http.StatusOK, true) + }) + + e.Logger.Fatal(e.Start(":9000")) +} + +func middlewareOne(next echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + fmt.Println("from middleware one") + return next(c) + } +} + +func middlewareTwo(next echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + fmt.Println("from middleware two") + return next(c) + } +} + +func middlewareSomething(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Println("from middleware something") + next.ServeHTTP(w, r) + }) +} + +func makeLogEntry(c echo.Context) *logrus.Entry { + if c == nil { + return logrus.WithFields(logrus.Fields{ + "at": time.Now().Format("2006-01-02 15:04:05"), + }) + } + + return logrus.WithFields(logrus.Fields{ + "at": time.Now().Format("2006-01-02 15:04:05"), + "method": c.Request().Method, + "uri": c.Request().URL.String(), + "ip": c.Request().RemoteAddr, + }) +} + +func middlewareLogging(next echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + makeLogEntry(c).Info("incoming request") + return next(c) + } +} + +func errorHandler(err error, c echo.Context) { + report, ok := err.(*echo.HTTPError) + if ok { + report.Message = fmt.Sprintf("http error %d - %v", report.Code, report.Message) + } else { + report = echo.NewHTTPError(http.StatusInternalServerError, err.Error()) + } + + makeLogEntry(c).Error(report.Message) + c.HTML(report.Code, report.Message.(string)) +} diff --git a/session-8/middleware/basicauth.go b/session-8/middleware/basicauth.go new file mode 100644 index 0000000..26feac9 --- /dev/null +++ b/session-8/middleware/basicauth.go @@ -0,0 +1,14 @@ +package middleware + +import ( + "github.com/labstack/echo" + "github.com/spf13/viper" +) + +func BasicAuthMiddleware(username, password string, c echo.Context) (bool, error) { + // Be careful to use constant time comparison to prevent timing attacks + if username == viper.GetString("BasicAuthUser") && password == viper.GetString("BasicAuthPass") { + return true, nil + } + return false, nil +} diff --git a/session-9/main.go b/session-9/main.go new file mode 100644 index 0000000..96ad28d --- /dev/null +++ b/session-9/main.go @@ -0,0 +1,47 @@ +package main + +import ( + "fmt" + "html/template" + "net/http" + + "github.com/labstack/echo" + "github.com/labstack/echo/middleware" +) + +type M map[string]interface{} + +const ( + CSRFTokenHeader = "X-CSRF-Token" + CSRFKey = "csrf" +) + +func main() { + tmpl := template.Must(template.ParseGlob("./*.html")) + + e := echo.New() + + e.Use(middleware.CSRFWithConfig(middleware.CSRFConfig{ + TokenLookup: "header:" + CSRFTokenHeader, + ContextKey: CSRFKey, + CookieMaxAge: 60, + })) + + e.GET("/index", func(c echo.Context) error { + data := make(M) + data[CSRFKey] = c.Get(CSRFKey) + return tmpl.Execute(c.Response(), data) + }) + + e.POST("/sayhello", func(c echo.Context) error { + data := make(M) + if err := c.Bind(&data); err != nil { + return err + } + + message := fmt.Sprintf("hello %s", data["name"]) + return c.JSON(http.StatusOK, message) + }) + + e.Logger.Fatal(e.Start(":9000")) +} diff --git a/session-9/view.html b/session-9/view.html new file mode 100644 index 0000000..5a5ff93 --- /dev/null +++ b/session-9/view.html @@ -0,0 +1,63 @@ + + + + + + +
+
+ + +
+
+ + +
+
+ + +
+
+ + + + + + \ No newline at end of file