diff options
| author | mo khan <mo@mokhan.ca> | 2025-06-18 17:11:42 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2025-06-18 17:11:42 -0600 |
| commit | 2694c82d97005ca39f29f540e26249c18a21f6d6 (patch) | |
| tree | 259be3c918a047e26fb357b406d915315aa0ead5 /app | |
| parent | c2b8edab01b23fde6cc196a3349ad6aa19a93299 (diff) | |
refactor: switch to a pure rust implementation
Diffstat (limited to 'app')
| -rw-r--r-- | app/app.go | 31 | ||||
| -rw-r--r-- | app/app_test.go | 52 | ||||
| -rw-r--r-- | app/init.go | 15 | ||||
| -rw-r--r-- | app/server.go | 24 | ||||
| -rw-r--r-- | app/server_test.go | 63 | ||||
| -rw-r--r-- | app/services/ability.go | 27 | ||||
| -rw-r--r-- | app/services/check.go | 72 | ||||
| -rw-r--r-- | app/services/check_test.go | 95 |
8 files changed, 0 insertions, 379 deletions
diff --git a/app/app.go b/app/app.go deleted file mode 100644 index f79b67b1..00000000 --- a/app/app.go +++ /dev/null @@ -1,31 +0,0 @@ -package app - -import ( - "net/http" - - "github.com/rs/zerolog" - "github.com/xlgmokha/x/pkg/ioc" - "github.com/xlgmokha/x/pkg/log" - "gitlab.com/gitlab-org/software-supply-chain-security/authorization/authzd.git/app/services" - "gitlab.com/gitlab-org/software-supply-chain-security/authorization/authzd.git/pkg/rpc" -) - -func New() http.Handler { - mux := http.NewServeMux() - for _, handler := range handlers() { - mux.Handle(handler.PathPrefix(), handler) - } - - mux.Handle("/health", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusOK) - })) - - logger := ioc.MustResolve[*zerolog.Logger](ioc.Default) - return log.HTTP(logger)(mux) -} - -func handlers() []rpc.TwirpServer { - return []rpc.TwirpServer{ - rpc.NewAbilityServer(services.NewAbilityService()), - } -} diff --git a/app/app_test.go b/app/app_test.go deleted file mode 100644 index f0068e87..00000000 --- a/app/app_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package app - -import ( - http "net/http" - "net/http/httptest" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/software-supply-chain-security/authorization/authzd.git/pkg/rpc" -) - -func TestApp(t *testing.T) { - handler := New() - srv := httptest.NewServer(handler) - defer srv.Close() - - t.Run("Ability.Allowed", func(t *testing.T) { - client := rpc.NewAbilityProtobufClient(srv.URL, &http.Client{}) - - t.Run("forbids", func(t *testing.T) { - reply, err := client.Allowed(t.Context(), &rpc.AllowRequest{ - Subject: "", - Permission: "", - Resource: "", - }) - require.NoError(t, err) - assert.False(t, reply.Result) - }) - - t.Run("allows gid://User/1 read gid://Organization/2", func(t *testing.T) { - reply, err := client.Allowed(t.Context(), &rpc.AllowRequest{ - Subject: "gid://example/User/1", - Permission: "read", - Resource: "gid://example/Organization/2", - }) - require.NoError(t, err) - assert.True(t, reply.Result) - }) - }) - - t.Run("GET /health", func(t *testing.T) { - t.Run("returns OK", func(t *testing.T) { - r := httptest.NewRequest("GET", "/health", nil) - w := httptest.NewRecorder() - - handler.ServeHTTP(w, r) - - assert.Equal(t, http.StatusOK, w.Code) - }) - }) -} diff --git a/app/init.go b/app/init.go deleted file mode 100644 index 3c4e757e..00000000 --- a/app/init.go +++ /dev/null @@ -1,15 +0,0 @@ -package app - -import ( - "os" - - "github.com/rs/zerolog" - "github.com/xlgmokha/x/pkg/ioc" - "github.com/xlgmokha/x/pkg/log" -) - -func init() { - ioc.RegisterSingleton[*zerolog.Logger](ioc.Default, func() *zerolog.Logger { - return log.New(os.Stdout, log.Fields{"app": "authzd"}) - }) -} diff --git a/app/server.go b/app/server.go deleted file mode 100644 index 3ce0aadc..00000000 --- a/app/server.go +++ /dev/null @@ -1,24 +0,0 @@ -package app - -import ( - "context" - - auth "github.com/envoyproxy/go-control-plane/envoy/service/auth/v3" - "gitlab.com/gitlab-org/software-supply-chain-security/authorization/authzd.git/app/services" - "google.golang.org/grpc" - "google.golang.org/grpc/reflection" -) - -type Server struct { - *grpc.Server -} - -func NewServer(ctx context.Context, options ...grpc.ServerOption) *Server { - server := grpc.NewServer(options...) - auth.RegisterAuthorizationServer(server, services.NewCheckService()) - reflection.Register(server) - - return &Server{ - Server: server, - } -} diff --git a/app/server_test.go b/app/server_test.go deleted file mode 100644 index ff34487a..00000000 --- a/app/server_test.go +++ /dev/null @@ -1,63 +0,0 @@ -package app - -import ( - "context" - "net" - "testing" - - auth "github.com/envoyproxy/go-control-plane/envoy/service/auth/v3" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/credentials/insecure" - "google.golang.org/grpc/test/bufconn" -) - -type HTTPRequest = auth.AttributeContext_HttpRequest - -func TestServer(t *testing.T) { - socket := bufconn.Listen(1024 * 1024) - srv := NewServer(t.Context()) - - defer srv.GracefulStop() - go func() { - require.NoError(t, srv.Serve(socket)) - }() - - connection, err := grpc.DialContext( - t.Context(), - "bufnet", - grpc.WithContextDialer(func(context.Context, string) (net.Conn, error) { - return socket.Dial() - }), - grpc.WithTransportCredentials(insecure.NewCredentials()), - ) - require.NoError(t, err) - defer connection.Close() - - client := auth.NewAuthorizationClient(connection) - - t.Run("CheckRequest", func(t *testing.T) { - tt := []struct { - http *HTTPRequest - status codes.Code - }{ - {status: codes.OK, http: &HTTPRequest{Method: "GET", Path: "/"}}, - } - - for _, example := range tt { - t.Run(example.http.Path, func(t *testing.T) { - response, err := client.Check(t.Context(), &auth.CheckRequest{ - Attributes: &auth.AttributeContext{ - Request: &auth.AttributeContext_Request{ - Http: example.http, - }, - }, - }) - require.NoError(t, err) - assert.Equal(t, int32(example.status), response.Status.Code) - }) - } - }) -} diff --git a/app/services/ability.go b/app/services/ability.go deleted file mode 100644 index f0379513..00000000 --- a/app/services/ability.go +++ /dev/null @@ -1,27 +0,0 @@ -package services - -import ( - context "context" - - "github.com/cedar-policy/cedar-go" - "gitlab.com/gitlab-org/software-supply-chain-security/authorization/authzd.git/pkg/gid" - "gitlab.com/gitlab-org/software-supply-chain-security/authorization/authzd.git/pkg/policies" - "gitlab.com/gitlab-org/software-supply-chain-security/authorization/authzd.git/pkg/rpc" -) - -type AbilityService struct { -} - -func NewAbilityService() *AbilityService { - return &AbilityService{} -} - -func (h *AbilityService) Allowed(ctx context.Context, req *rpc.AllowRequest) (*rpc.AllowReply, error) { - ok := policies.Allowed(ctx, cedar.Request{ - Principal: gid.NewEntityUID(req.Subject), - Action: cedar.NewEntityUID("Permission", cedar.String(req.Permission)), - Resource: gid.NewEntityUID(req.Resource), - Context: cedar.NewRecord(cedar.RecordMap{}), - }) - return &rpc.AllowReply{Result: ok}, nil -} diff --git a/app/services/check.go b/app/services/check.go deleted file mode 100644 index 23deecb9..00000000 --- a/app/services/check.go +++ /dev/null @@ -1,72 +0,0 @@ -package services - -import ( - "context" - - "github.com/cedar-policy/cedar-go" - core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" - auth "github.com/envoyproxy/go-control-plane/envoy/service/auth/v3" - types "github.com/envoyproxy/go-control-plane/envoy/type/v3" - "gitlab.com/gitlab-org/software-supply-chain-security/authorization/authzd.git/pkg/gid" - "gitlab.com/gitlab-org/software-supply-chain-security/authorization/authzd.git/pkg/policies" - status "google.golang.org/genproto/googleapis/rpc/status" - "google.golang.org/grpc/codes" -) - -type CheckService struct { - auth.UnimplementedAuthorizationServer -} - -func NewCheckService() *CheckService { - return &CheckService{} -} - -func (svc *CheckService) Check(ctx context.Context, request *auth.CheckRequest) (*auth.CheckResponse, error) { - if svc.isAllowed(ctx, request) { - return svc.OK(ctx), nil - } - return svc.Denied(ctx), nil -} - -func (svc *CheckService) isAllowed(ctx context.Context, r *auth.CheckRequest) bool { - return policies.Allowed(ctx, cedar.Request{ - Principal: gid.NewEntityUID("gid://gitlab/User/*"), - Action: cedar.NewEntityUID("HttpMethod", cedar.String(r.Attributes.Request.Http.Method)), - Resource: cedar.NewEntityUID("HttpPath", cedar.String(r.Attributes.Request.Http.Path)), - Context: cedar.NewRecord(cedar.RecordMap{ - "host": cedar.String(r.Attributes.Request.Http.Host), - }), - }) - -} - -func (svc *CheckService) OK(ctx context.Context) *auth.CheckResponse { - return &auth.CheckResponse{ - Status: &status.Status{ - Code: int32(codes.OK), - }, - HttpResponse: &auth.CheckResponse_OkResponse{ - OkResponse: &auth.OkHttpResponse{ - Headers: []*core.HeaderValueOption{}, - HeadersToRemove: []string{}, - ResponseHeadersToAdd: []*core.HeaderValueOption{}, - }, - }, - } -} - -func (svc *CheckService) Denied(ctx context.Context) *auth.CheckResponse { - return &auth.CheckResponse{ - Status: &status.Status{ - Code: int32(codes.PermissionDenied), - }, - HttpResponse: &auth.CheckResponse_DeniedResponse{ - DeniedResponse: &auth.DeniedHttpResponse{ - Status: &types.HttpStatus{ - Code: types.StatusCode_Unauthorized, - }, - Headers: []*core.HeaderValueOption{}, - }, - }, - } -} diff --git a/app/services/check_test.go b/app/services/check_test.go deleted file mode 100644 index 4eb396bb..00000000 --- a/app/services/check_test.go +++ /dev/null @@ -1,95 +0,0 @@ -package services - -import ( - "strings" - "testing" - - core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" - auth "github.com/envoyproxy/go-control-plane/envoy/service/auth/v3" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/types/known/timestamppb" -) - -func TestCheckService(t *testing.T) { - svc := NewCheckService() - - t.Run("allows access", func(t *testing.T) { - idToken := "header.payload.signature" - accessToken := "f88f60df11e458b594c80b299aee05f8e5805c65c3e779cc6fbc606c4ac36227" - refreshToken := "0847d325d6e4f021c4baaae0ddb425dbd8795807a4751cd2131bec8e8a9aee24" - - cookies := []string{ - "bearer_token=" + accessToken + ";", - "id_token=" + idToken + ";", - "refresh_token=" + refreshToken, - } - - response, err := svc.Check(t.Context(), &auth.CheckRequest{ - Attributes: &auth.AttributeContext{ - Source: &auth.AttributeContext_Peer{ - Address: &core.Address{ - Address: &core.Address_SocketAddress{ - SocketAddress: &core.SocketAddress{ - Address: "127.0.0.1", - PortSpecifier: &core.SocketAddress_PortValue{ - PortValue: 52358, - }, - }, - }, - }, - }, - Destination: &auth.AttributeContext_Peer{ - Address: &core.Address{ - Address: &core.Address_SocketAddress{ - SocketAddress: &core.SocketAddress{ - Address: "127.0.0.1", - PortSpecifier: &core.SocketAddress_PortValue{ - PortValue: 10000, - }, - }, - }, - }, - }, - Request: &auth.AttributeContext_Request{ - Time: ×tamppb.Timestamp{Seconds: 1747937928, Nanos: 476481000}, - Http: &auth.AttributeContext_HttpRequest{ - Id: "1248474133684962828", - Method: "GET", - Headers: map[string]string{ - ":authority": "localhost:10000", - ":method": "GET", - ":path": "/health", - ":scheme": "http", - "accept": "*/*", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en-US,en;q=0.9", - "cache-control": "max-age=0", - "content-length": "64", - "content-type": "application/json", - "cookie": strings.Join(cookies, "; "), - "origin": "http://localhost:10000", - "referer": "http://localhost:10000/dashboard", - "sec-ch-ua-mobile": "?0", - "sec-ch-ua-platform": "Linux", - "sec-fetch-dest": "empty", - "sec-fetch-mode": "cors", - "sec-fetch-site": "same-origin", - "x-forwarded-proto": "http", - "x-request-id": "7e064610-9e19-4a38-8354-0de0b5fbd7c6", - }, - Path: "/health", - Host: "localhost:10000", - Scheme: "http", - Protocol: "HTTP/1.1", - }, - }, - MetadataContext: &core.Metadata{}, - RouteMetadataContext: &core.Metadata{}, - }, - }) - - require.NoError(t, err) - assert.NotNil(t, response.GetOkResponse()) - }) -} |
