diff options
-rw-r--r-- | pkg/api/handlers/compat/auth.go | 51 | ||||
-rw-r--r-- | pkg/api/server/register_auth.go | 24 | ||||
-rw-r--r-- | pkg/api/server/swagger.go | 9 | ||||
-rw-r--r-- | pkg/domain/entities/system.go | 11 | ||||
-rw-r--r-- | test/apiv2/rest_api/test_rest_v2_0_0.py | 21 |
5 files changed, 104 insertions, 12 deletions
diff --git a/pkg/api/handlers/compat/auth.go b/pkg/api/handlers/compat/auth.go new file mode 100644 index 000000000..e914301f4 --- /dev/null +++ b/pkg/api/handlers/compat/auth.go @@ -0,0 +1,51 @@ +package compat + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "strings" + + DockerClient "github.com/containers/image/v5/docker" + "github.com/containers/image/v5/types" + "github.com/containers/podman/v3/pkg/api/handlers/utils" + "github.com/containers/podman/v3/pkg/domain/entities" + "github.com/containers/podman/v3/pkg/registries" + docker "github.com/docker/docker/api/types" + "github.com/pkg/errors" +) + +func Auth(w http.ResponseWriter, r *http.Request) { + var authConfig docker.AuthConfig + err := json.NewDecoder(r.Body).Decode(&authConfig) + if err != nil { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "failed to parse request")) + return + } + + skipTLS := types.NewOptionalBool(false) + if strings.HasPrefix(authConfig.ServerAddress, "http://localhost/") || strings.HasPrefix(authConfig.ServerAddress, "http://localhost:") { + // support for local testing + skipTLS = types.NewOptionalBool(true) + } + + fmt.Println("Authenticating with existing credentials...") + sysCtx := types.SystemContext{ + AuthFilePath: "", + DockerCertPath: "", + DockerInsecureSkipTLSVerify: skipTLS, + SystemRegistriesConfPath: registries.SystemRegistriesConfPath(), + } + if err := DockerClient.CheckAuth(context.Background(), &sysCtx, authConfig.Username, authConfig.Password, authConfig.ServerAddress); err == nil { + utils.WriteResponse(w, http.StatusOK, entities.AuthReport{ + IdentityToken: "", + Status: "Login Succeeded", + }) + } else { + utils.WriteResponse(w, http.StatusBadRequest, entities.AuthReport{ + IdentityToken: "", + Status: "login attempt to " + authConfig.ServerAddress + " failed with status: " + err.Error(), + }) + } +} diff --git a/pkg/api/server/register_auth.go b/pkg/api/server/register_auth.go index 1e5474462..56e115e30 100644 --- a/pkg/api/server/register_auth.go +++ b/pkg/api/server/register_auth.go @@ -1,13 +1,33 @@ package server import ( + "net/http" + "github.com/containers/podman/v3/pkg/api/handlers/compat" "github.com/gorilla/mux" ) func (s *APIServer) registerAuthHandlers(r *mux.Router) error { - r.Handle(VersionedPath("/auth"), s.APIHandler(compat.UnsupportedHandler)) + // swagger:operation POST /auth compat auth + // --- + // summary: Check auth configuration + // tags: + // - system (compat) + // produces: + // - application/json + // parameters: + // - in: body + // name: authConfig + // description: Authentication to check + // schema: + // $ref: "#/definitions/AuthConfig" + // responses: + // 200: + // $ref: "#/responses/SystemAuthResponse" + // 500: + // $ref: "#/responses/InternalError" + r.Handle(VersionedPath("/auth"), s.APIHandler(compat.Auth)).Methods(http.MethodPost) // Added non version path to URI to support docker non versioned paths - r.Handle("/auth", s.APIHandler(compat.UnsupportedHandler)) + r.Handle("/auth", s.APIHandler(compat.Auth)).Methods(http.MethodPost) return nil } diff --git a/pkg/api/server/swagger.go b/pkg/api/server/swagger.go index 92efb8ef3..12fd083bb 100644 --- a/pkg/api/server/swagger.go +++ b/pkg/api/server/swagger.go @@ -226,3 +226,12 @@ type swagSystemPruneReport struct { entities.SystemPruneReport } } + +// Auth response +// swagger:response SystemAuthResponse +type swagSystemAuthResponse struct { + // in:body + Body struct { + entities.AuthReport + } +} diff --git a/pkg/domain/entities/system.go b/pkg/domain/entities/system.go index a1cfb4481..4b8383613 100644 --- a/pkg/domain/entities/system.go +++ b/pkg/domain/entities/system.go @@ -107,3 +107,14 @@ type ComponentVersion struct { type ListRegistriesReport struct { Registries []string } + +// swagger:model AuthConfig +type AuthConfig struct { + types.AuthConfig +} + +// AuthReport describes the response for authentication check +type AuthReport struct { + IdentityToken string + Status string +} diff --git a/test/apiv2/rest_api/test_rest_v2_0_0.py b/test/apiv2/rest_api/test_rest_v2_0_0.py index c0b61ea85..062cf9386 100644 --- a/test/apiv2/rest_api/test_rest_v2_0_0.py +++ b/test/apiv2/rest_api/test_rest_v2_0_0.py @@ -555,16 +555,17 @@ class TestApi(unittest.TestCase): self.assertIn(name, payload["VolumesDeleted"]) self.assertGreater(payload["SpaceReclaimed"], 0) - def test_auth_compat(self): - r = requests.post( - PODMAN_URL + "/v1.40/auth", - json={ - "username": "bozo", - "password": "wedontneednopasswords", - "serveraddress": "https://localhost/v1.40/", - }, - ) - self.assertEqual(r.status_code, 404, r.content) + # TBD: how to test auth endpoint (which in turn requires a docker registry to connect to) + # def test_auth_compat(self): + # r = requests.post( + # PODMAN_URL + "/v1.40/auth", + # json={ + # "username": "bozo", + # "password": "wedontneednopasswords", + # "serveraddress": "https://localhost/v1.40/", + # }, + # ) + # self.assertEqual(r.status_code, 404, r.content) def test_version(self): r = requests.get(PODMAN_URL + "/v1.40/version") |