mirror of
https://github.com/harness/drone.git
synced 2025-05-04 09:39:18 +08:00
[MAINT] initial work on linter setup (#16)
* initial work on linter setup * simple linter rules fixed
This commit is contained in:
parent
f58ceac474
commit
ca8aa47e05
4
Makefile
4
Makefile
@ -35,7 +35,7 @@ tools: $(tools) ## Install tools required for the build
|
|||||||
mocks: $(mocks)
|
mocks: $(mocks)
|
||||||
@echo "Generating Test Mocks"
|
@echo "Generating Test Mocks"
|
||||||
|
|
||||||
generate: $(mocks) wire_gen.go mocks/mock_client.go
|
generate: $(mocks) cli/server/wire_gen.go mocks/mock_client.go
|
||||||
@echo "Generating Code"
|
@echo "Generating Code"
|
||||||
|
|
||||||
build: generate ## Build the gitness service binary
|
build: generate ## Build the gitness service binary
|
||||||
@ -114,7 +114,7 @@ lint: tools generate # lint the golang code
|
|||||||
# Some code generation can be slow, so we only run it if
|
# Some code generation can be slow, so we only run it if
|
||||||
# the source file has changed.
|
# the source file has changed.
|
||||||
###########################################
|
###########################################
|
||||||
wire_gen.go: cli/server/wire.go ## Update the wire dependency injection if wire.go has changed.
|
cli/server/wire_gen.go: cli/server/wire.go ## Update the wire dependency injection if wire.go has changed.
|
||||||
@echo "Updating wire_gen.go"
|
@echo "Updating wire_gen.go"
|
||||||
go generate ./cli/server/wire_gen.go
|
go generate ./cli/server/wire_gen.go
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
package cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/harness/gitness/cli/server"
|
"github.com/harness/gitness/cli/server"
|
||||||
@ -17,9 +16,6 @@ import (
|
|||||||
"gopkg.in/alecthomas/kingpin.v2"
|
"gopkg.in/alecthomas/kingpin.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// empty context
|
|
||||||
var nocontext = context.Background()
|
|
||||||
|
|
||||||
// application name
|
// application name
|
||||||
var application = "gitness"
|
var application = "gitness"
|
||||||
|
|
||||||
|
@ -25,7 +25,10 @@ type command struct {
|
|||||||
|
|
||||||
func (c *command) run(*kingpin.ParseContext) error {
|
func (c *command) run(*kingpin.ParseContext) error {
|
||||||
// load environment variables from file.
|
// load environment variables from file.
|
||||||
godotenv.Load(c.envfile)
|
err := godotenv.Load(c.envfile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// create the system configuration store by loading
|
// create the system configuration store by loading
|
||||||
// data from the environment.
|
// data from the environment.
|
||||||
|
@ -51,7 +51,9 @@ func (c *listCommand) run(*kingpin.ParseContext) error {
|
|||||||
return enc.Encode(list)
|
return enc.Encode(list)
|
||||||
}
|
}
|
||||||
for _, item := range list {
|
for _, item := range list {
|
||||||
tmpl.Execute(os.Stdout, item)
|
if err = tmpl.Execute(os.Stdout, item); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"golang.org/x/term"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -20,7 +21,6 @@ import (
|
|||||||
"github.com/harness/gitness/types"
|
"github.com/harness/gitness/types"
|
||||||
|
|
||||||
"github.com/adrg/xdg"
|
"github.com/adrg/xdg"
|
||||||
"golang.org/x/crypto/ssh/terminal"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Client returns a client that is configured from file.
|
// Client returns a client that is configured from file.
|
||||||
@ -72,7 +72,7 @@ func Username() string {
|
|||||||
// Password returns the password from stdin.
|
// Password returns the password from stdin.
|
||||||
func Password() string {
|
func Password() string {
|
||||||
fmt.Print("Enter Password: ")
|
fmt.Print("Enter Password: ")
|
||||||
passwordb, _ := terminal.ReadPassword(int(syscall.Stdin))
|
passwordb, _ := term.ReadPassword(int(syscall.Stdin))
|
||||||
password := string(passwordb)
|
password := string(passwordb)
|
||||||
|
|
||||||
return strings.TrimSpace(password)
|
return strings.TrimSpace(password)
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httputil"
|
"net/http/httputil"
|
||||||
@ -150,11 +151,6 @@ func (c *HTTPClient) post(rawurl string, in, out interface{}) error {
|
|||||||
return c.do(rawurl, "POST", in, out)
|
return c.do(rawurl, "POST", in, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper function for making an http PUT request.
|
|
||||||
func (c *HTTPClient) put(rawurl string, in, out interface{}) error {
|
|
||||||
return c.do(rawurl, "PUT", in, out)
|
|
||||||
}
|
|
||||||
|
|
||||||
// helper function for making an http PATCH request.
|
// helper function for making an http PATCH request.
|
||||||
func (c *HTTPClient) patch(rawurl string, in, out interface{}) error {
|
func (c *HTTPClient) patch(rawurl string, in, out interface{}) error {
|
||||||
return c.do(rawurl, "PATCH", in, out)
|
return c.do(rawurl, "PATCH", in, out)
|
||||||
@ -199,7 +195,9 @@ func (c *HTTPClient) stream(rawurl, method string, in, out interface{}) (io.Read
|
|||||||
buf = new(bytes.Buffer)
|
buf = new(bytes.Buffer)
|
||||||
// if posting form data, encode the form values.
|
// if posting form data, encode the form values.
|
||||||
if form, ok := in.(*url.Values); ok {
|
if form, ok := in.(*url.Values); ok {
|
||||||
io.WriteString(buf, form.Encode())
|
if _, err := io.WriteString(buf, form.Encode()); err != nil {
|
||||||
|
log.Err(err).Msg("in stream method")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if err := json.NewEncoder(buf).Encode(in); err != nil {
|
if err := json.NewEncoder(buf).Encode(in); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -239,7 +237,9 @@ func (c *HTTPClient) stream(rawurl, method string, in, out interface{}) (io.Read
|
|||||||
if resp.StatusCode > 299 {
|
if resp.StatusCode > 299 {
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
err := new(remoteError)
|
err := new(remoteError)
|
||||||
json.NewDecoder(resp.Body).Decode(err)
|
if decodeErr := json.NewDecoder(resp.Body).Decode(err); decodeErr != nil {
|
||||||
|
return nil, decodeErr
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return resp.Body, nil
|
return resp.Body, nil
|
||||||
|
@ -33,7 +33,9 @@ func TestFind(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
got, want := &types.User{}, mockUser
|
got, want := &types.User{}, mockUser
|
||||||
json.NewDecoder(w.Body).Decode(got)
|
if err := json.NewDecoder(w.Body).Decode(got); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
if diff := cmp.Diff(got, want); len(diff) != 0 {
|
if diff := cmp.Diff(got, want); len(diff) != 0 {
|
||||||
t.Errorf(diff)
|
t.Errorf(diff)
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,9 @@ func TestToken(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
result := &types.Token{}
|
result := &types.Token{}
|
||||||
json.NewDecoder(w.Body).Decode(&result)
|
if err := json.NewDecoder(w.Body).Decode(&result); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
_, err := jwt.Parse(result.Value, func(token *jwt.Token) (interface{}, error) {
|
_, err := jwt.Parse(result.Value, func(token *jwt.Token) (interface{}, error) {
|
||||||
return []byte(mockUser.Salt), nil
|
return []byte(mockUser.Salt), nil
|
||||||
|
@ -56,7 +56,7 @@ func TestUpdate(t *testing.T) {
|
|||||||
users.EXPECT().Update(gomock.Any(), before)
|
users.EXPECT().Update(gomock.Any(), before)
|
||||||
|
|
||||||
in := new(bytes.Buffer)
|
in := new(bytes.Buffer)
|
||||||
json.NewEncoder(in).Encode(userInput)
|
_ = json.NewEncoder(in).Encode(userInput)
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
r := httptest.NewRequest("PATCH", "/api/v1/user", in)
|
r := httptest.NewRequest("PATCH", "/api/v1/user", in)
|
||||||
r = r.WithContext(
|
r = r.WithContext(
|
||||||
@ -81,7 +81,9 @@ func TestUpdate(t *testing.T) {
|
|||||||
// Password hash is not exposecd to JSON
|
// Password hash is not exposecd to JSON
|
||||||
}
|
}
|
||||||
got, want := new(types.User), after
|
got, want := new(types.User), after
|
||||||
json.NewDecoder(w.Body).Decode(got)
|
if err := json.NewDecoder(w.Body).Decode(got); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
if diff := cmp.Diff(got, want); len(diff) != 0 {
|
if diff := cmp.Diff(got, want); len(diff) != 0 {
|
||||||
t.Errorf(diff)
|
t.Errorf(diff)
|
||||||
}
|
}
|
||||||
@ -108,7 +110,7 @@ func TestUpdate_HashError(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
in := new(bytes.Buffer)
|
in := new(bytes.Buffer)
|
||||||
json.NewEncoder(in).Encode(userInput)
|
_ = json.NewEncoder(in).Encode(userInput)
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
r := httptest.NewRequest("PATCH", "/api/v1/user", in)
|
r := httptest.NewRequest("PATCH", "/api/v1/user", in)
|
||||||
r = r.WithContext(
|
r = r.WithContext(
|
||||||
@ -121,7 +123,9 @@ func TestUpdate_HashError(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
got := new(render.Error)
|
got := new(render.Error)
|
||||||
json.NewDecoder(w.Body).Decode(got)
|
if err := json.NewDecoder(w.Body).Decode(got); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
if diff := cmp.Diff(got.Message, render.ErrInternal.Message); len(diff) != 0 {
|
if diff := cmp.Diff(got.Message, render.ErrInternal.Message); len(diff) != 0 {
|
||||||
t.Errorf(diff)
|
t.Errorf(diff)
|
||||||
}
|
}
|
||||||
@ -152,7 +156,9 @@ func TestUpdate_BadRequest(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
got := new(render.Error)
|
got := new(render.Error)
|
||||||
json.NewDecoder(w.Body).Decode(got)
|
if err := json.NewDecoder(w.Body).Decode(got); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
if diff := cmp.Diff(got.Message, "Invalid request body: EOF."); len(diff) != 0 {
|
if diff := cmp.Diff(got.Message, "Invalid request body: EOF."); len(diff) != 0 {
|
||||||
t.Errorf(diff)
|
t.Errorf(diff)
|
||||||
}
|
}
|
||||||
@ -176,7 +182,7 @@ func TestUpdate_ServerError(t *testing.T) {
|
|||||||
users.EXPECT().Update(gomock.Any(), user).Return(render.ErrNotFound)
|
users.EXPECT().Update(gomock.Any(), user).Return(render.ErrNotFound)
|
||||||
|
|
||||||
in := new(bytes.Buffer)
|
in := new(bytes.Buffer)
|
||||||
json.NewEncoder(in).Encode(userInput)
|
_ = json.NewEncoder(in).Encode(userInput)
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
r := httptest.NewRequest("PATCH", "/api/v1/user", in)
|
r := httptest.NewRequest("PATCH", "/api/v1/user", in)
|
||||||
r = r.WithContext(
|
r = r.WithContext(
|
||||||
@ -189,7 +195,9 @@ func TestUpdate_ServerError(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
got, want := new(render.Error), render.ErrInternal
|
got, want := new(render.Error), render.ErrInternal
|
||||||
json.NewDecoder(w.Body).Decode(got)
|
if err := json.NewDecoder(w.Body).Decode(got); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
if diff := cmp.Diff(got, want); len(diff) != 0 {
|
if diff := cmp.Diff(got, want); len(diff) != 0 {
|
||||||
t.Errorf(diff)
|
t.Errorf(diff)
|
||||||
}
|
}
|
||||||
|
@ -32,19 +32,19 @@ func buildAccount(reflector *openapi3.Reflector) {
|
|||||||
onLogin := openapi3.Operation{}
|
onLogin := openapi3.Operation{}
|
||||||
onLogin.WithTags("account")
|
onLogin.WithTags("account")
|
||||||
onLogin.WithMapOfAnything(map[string]interface{}{"operationId": "onLogin"})
|
onLogin.WithMapOfAnything(map[string]interface{}{"operationId": "onLogin"})
|
||||||
reflector.SetRequest(&onLogin, new(loginRequest), http.MethodPost)
|
_ = reflector.SetRequest(&onLogin, new(loginRequest), http.MethodPost)
|
||||||
reflector.SetJSONResponse(&onLogin, new(types.Token), http.StatusOK)
|
_ = reflector.SetJSONResponse(&onLogin, new(types.Token), http.StatusOK)
|
||||||
reflector.SetJSONResponse(&onLogin, new(render.Error), http.StatusBadRequest)
|
_ = reflector.SetJSONResponse(&onLogin, new(render.Error), http.StatusBadRequest)
|
||||||
reflector.SetJSONResponse(&onLogin, new(render.Error), http.StatusInternalServerError)
|
_ = reflector.SetJSONResponse(&onLogin, new(render.Error), http.StatusInternalServerError)
|
||||||
reflector.SetJSONResponse(&onLogin, new(render.Error), http.StatusNotFound)
|
_ = reflector.SetJSONResponse(&onLogin, new(render.Error), http.StatusNotFound)
|
||||||
reflector.Spec.AddOperation(http.MethodPost, "/login", onLogin)
|
_ = reflector.Spec.AddOperation(http.MethodPost, "/login", onLogin)
|
||||||
|
|
||||||
onRegister := openapi3.Operation{}
|
onRegister := openapi3.Operation{}
|
||||||
onRegister.WithTags("account")
|
onRegister.WithTags("account")
|
||||||
onRegister.WithMapOfAnything(map[string]interface{}{"operationId": "onRegister"})
|
onRegister.WithMapOfAnything(map[string]interface{}{"operationId": "onRegister"})
|
||||||
reflector.SetRequest(&onRegister, new(registerRequest), http.MethodPost)
|
_ = reflector.SetRequest(&onRegister, new(registerRequest), http.MethodPost)
|
||||||
reflector.SetJSONResponse(&onRegister, new(types.Token), http.StatusOK)
|
_ = reflector.SetJSONResponse(&onRegister, new(types.Token), http.StatusOK)
|
||||||
reflector.SetJSONResponse(&onRegister, new(render.Error), http.StatusInternalServerError)
|
_ = reflector.SetJSONResponse(&onRegister, new(render.Error), http.StatusInternalServerError)
|
||||||
reflector.SetJSONResponse(&onRegister, new(render.Error), http.StatusBadRequest)
|
_ = reflector.SetJSONResponse(&onRegister, new(render.Error), http.StatusBadRequest)
|
||||||
reflector.Spec.AddOperation(http.MethodPost, "/register", onRegister)
|
_ = reflector.Spec.AddOperation(http.MethodPost, "/register", onRegister)
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,6 @@
|
|||||||
package openapi
|
package openapi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/harness/gitness/version"
|
"github.com/harness/gitness/version"
|
||||||
|
|
||||||
"github.com/swaggest/openapi-go/openapi3"
|
"github.com/swaggest/openapi-go/openapi3"
|
||||||
@ -29,37 +25,38 @@ type (
|
|||||||
Size int `query:"per_page" default:"100"`
|
Size int `query:"per_page" default:"100"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// base response for pagination
|
// TODO: base response for pagination
|
||||||
paginationResponse struct {
|
//paginationResponse struct {
|
||||||
Total int `header:"x-total"`
|
// Total int `header:"x-total"`
|
||||||
Pagelen int `header:"x-total-pages"`
|
// Pagelen int `header:"x-total-pages"`
|
||||||
Page int `header:"x-page"`
|
// Page int `header:"x-page"`
|
||||||
Size int `header:"x-per-page"`
|
// Size int `header:"x-per-page"`
|
||||||
Next int `header:"x-next"`
|
// Next int `header:"x-next"`
|
||||||
Prev int `header:"x-prev"`
|
// Prev int `header:"x-prev"`
|
||||||
Link []string `header:"Link"`
|
// Link []string `header:"Link"`
|
||||||
}
|
//}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Handler returns an http.HandlerFunc that writes the openapi v3
|
// Handler returns an http.HandlerFunc that writes the openapi v3
|
||||||
// specification file to the http.Response body.
|
// specification file to the http.Response body.
|
||||||
func Handler() http.HandlerFunc {
|
// TODO: unused function
|
||||||
spec := Generate()
|
//func Handler() http.HandlerFunc {
|
||||||
yaml, _ := spec.MarshalYAML()
|
// spec := Generate()
|
||||||
json, _ := spec.MarshalJSON()
|
// yaml, _ := spec.MarshalYAML()
|
||||||
|
// json, _ := spec.MarshalJSON()
|
||||||
yaml = normalize(yaml)
|
//
|
||||||
json = normalize(json)
|
// yaml = normalize(yaml)
|
||||||
|
// json = normalize(json)
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
//
|
||||||
switch {
|
// return func(w http.ResponseWriter, r *http.Request) {
|
||||||
case strings.HasSuffix(r.URL.Path, ".json"):
|
// switch {
|
||||||
w.Write(json)
|
// case strings.HasSuffix(r.URL.Path, ".json"):
|
||||||
default:
|
// w.Write(json)
|
||||||
w.Write(yaml)
|
// default:
|
||||||
}
|
// w.Write(yaml)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
// Generate is a helper function that constructs the
|
// Generate is a helper function that constructs the
|
||||||
// openapi specification object, which can be marshaled
|
// openapi specification object, which can be marshaled
|
||||||
@ -108,10 +105,11 @@ func Generate() *openapi3.Spec {
|
|||||||
|
|
||||||
// helper function normalizes the output to ensure
|
// helper function normalizes the output to ensure
|
||||||
// automatically-generated names are more user friendly.
|
// automatically-generated names are more user friendly.
|
||||||
func normalize(data []byte) []byte {
|
// TODO: unused function
|
||||||
data = bytes.ReplaceAll(data, []byte("Types"), []byte(""))
|
//func normalize(data []byte) []byte {
|
||||||
data = bytes.ReplaceAll(data, []byte("Openapi"), []byte(""))
|
// data = bytes.ReplaceAll(data, []byte("Types"), []byte(""))
|
||||||
data = bytes.ReplaceAll(data, []byte("FormData"), []byte(""))
|
// data = bytes.ReplaceAll(data, []byte("Openapi"), []byte(""))
|
||||||
data = bytes.ReplaceAll(data, []byte("RenderError"), []byte("Error"))
|
// data = bytes.ReplaceAll(data, []byte("FormData"), []byte(""))
|
||||||
return data
|
// data = bytes.ReplaceAll(data, []byte("RenderError"), []byte("Error"))
|
||||||
}
|
// return data
|
||||||
|
//}
|
||||||
|
@ -25,32 +25,32 @@ func buildUser(reflector *openapi3.Reflector) {
|
|||||||
opFind := openapi3.Operation{}
|
opFind := openapi3.Operation{}
|
||||||
opFind.WithTags("user")
|
opFind.WithTags("user")
|
||||||
opFind.WithMapOfAnything(map[string]interface{}{"operationId": "getUser"})
|
opFind.WithMapOfAnything(map[string]interface{}{"operationId": "getUser"})
|
||||||
reflector.SetRequest(&opFind, nil, http.MethodGet)
|
_ = reflector.SetRequest(&opFind, nil, http.MethodGet)
|
||||||
reflector.SetJSONResponse(&opFind, new(types.User), http.StatusOK)
|
_ = reflector.SetJSONResponse(&opFind, new(types.User), http.StatusOK)
|
||||||
reflector.SetJSONResponse(&opFind, new(render.Error), http.StatusInternalServerError)
|
_ = reflector.SetJSONResponse(&opFind, new(render.Error), http.StatusInternalServerError)
|
||||||
reflector.Spec.AddOperation(http.MethodGet, "/user", opFind)
|
_ = reflector.Spec.AddOperation(http.MethodGet, "/user", opFind)
|
||||||
|
|
||||||
opUpdate := openapi3.Operation{}
|
opUpdate := openapi3.Operation{}
|
||||||
opUpdate.WithTags("user")
|
opUpdate.WithTags("user")
|
||||||
opUpdate.WithMapOfAnything(map[string]interface{}{"operationId": "updateUser"})
|
opUpdate.WithMapOfAnything(map[string]interface{}{"operationId": "updateUser"})
|
||||||
reflector.SetRequest(&opUpdate, new(types.UserInput), http.MethodPatch)
|
_ = reflector.SetRequest(&opUpdate, new(types.UserInput), http.MethodPatch)
|
||||||
reflector.SetJSONResponse(&opUpdate, new(types.User), http.StatusOK)
|
_ = reflector.SetJSONResponse(&opUpdate, new(types.User), http.StatusOK)
|
||||||
reflector.SetJSONResponse(&opUpdate, new(render.Error), http.StatusInternalServerError)
|
_ = reflector.SetJSONResponse(&opUpdate, new(render.Error), http.StatusInternalServerError)
|
||||||
reflector.Spec.AddOperation(http.MethodPatch, "/user", opUpdate)
|
_ = reflector.Spec.AddOperation(http.MethodPatch, "/user", opUpdate)
|
||||||
|
|
||||||
opToken := openapi3.Operation{}
|
opToken := openapi3.Operation{}
|
||||||
opToken.WithTags("user")
|
opToken.WithTags("user")
|
||||||
opToken.WithMapOfAnything(map[string]interface{}{"operationId": "createToken"})
|
opToken.WithMapOfAnything(map[string]interface{}{"operationId": "createToken"})
|
||||||
reflector.SetRequest(&opToken, new(types.Token), http.MethodPost)
|
_ = reflector.SetRequest(&opToken, new(types.Token), http.MethodPost)
|
||||||
reflector.SetJSONResponse(&opToken, new(types.User), http.StatusOK)
|
_ = reflector.SetJSONResponse(&opToken, new(types.User), http.StatusOK)
|
||||||
reflector.SetJSONResponse(&opToken, new(render.Error), http.StatusInternalServerError)
|
_ = reflector.SetJSONResponse(&opToken, new(render.Error), http.StatusInternalServerError)
|
||||||
reflector.Spec.AddOperation(http.MethodPost, "/user/token", opToken)
|
_ = reflector.Spec.AddOperation(http.MethodPost, "/user/token", opToken)
|
||||||
|
|
||||||
opCurrent := openapi3.Operation{}
|
opCurrent := openapi3.Operation{}
|
||||||
opCurrent.WithTags("user")
|
opCurrent.WithTags("user")
|
||||||
opCurrent.WithMapOfAnything(map[string]interface{}{"operationId": "getCurrentUser"})
|
opCurrent.WithMapOfAnything(map[string]interface{}{"operationId": "getCurrentUser"})
|
||||||
reflector.SetRequest(&opFind, new(baseRequest), http.MethodGet)
|
_ = reflector.SetRequest(&opFind, new(baseRequest), http.MethodGet)
|
||||||
reflector.SetJSONResponse(&opCurrent, new(currentUserResponse), http.StatusOK)
|
_ = reflector.SetJSONResponse(&opCurrent, new(currentUserResponse), http.StatusOK)
|
||||||
reflector.SetJSONResponse(&opCurrent, new(render.Error), http.StatusInternalServerError)
|
_ = reflector.SetJSONResponse(&opCurrent, new(render.Error), http.StatusInternalServerError)
|
||||||
reflector.Spec.AddOperation(http.MethodGet, "/api/user/currentUser", opCurrent)
|
_ = reflector.Spec.AddOperation(http.MethodGet, "/api/user/currentUser", opCurrent)
|
||||||
}
|
}
|
||||||
|
@ -44,49 +44,49 @@ func buildUsers(reflector *openapi3.Reflector) {
|
|||||||
opFind := openapi3.Operation{}
|
opFind := openapi3.Operation{}
|
||||||
opFind.WithTags("users")
|
opFind.WithTags("users")
|
||||||
opFind.WithMapOfAnything(map[string]interface{}{"operationId": "getUserEmail"})
|
opFind.WithMapOfAnything(map[string]interface{}{"operationId": "getUserEmail"})
|
||||||
reflector.SetRequest(&opFind, new(userRequest), http.MethodGet)
|
_ = reflector.SetRequest(&opFind, new(userRequest), http.MethodGet)
|
||||||
reflector.SetJSONResponse(&opFind, new(types.User), http.StatusOK)
|
_ = reflector.SetJSONResponse(&opFind, new(types.User), http.StatusOK)
|
||||||
reflector.SetJSONResponse(&opFind, new(render.Error), http.StatusBadRequest)
|
_ = reflector.SetJSONResponse(&opFind, new(render.Error), http.StatusBadRequest)
|
||||||
reflector.SetJSONResponse(&opFind, new(render.Error), http.StatusInternalServerError)
|
_ = reflector.SetJSONResponse(&opFind, new(render.Error), http.StatusInternalServerError)
|
||||||
reflector.SetJSONResponse(&opFind, new(render.Error), http.StatusNotFound)
|
_ = reflector.SetJSONResponse(&opFind, new(render.Error), http.StatusNotFound)
|
||||||
reflector.Spec.AddOperation(http.MethodGet, "/users/{email}", opFind)
|
_ = reflector.Spec.AddOperation(http.MethodGet, "/users/{email}", opFind)
|
||||||
|
|
||||||
opList := openapi3.Operation{}
|
opList := openapi3.Operation{}
|
||||||
opList.WithTags("users")
|
opList.WithTags("users")
|
||||||
opList.WithMapOfAnything(map[string]interface{}{"operationId": "listUsers"})
|
opList.WithMapOfAnything(map[string]interface{}{"operationId": "listUsers"})
|
||||||
reflector.SetRequest(&opList, new(userListRequest), http.MethodGet)
|
_ = reflector.SetRequest(&opList, new(userListRequest), http.MethodGet)
|
||||||
reflector.SetJSONResponse(&opList, new([]*types.User), http.StatusOK)
|
_ = reflector.SetJSONResponse(&opList, new([]*types.User), http.StatusOK)
|
||||||
reflector.SetJSONResponse(&opList, new(render.Error), http.StatusBadRequest)
|
_ = reflector.SetJSONResponse(&opList, new(render.Error), http.StatusBadRequest)
|
||||||
reflector.SetJSONResponse(&opList, new(render.Error), http.StatusInternalServerError)
|
_ = reflector.SetJSONResponse(&opList, new(render.Error), http.StatusInternalServerError)
|
||||||
reflector.SetJSONResponse(&opList, new(render.Error), http.StatusNotFound)
|
_ = reflector.SetJSONResponse(&opList, new(render.Error), http.StatusNotFound)
|
||||||
reflector.Spec.AddOperation(http.MethodGet, "/users", opList)
|
_ = reflector.Spec.AddOperation(http.MethodGet, "/users", opList)
|
||||||
|
|
||||||
opCreate := openapi3.Operation{}
|
opCreate := openapi3.Operation{}
|
||||||
opCreate.WithTags("users")
|
opCreate.WithTags("users")
|
||||||
opCreate.WithMapOfAnything(map[string]interface{}{"operationId": "createUser"})
|
opCreate.WithMapOfAnything(map[string]interface{}{"operationId": "createUser"})
|
||||||
reflector.SetRequest(&opCreate, new(types.UserInput), http.MethodPost)
|
_ = reflector.SetRequest(&opCreate, new(types.UserInput), http.MethodPost)
|
||||||
reflector.SetJSONResponse(&opCreate, new(types.User), http.StatusOK)
|
_ = reflector.SetJSONResponse(&opCreate, new(types.User), http.StatusOK)
|
||||||
reflector.SetJSONResponse(&opCreate, new(render.Error), http.StatusBadRequest)
|
_ = reflector.SetJSONResponse(&opCreate, new(render.Error), http.StatusBadRequest)
|
||||||
reflector.SetJSONResponse(&opCreate, new(render.Error), http.StatusInternalServerError)
|
_ = reflector.SetJSONResponse(&opCreate, new(render.Error), http.StatusInternalServerError)
|
||||||
reflector.SetJSONResponse(&opCreate, new(render.Error), http.StatusNotFound)
|
_ = reflector.SetJSONResponse(&opCreate, new(render.Error), http.StatusNotFound)
|
||||||
reflector.Spec.AddOperation(http.MethodPost, "/users", opCreate)
|
_ = reflector.Spec.AddOperation(http.MethodPost, "/users", opCreate)
|
||||||
|
|
||||||
opUpdate := openapi3.Operation{}
|
opUpdate := openapi3.Operation{}
|
||||||
opUpdate.WithTags("users")
|
opUpdate.WithTags("users")
|
||||||
opUpdate.WithMapOfAnything(map[string]interface{}{"operationId": "updateUsers"})
|
opUpdate.WithMapOfAnything(map[string]interface{}{"operationId": "updateUsers"})
|
||||||
reflector.SetRequest(&opUpdate, new(userUpdateRequest), http.MethodPatch)
|
_ = reflector.SetRequest(&opUpdate, new(userUpdateRequest), http.MethodPatch)
|
||||||
reflector.SetJSONResponse(&opUpdate, new(types.User), http.StatusOK)
|
_ = reflector.SetJSONResponse(&opUpdate, new(types.User), http.StatusOK)
|
||||||
reflector.SetJSONResponse(&opUpdate, new(render.Error), http.StatusBadRequest)
|
_ = reflector.SetJSONResponse(&opUpdate, new(render.Error), http.StatusBadRequest)
|
||||||
reflector.SetJSONResponse(&opUpdate, new(render.Error), http.StatusInternalServerError)
|
_ = reflector.SetJSONResponse(&opUpdate, new(render.Error), http.StatusInternalServerError)
|
||||||
reflector.SetJSONResponse(&opUpdate, new(render.Error), http.StatusNotFound)
|
_ = reflector.SetJSONResponse(&opUpdate, new(render.Error), http.StatusNotFound)
|
||||||
reflector.Spec.AddOperation(http.MethodPatch, "/users/{email}", opUpdate)
|
_ = reflector.Spec.AddOperation(http.MethodPatch, "/users/{email}", opUpdate)
|
||||||
|
|
||||||
opDelete := openapi3.Operation{}
|
opDelete := openapi3.Operation{}
|
||||||
opDelete.WithTags("users")
|
opDelete.WithTags("users")
|
||||||
opDelete.WithMapOfAnything(map[string]interface{}{"operationId": "deleteUser"})
|
opDelete.WithMapOfAnything(map[string]interface{}{"operationId": "deleteUser"})
|
||||||
reflector.SetRequest(&opDelete, new(userRequest), http.MethodDelete)
|
_ = reflector.SetRequest(&opDelete, new(userRequest), http.MethodDelete)
|
||||||
reflector.SetJSONResponse(&opDelete, nil, http.StatusNoContent)
|
_ = reflector.SetJSONResponse(&opDelete, nil, http.StatusNoContent)
|
||||||
reflector.SetJSONResponse(&opDelete, new(render.Error), http.StatusInternalServerError)
|
_ = reflector.SetJSONResponse(&opDelete, new(render.Error), http.StatusInternalServerError)
|
||||||
reflector.SetJSONResponse(&opDelete, new(render.Error), http.StatusNotFound)
|
_ = reflector.SetJSONResponse(&opDelete, new(render.Error), http.StatusNotFound)
|
||||||
reflector.Spec.AddOperation(http.MethodDelete, "/users/{email}", opDelete)
|
_ = reflector.Spec.AddOperation(http.MethodDelete, "/users/{email}", opDelete)
|
||||||
}
|
}
|
||||||
|
@ -104,10 +104,12 @@ func ErrorObject(w http.ResponseWriter, code int, err *Error) {
|
|||||||
func JSON(w http.ResponseWriter, code int, v interface{}) {
|
func JSON(w http.ResponseWriter, code int, v interface{}) {
|
||||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
w.Header().Set("X-Content-Type-Options", "nosniff")
|
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||||
w.WriteHeader(code)
|
|
||||||
enc := json.NewEncoder(w)
|
enc := json.NewEncoder(w)
|
||||||
if indent {
|
if indent { // is this necessary? it will affect performance
|
||||||
enc.SetIndent("", " ")
|
enc.SetIndent("", " ")
|
||||||
}
|
}
|
||||||
enc.Encode(v)
|
if err := enc.Encode(v); err != nil {
|
||||||
|
code = http.StatusInternalServerError
|
||||||
|
}
|
||||||
|
w.WriteHeader(code)
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,9 @@ func TestWriteErrorf(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
errjson := &Error{}
|
errjson := &Error{}
|
||||||
json.NewDecoder(w.Body).Decode(errjson)
|
if err := json.NewDecoder(w.Body).Decode(errjson); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
if got, want := errjson.Message, e.Message; got != want {
|
if got, want := errjson.Message, e.Message; got != want {
|
||||||
t.Errorf("Want error message %s, got %s", want, got)
|
t.Errorf("Want error message %s, got %s", want, got)
|
||||||
}
|
}
|
||||||
@ -38,7 +40,9 @@ func TestWriteErrorCode(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
errjson := &Error{}
|
errjson := &Error{}
|
||||||
json.NewDecoder(w.Body).Decode(errjson)
|
if err := json.NewDecoder(w.Body).Decode(errjson); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
if got, want := errjson.Message, "pc load letter 1"; got != want {
|
if got, want := errjson.Message, "pc load letter 1"; got != want {
|
||||||
t.Errorf("Want error message %s, got %s", want, got)
|
t.Errorf("Want error message %s, got %s", want, got)
|
||||||
}
|
}
|
||||||
@ -54,7 +58,9 @@ func TestWriteNotFound(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
errjson := &Error{}
|
errjson := &Error{}
|
||||||
json.NewDecoder(w.Body).Decode(errjson)
|
if err := json.NewDecoder(w.Body).Decode(errjson); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
if got, want := errjson.Message, ErrNotFound.Message; got != want {
|
if got, want := errjson.Message, ErrNotFound.Message; got != want {
|
||||||
t.Errorf("Want error message %s, got %s", want, got)
|
t.Errorf("Want error message %s, got %s", want, got)
|
||||||
}
|
}
|
||||||
@ -70,7 +76,9 @@ func TestWriteUnauthorized(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
errjson := &Error{}
|
errjson := &Error{}
|
||||||
json.NewDecoder(w.Body).Decode(errjson)
|
if err := json.NewDecoder(w.Body).Decode(errjson); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
if got, want := errjson.Message, ErrUnauthorized.Message; got != want {
|
if got, want := errjson.Message, ErrUnauthorized.Message; got != want {
|
||||||
t.Errorf("Want error message %s, got %s", want, got)
|
t.Errorf("Want error message %s, got %s", want, got)
|
||||||
}
|
}
|
||||||
@ -86,7 +94,9 @@ func TestWriteForbidden(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
errjson := &Error{}
|
errjson := &Error{}
|
||||||
json.NewDecoder(w.Body).Decode(errjson)
|
if err := json.NewDecoder(w.Body).Decode(errjson); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
if got, want := errjson.Message, ErrForbidden.Message; got != want {
|
if got, want := errjson.Message, ErrForbidden.Message; got != want {
|
||||||
t.Errorf("Want error message %s, got %s", want, got)
|
t.Errorf("Want error message %s, got %s", want, got)
|
||||||
}
|
}
|
||||||
@ -102,7 +112,9 @@ func TestWriteBadRequest(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
errjson := &Error{}
|
errjson := &Error{}
|
||||||
json.NewDecoder(w.Body).Decode(errjson)
|
if err := json.NewDecoder(w.Body).Decode(errjson); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
if got, want := errjson.Message, ErrBadRequest.Message; got != want {
|
if got, want := errjson.Message, ErrBadRequest.Message; got != want {
|
||||||
t.Errorf("Want error message %s, got %s", want, got)
|
t.Errorf("Want error message %s, got %s", want, got)
|
||||||
}
|
}
|
||||||
@ -116,7 +128,7 @@ func TestWriteJSON(t *testing.T) {
|
|||||||
if got, want := w.Body.String(), "{\"hello\":\"world\"}\n"; got != want {
|
if got, want := w.Body.String(), "{\"hello\":\"world\"}\n"; got != want {
|
||||||
t.Errorf("Want JSON body %q, got %q", want, got)
|
t.Errorf("Want JSON body %q, got %q", want, got)
|
||||||
}
|
}
|
||||||
if got, want := w.HeaderMap.Get("Content-Type"), "application/json; charset=utf-8"; got != want {
|
if got, want := w.Header().Get("Content-Type"), "application/json; charset=utf-8"; got != want {
|
||||||
t.Errorf("Want Content-Type %q, got %q", want, got)
|
t.Errorf("Want Content-Type %q, got %q", want, got)
|
||||||
}
|
}
|
||||||
if got, want := w.Code, http.StatusTeapot; got != want {
|
if got, want := w.Code, http.StatusTeapot; got != want {
|
||||||
|
@ -64,7 +64,7 @@ func (a *TokenAuthenticator) Authenticate(r *http.Request) (*types.User, error)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if parsed.Valid == false {
|
if !parsed.Valid {
|
||||||
return nil, errors.New("Invalid token")
|
return nil, errors.New("Invalid token")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,5 +36,5 @@ type Authorizer interface {
|
|||||||
* (false, nil) - the principal does not have permission to perform all the actions (at least one is not allowed)
|
* (false, nil) - the principal does not have permission to perform all the actions (at least one is not allowed)
|
||||||
* (false, err) - an error occured while performing the permission check and all actions should be denied
|
* (false, err) - an error occured while performing the permission check and all actions should be denied
|
||||||
*/
|
*/
|
||||||
CheckAll(principalType enum.PrincipalType, principalId string, permissionChecks ...*types.PermissionCheck) (bool, error)
|
CheckAll(principalType enum.PrincipalType, principalId string, permissionChecks ...types.PermissionCheck) (bool, error)
|
||||||
}
|
}
|
||||||
|
@ -42,15 +42,18 @@ func NewAuthorizer(aclEndpoint, authToken string) (authz.Authorizer, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *Authorizer) Check(principalType enum.PrincipalType, principalId string, scope *types.Scope, resource *types.Resource, permission enum.Permission) (bool, error) {
|
func (a *Authorizer) Check(principalType enum.PrincipalType, principalId string, scope *types.Scope, resource *types.Resource, permission enum.Permission) (bool, error) {
|
||||||
return a.CheckAll(principalType, principalId, &types.PermissionCheck{Scope: *scope, Resource: *resource, Permission: permission})
|
return a.CheckAll(principalType, principalId, types.PermissionCheck{Scope: *scope, Resource: *resource, Permission: permission})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Authorizer) CheckAll(principalType enum.PrincipalType, principalId string, permissionChecks ...*types.PermissionCheck) (bool, error) {
|
func (a *Authorizer) CheckAll(principalType enum.PrincipalType, principalId string, permissionChecks ...types.PermissionCheck) (bool, error) {
|
||||||
if len(permissionChecks) == 0 {
|
if len(permissionChecks) == 0 {
|
||||||
return false, authz.ErrNoPermissionCheckProvided
|
return false, authz.ErrNoPermissionCheckProvided
|
||||||
}
|
}
|
||||||
|
|
||||||
requestDto, err := createAclRequest(principalType, principalId, permissionChecks)
|
requestDto, err := createAclRequest(principalType, principalId, permissionChecks)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
byt, err := json.Marshal(requestDto)
|
byt, err := json.Marshal(requestDto)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
@ -91,7 +94,7 @@ func (a *Authorizer) CheckAll(principalType enum.PrincipalType, principalId stri
|
|||||||
return checkAclResponse(permissionChecks, responseDto)
|
return checkAclResponse(permissionChecks, responseDto)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createAclRequest(principalType enum.PrincipalType, principalId string, permissionChecks []*types.PermissionCheck) (*aclRequest, error) {
|
func createAclRequest(principalType enum.PrincipalType, principalId string, permissionChecks []types.PermissionCheck) (*aclRequest, error) {
|
||||||
// Generate ACL req
|
// Generate ACL req
|
||||||
req := aclRequest{
|
req := aclRequest{
|
||||||
Permissions: []aclPermission{},
|
Permissions: []aclPermission{},
|
||||||
@ -123,7 +126,7 @@ func createAclRequest(principalType enum.PrincipalType, principalId string, perm
|
|||||||
return &req, nil
|
return &req, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkAclResponse(permissionChecks []*types.PermissionCheck, responseDto aclResponse) (bool, error) {
|
func checkAclResponse(permissionChecks []types.PermissionCheck, responseDto aclResponse) (bool, error) {
|
||||||
/*
|
/*
|
||||||
* We are assuming two things:
|
* We are assuming two things:
|
||||||
* - All permission checks were made for the same principal.
|
* - All permission checks were made for the same principal.
|
||||||
|
@ -35,9 +35,11 @@ func (a *UnsafeAuthorizer) Check(principalType enum.PrincipalType, principalId s
|
|||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
func (a *UnsafeAuthorizer) CheckAll(principalType enum.PrincipalType, principalId string, permissionChecks ...*types.PermissionCheck) (bool, error) {
|
func (a *UnsafeAuthorizer) CheckAll(principalType enum.PrincipalType, principalId string, permissionChecks ...types.PermissionCheck) (bool, error) {
|
||||||
for _, p := range permissionChecks {
|
for _, p := range permissionChecks {
|
||||||
a.Check(principalType, principalId, &p.Scope, &p.Resource, p.Permission)
|
if _, err := a.Check(principalType, principalId, &p.Scope, &p.Resource, p.Permission); err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
|
@ -11,9 +11,6 @@ import (
|
|||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// helper function returns the current time.
|
|
||||||
var now = time.Now
|
|
||||||
|
|
||||||
// Nightly is a sub-routine that periodically purges historical data.
|
// Nightly is a sub-routine that periodically purges historical data.
|
||||||
type Nightly struct {
|
type Nightly struct {
|
||||||
// Inject required stores here
|
// Inject required stores here
|
||||||
|
@ -174,16 +174,16 @@ func setupRoutesV1(
|
|||||||
|
|
||||||
r.Route("/{user}", func(r chi.Router) {
|
r.Route("/{user}", func(r chi.Router) {
|
||||||
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
|
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Write([]byte(fmt.Sprintf("Get user '%s'", chi.URLParam(r, "rref"))))
|
_, _ = w.Write([]byte(fmt.Sprintf("Get user '%s'", chi.URLParam(r, "rref"))))
|
||||||
})
|
})
|
||||||
r.Post("/", func(w http.ResponseWriter, r *http.Request) {
|
r.Post("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Write([]byte(fmt.Sprintf("Create user '%s'", chi.URLParam(r, "rref"))))
|
_, _ = w.Write([]byte(fmt.Sprintf("Create user '%s'", chi.URLParam(r, "rref"))))
|
||||||
})
|
})
|
||||||
r.Put("/", func(w http.ResponseWriter, r *http.Request) {
|
r.Put("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Write([]byte(fmt.Sprintf("Update user '%s'", chi.URLParam(r, "rref"))))
|
_, _ = w.Write([]byte(fmt.Sprintf("Update user '%s'", chi.URLParam(r, "rref"))))
|
||||||
})
|
})
|
||||||
r.Delete("/", func(w http.ResponseWriter, r *http.Request) {
|
r.Delete("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Write([]byte(fmt.Sprintf("Delete user '%s'", chi.URLParam(r, "rref"))))
|
_, _ = w.Write([]byte(fmt.Sprintf("Delete user '%s'", chi.URLParam(r, "rref"))))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -92,7 +92,7 @@ func stubGitHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
rep, _ := request.RepoFrom(r.Context())
|
rep, _ := request.RepoFrom(r.Context())
|
||||||
|
|
||||||
w.WriteHeader(http.StatusTeapot)
|
w.WriteHeader(http.StatusTeapot)
|
||||||
w.Write([]byte(fmt.Sprintf(
|
_, _ = w.Write([]byte(fmt.Sprintf(
|
||||||
"Oooops, seems you hit a major construction site ... \n"+
|
"Oooops, seems you hit a major construction site ... \n"+
|
||||||
" Repo: '%s' (%s)\n"+
|
" Repo: '%s' (%s)\n"+
|
||||||
" Method: '%s'\n"+
|
" Method: '%s'\n"+
|
||||||
|
@ -41,10 +41,8 @@ func (s *Server) listenAndServe(ctx context.Context) error {
|
|||||||
Handler: s.Handler,
|
Handler: s.Handler,
|
||||||
}
|
}
|
||||||
g.Go(func() error {
|
g.Go(func() error {
|
||||||
select {
|
<-ctx.Done()
|
||||||
case <-ctx.Done():
|
return s1.Shutdown(ctx)
|
||||||
return s1.Shutdown(ctx)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
g.Go(func() error {
|
g.Go(func() error {
|
||||||
return s1.ListenAndServe()
|
return s1.ListenAndServe()
|
||||||
@ -72,12 +70,14 @@ func (s *Server) listenAndServeTLS(ctx context.Context) error {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
g.Go(func() error {
|
g.Go(func() error {
|
||||||
select {
|
<-ctx.Done()
|
||||||
case <-ctx.Done():
|
if err := s1.Shutdown(ctx); err != nil {
|
||||||
s1.Shutdown(ctx)
|
return err
|
||||||
s2.Shutdown(ctx)
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
if err := s2.Shutdown(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
return g.Wait()
|
return g.Wait()
|
||||||
}
|
}
|
||||||
@ -108,12 +108,14 @@ func (s Server) listenAndServeAcme(ctx context.Context) error {
|
|||||||
return s2.ListenAndServeTLS("", "")
|
return s2.ListenAndServeTLS("", "")
|
||||||
})
|
})
|
||||||
g.Go(func() error {
|
g.Go(func() error {
|
||||||
select {
|
<-ctx.Done()
|
||||||
case <-ctx.Done():
|
if err := s1.Shutdown(ctx); err != nil {
|
||||||
s1.Shutdown(ctx)
|
return err
|
||||||
s2.Shutdown(ctx)
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
if err := s2.Shutdown(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
return g.Wait()
|
return g.Wait()
|
||||||
}
|
}
|
||||||
|
@ -199,14 +199,15 @@ func DeletePath(ctx context.Context, db *sqlx.DB, id int64) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return processSqlErrorf(err, "Failed to start a new transaction")
|
return processSqlErrorf(err, "Failed to start a new transaction")
|
||||||
}
|
}
|
||||||
defer tx.Rollback()
|
defer func(tx *sqlx.Tx) {
|
||||||
|
_ = tx.Rollback()
|
||||||
|
}(tx)
|
||||||
|
|
||||||
// ensure path is an alias
|
// ensure path is an alias
|
||||||
dst := new(types.Path)
|
dst := new(types.Path)
|
||||||
err = tx.GetContext(ctx, dst, pathSelectId, id)
|
if err = tx.GetContext(ctx, dst, pathSelectId, id); err != nil {
|
||||||
if err != nil {
|
|
||||||
return processSqlErrorf(err, "Failed to find path with id %d", id)
|
return processSqlErrorf(err, "Failed to find path with id %d", id)
|
||||||
} else if dst.IsAlias == false {
|
} else if !dst.IsAlias {
|
||||||
return store.ErrPrimaryPathCantBeDeleted
|
return store.ErrPrimaryPathCantBeDeleted
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,10 +361,6 @@ const pathSelectId = pathBase + `
|
|||||||
WHERE path_id = $1
|
WHERE path_id = $1
|
||||||
`
|
`
|
||||||
|
|
||||||
const pathSelectPath = pathBase + `
|
|
||||||
WHERE path_value = $1
|
|
||||||
`
|
|
||||||
|
|
||||||
const pathDeleteId = `
|
const pathDeleteId = `
|
||||||
DELETE FROM paths
|
DELETE FROM paths
|
||||||
WHERE path_id = $1
|
WHERE path_id = $1
|
||||||
|
@ -54,7 +54,9 @@ func (s *RepoStore) Create(ctx context.Context, repo *types.Repository) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return processSqlErrorf(err, "Failed to start a new transaction")
|
return processSqlErrorf(err, "Failed to start a new transaction")
|
||||||
}
|
}
|
||||||
defer tx.Rollback()
|
defer func(tx *sqlx.Tx) {
|
||||||
|
_ = tx.Rollback()
|
||||||
|
}(tx)
|
||||||
|
|
||||||
// insert repo first so we get id
|
// insert repo first so we get id
|
||||||
query, arg, err := s.db.BindNamed(repoInsert, repo)
|
query, arg, err := s.db.BindNamed(repoInsert, repo)
|
||||||
@ -107,7 +109,9 @@ func (s *RepoStore) Move(ctx context.Context, userId int64, repoId int64, newSpa
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, processSqlErrorf(err, "Failed to start a new transaction")
|
return nil, processSqlErrorf(err, "Failed to start a new transaction")
|
||||||
}
|
}
|
||||||
defer tx.Rollback()
|
defer func(tx *sqlx.Tx) {
|
||||||
|
_ = tx.Rollback() // should we take care about rollbacks errors?
|
||||||
|
}(tx)
|
||||||
|
|
||||||
// get current path of repo
|
// get current path of repo
|
||||||
currentPath, err := FindPathTx(ctx, tx, enum.PathTargetTypeRepo, repoId)
|
currentPath, err := FindPathTx(ctx, tx, enum.PathTargetTypeRepo, repoId)
|
||||||
@ -168,7 +172,7 @@ func (s *RepoStore) Update(ctx context.Context, repo *types.Repository) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if _, err = s.db.ExecContext(ctx, query, arg...); err != nil {
|
if _, err = s.db.ExecContext(ctx, query, arg...); err != nil {
|
||||||
processSqlErrorf(err, "Update query failed")
|
return processSqlErrorf(err, "Update query failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -180,7 +184,9 @@ func (s *RepoStore) Delete(ctx context.Context, id int64) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return processSqlErrorf(err, "Failed to start a new transaction")
|
return processSqlErrorf(err, "Failed to start a new transaction")
|
||||||
}
|
}
|
||||||
defer tx.Rollback()
|
defer func(tx *sqlx.Tx) {
|
||||||
|
_ = tx.Rollback()
|
||||||
|
}(tx)
|
||||||
|
|
||||||
// delete all paths
|
// delete all paths
|
||||||
err = DeleteAllPaths(ctx, tx, enum.PathTargetTypeRepo, id)
|
err = DeleteAllPaths(ctx, tx, enum.PathTargetTypeRepo, id)
|
||||||
|
@ -55,7 +55,9 @@ func (s *SpaceStore) Create(ctx context.Context, space *types.Space) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return processSqlErrorf(err, "Failed to start a new transaction")
|
return processSqlErrorf(err, "Failed to start a new transaction")
|
||||||
}
|
}
|
||||||
defer tx.Rollback()
|
defer func(tx *sqlx.Tx) {
|
||||||
|
_ = tx.Rollback()
|
||||||
|
}(tx)
|
||||||
|
|
||||||
// insert space first so we get id
|
// insert space first so we get id
|
||||||
query, arg, err := s.db.BindNamed(spaceInsert, space)
|
query, arg, err := s.db.BindNamed(spaceInsert, space)
|
||||||
@ -111,7 +113,9 @@ func (s *SpaceStore) Move(ctx context.Context, userId int64, spaceId int64, newP
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, processSqlErrorf(err, "Failed to start a new transaction")
|
return nil, processSqlErrorf(err, "Failed to start a new transaction")
|
||||||
}
|
}
|
||||||
defer tx.Rollback()
|
defer func(tx *sqlx.Tx) {
|
||||||
|
_ = tx.Rollback()
|
||||||
|
}(tx)
|
||||||
|
|
||||||
// always get currentpath (either it didn't change or we need to for validation)
|
// always get currentpath (either it didn't change or we need to for validation)
|
||||||
currentPath, err := FindPathTx(ctx, tx, enum.PathTargetTypeSpace, spaceId)
|
currentPath, err := FindPathTx(ctx, tx, enum.PathTargetTypeSpace, spaceId)
|
||||||
@ -183,7 +187,7 @@ func (s *SpaceStore) Update(ctx context.Context, space *types.Space) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if _, err = s.db.ExecContext(ctx, query, arg...); err != nil {
|
if _, err = s.db.ExecContext(ctx, query, arg...); err != nil {
|
||||||
processSqlErrorf(err, "Update query failed")
|
return processSqlErrorf(err, "Update query failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -195,7 +199,9 @@ func (s *SpaceStore) Delete(ctx context.Context, id int64) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return processSqlErrorf(err, "Failed to start a new transaction")
|
return processSqlErrorf(err, "Failed to start a new transaction")
|
||||||
}
|
}
|
||||||
defer tx.Rollback()
|
defer func(tx *sqlx.Tx) {
|
||||||
|
_ = tx.Rollback()
|
||||||
|
}(tx)
|
||||||
|
|
||||||
// get primary path
|
// get primary path
|
||||||
path, err := FindPathTx(ctx, tx, enum.PathTargetTypeSpace, id)
|
path, err := FindPathTx(ctx, tx, enum.PathTargetTypeSpace, id)
|
||||||
@ -205,9 +211,10 @@ func (s *SpaceStore) Delete(ctx context.Context, id int64) error {
|
|||||||
|
|
||||||
// Get child count and ensure there are none
|
// Get child count and ensure there are none
|
||||||
count, err := CountPrimaryChildPathsTx(ctx, tx, path.Value)
|
count, err := CountPrimaryChildPathsTx(ctx, tx, path.Value)
|
||||||
if err := tx.QueryRow(spaceCount, id).Scan(&count); err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "Failed to count the child paths of the space")
|
return fmt.Errorf("child count error: %w", err)
|
||||||
} else if count > 0 {
|
}
|
||||||
|
if count > 0 {
|
||||||
// TODO: still returns 500
|
// TODO: still returns 500
|
||||||
return store.ErrSpaceWithChildsCantBeDeleted
|
return store.ErrSpaceWithChildsCantBeDeleted
|
||||||
}
|
}
|
||||||
@ -219,7 +226,7 @@ func (s *SpaceStore) Delete(ctx context.Context, id int64) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// delete the space
|
// delete the space
|
||||||
if _, err := tx.Exec(spaceDelete, id); err != nil {
|
if _, err = tx.Exec(spaceDelete, id); err != nil {
|
||||||
return processSqlErrorf(err, "The delete query failed")
|
return processSqlErrorf(err, "The delete query failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,14 +5,11 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/jmoiron/sqlx"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/jmoiron/sqlx"
|
|
||||||
|
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
_ "github.com/mattn/go-sqlite3"
|
_ "github.com/mattn/go-sqlite3"
|
||||||
@ -35,12 +32,12 @@ func connect() (*sqlx.DB, error) {
|
|||||||
|
|
||||||
// seed seed the database state.
|
// seed seed the database state.
|
||||||
func seed(db *sqlx.DB) error {
|
func seed(db *sqlx.DB) error {
|
||||||
db.Exec("DELETE FROM executions")
|
_, _ = db.Exec("DELETE FROM executions")
|
||||||
db.Exec("DELETE FROM pipelines")
|
_, _ = db.Exec("DELETE FROM pipelines")
|
||||||
db.Exec("DELETE FROM users")
|
_, _ = db.Exec("DELETE FROM users")
|
||||||
db.Exec("ALTER SEQUENCE users_user_id_seq RESTART WITH 1")
|
_, _ = db.Exec("ALTER SEQUENCE users_user_id_seq RESTART WITH 1")
|
||||||
db.Exec("ALTER SEQUENCE pipelines_pipeline_id_seq RESTART WITH 1")
|
_, _ = db.Exec("ALTER SEQUENCE pipelines_pipeline_id_seq RESTART WITH 1")
|
||||||
db.Exec("ALTER SEQUENCE executions_execution_id_seq RESTART WITH 1")
|
_, _ = db.Exec("ALTER SEQUENCE executions_execution_id_seq RESTART WITH 1")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,12 +49,3 @@ func unmarshal(path string, v interface{}) error {
|
|||||||
}
|
}
|
||||||
return json.Unmarshal(out, v)
|
return json.Unmarshal(out, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// dump json data to the test logs.
|
|
||||||
func debug(t *testing.T, v interface{}) {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
enc := json.NewEncoder(os.Stdout)
|
|
||||||
enc.SetIndent("", " ")
|
|
||||||
enc.Encode(v)
|
|
||||||
t.Log(buf.String())
|
|
||||||
}
|
|
||||||
|
@ -6,6 +6,7 @@ package database
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"database/sql"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/harness/gitness/internal/store"
|
"github.com/harness/gitness/internal/store"
|
||||||
@ -136,7 +137,9 @@ func (s *UserStore) Delete(ctx context.Context, user *types.User) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return processSqlErrorf(err, "Failed to start a new transaction")
|
return processSqlErrorf(err, "Failed to start a new transaction")
|
||||||
}
|
}
|
||||||
defer tx.Rollback()
|
defer func(tx *sql.Tx) {
|
||||||
|
_ = tx.Rollback()
|
||||||
|
}(tx)
|
||||||
// delete the user
|
// delete the user
|
||||||
if _, err := tx.ExecContext(ctx, userDelete, user.ID); err != nil {
|
if _, err := tx.ExecContext(ctx, userDelete, user.ID); err != nil {
|
||||||
return processSqlErrorf(err, "The delete query failed")
|
return processSqlErrorf(err, "The delete query failed")
|
||||||
@ -188,10 +191,6 @@ const userSelectEmail = userBase + `
|
|||||||
WHERE user_email = $1
|
WHERE user_email = $1
|
||||||
`
|
`
|
||||||
|
|
||||||
const userSelectToken = userBase + `
|
|
||||||
WHERE user_salt = $1
|
|
||||||
`
|
|
||||||
|
|
||||||
const userDelete = `
|
const userDelete = `
|
||||||
DELETE FROM users
|
DELETE FROM users
|
||||||
WHERE user_id = $1
|
WHERE user_id = $1
|
||||||
|
@ -15,7 +15,6 @@ import (
|
|||||||
|
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
"github.com/google/go-cmp/cmp/cmpopts"
|
"github.com/google/go-cmp/cmp/cmpopts"
|
||||||
"github.com/jmoiron/sqlx"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// user fields to ignore in test comparisons
|
// user fields to ignore in test comparisons
|
||||||
@ -252,20 +251,3 @@ func testUserDelete(s store.UserStore) func(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper function that returns an user store that is seeded
|
|
||||||
// with user data loaded from a json file.
|
|
||||||
func newUserStoreSeeded(db *sqlx.DB) (store.UserStore, error) {
|
|
||||||
store := NewUserStoreSync(NewUserStore(db))
|
|
||||||
vv := []*types.User{}
|
|
||||||
if err := unmarshal("testdata/users.json", &vv); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for _, v := range vv {
|
|
||||||
v.Salt = fmt.Sprintf("%x", v.Email)
|
|
||||||
if err := store.Create(noContext, v); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return store, nil
|
|
||||||
}
|
|
||||||
|
@ -21,10 +21,10 @@ const (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
ErrNameLength = &CheckError{fmt.Sprintf("Name has to be between %d and %d in length.", minNameLength, maxNameLength)}
|
ErrNameLength = &CheckError{fmt.Sprintf("Name has to be between %d and %d in length.", minNameLength, maxNameLength)}
|
||||||
ErrNameRegex = &CheckError{fmt.Sprintf("Name has start with a letter and only contain the following [a-z0-9-_].")}
|
ErrNameRegex = &CheckError{"Name has start with a letter and only contain the following [a-z0-9-_]."}
|
||||||
|
|
||||||
ErrDisplayNameLength = &CheckError{fmt.Sprintf("Display name has to be between %d and %d in length.", minDisplayNameLength, maxDisplayNameLength)}
|
ErrDisplayNameLength = &CheckError{fmt.Sprintf("Display name has to be between %d and %d in length.", minDisplayNameLength, maxDisplayNameLength)}
|
||||||
ErrDisplayNameRegex = &CheckError{fmt.Sprintf("Display name has start with a letter and only contain the following [a-zA-Z0-9-_ ].")}
|
ErrDisplayNameRegex = &CheckError{"Display name has start with a letter and only contain the following [a-zA-Z0-9-_ ]."}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Name checks the provided name and returns an error in it isn't valid.
|
// Name checks the provided name and returns an error in it isn't valid.
|
||||||
|
@ -46,7 +46,7 @@ func Path(path string, isSpace bool) error {
|
|||||||
// ensure path is not too deep
|
// ensure path is not too deep
|
||||||
segments := strings.Split(path, types.PathSeparator)
|
segments := strings.Split(path, types.PathSeparator)
|
||||||
l := len(segments)
|
l := len(segments)
|
||||||
if l < minPathSegments || (isSpace == false && l > maxPathSegments) || (isSpace && l > maxPathSegmentsForSpace) {
|
if l < minPathSegments || (!isSpace && l > maxPathSegments) || (isSpace && l > maxPathSegmentsForSpace) {
|
||||||
return ErrPathInvalidSize
|
return ErrPathInvalidSize
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,5 +100,5 @@ func PathParams(path *types.PathParams, currentPath string, isSpace bool) error
|
|||||||
*/
|
*/
|
||||||
func PathTooLong(path string, isSpace bool) bool {
|
func PathTooLong(path string, isSpace bool) bool {
|
||||||
l := strings.Count(path, types.PathSeparator) + 1
|
l := strings.Count(path, types.PathSeparator) + 1
|
||||||
return (isSpace == false && l > maxPathSegments) || (isSpace && l > maxPathSegmentsForSpace)
|
return (!isSpace && l > maxPathSegments) || (isSpace && l > maxPathSegmentsForSpace)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user