-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(bff): user info endpoint (#630)
* feat(bff): user info endpoint Signed-off-by: Eder Ignatowicz <[email protected]> * Update clients/ui/bff/README.md Co-authored-by: Griffin Sullivan <[email protected]> Signed-off-by: Eder Ignatowicz <[email protected]> --------- Signed-off-by: Eder Ignatowicz <[email protected]> Co-authored-by: Griffin Sullivan <[email protected]>
- Loading branch information
1 parent
20c04c7
commit 1449fb3
Showing
11 changed files
with
333 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -57,6 +57,7 @@ make docker-build | |
| URL Pattern | Handler | Action | | ||
|----------------------------------------------------------------------------------------------|----------------------------------------------|-------------------------------------------------------------| | ||
| GET /v1/healthcheck | HealthcheckHandler | Show application information. | | ||
| GET /v1/user | UserHandler | Show "kubeflow-user-id" from header information. | | ||
| GET /v1/model_registry | ModelRegistryHandler | Get all model registries, | | ||
| GET /v1/model_registry/{model_registry_id}/registered_models | GetAllRegisteredModelsHandler | Gets a list of all RegisteredModel entities. | | ||
| POST /v1/model_registry/{model_registry_id}/registered_models | CreateRegisteredModelHandler | Create a RegisteredModel entity. | | ||
|
@@ -78,6 +79,10 @@ You will need to inject your requests with a kubeflow-userid header for authoriz | |
curl -i -H "kubeflow-userid: [email protected]" localhost:4000/api/v1/healthcheck | ||
``` | ||
``` | ||
# GET /v1/user | ||
curl -i -H "kubeflow-userid: [email protected]" localhost:4000/api/v1/user | ||
``` | ||
``` | ||
# GET /v1/model_registry | ||
curl -i -H "kubeflow-userid: [email protected]" localhost:4000/api/v1/model_registry | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package api | ||
|
||
import ( | ||
"errors" | ||
"github.com/julienschmidt/httprouter" | ||
"github.com/kubeflow/model-registry/ui/bff/internal/models" | ||
"net/http" | ||
) | ||
|
||
type UserEnvelope Envelope[*models.User, None] | ||
|
||
func (app *App) UserHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { | ||
|
||
userHeader := r.Header.Get(kubeflowUserId) | ||
if userHeader == "" { | ||
app.serverErrorResponse(w, r, errors.New("kubeflow-userid not present on header")) | ||
return | ||
} | ||
|
||
user, err := app.repositories.User.GetUser(app.kubernetesClient, userHeader) | ||
if err != nil { | ||
app.serverErrorResponse(w, r, err) | ||
return | ||
} | ||
|
||
userRes := UserEnvelope{ | ||
Data: user, | ||
} | ||
|
||
err = app.WriteJSON(w, http.StatusOK, userRes, nil) | ||
|
||
if err != nil { | ||
app.serverErrorResponse(w, r, err) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
package api | ||
|
||
import ( | ||
"encoding/json" | ||
"io" | ||
"net/http" | ||
"net/http/httptest" | ||
|
||
"github.com/kubeflow/model-registry/ui/bff/internal/repositories" | ||
. "github.com/onsi/ginkgo/v2" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
const ( | ||
KubeflowUserIDHeaderValue = "[email protected]" | ||
DoraNonAdminUser = "[email protected]" | ||
) | ||
|
||
var _ = Describe("TestUserHandler", func() { | ||
Context("fetching user details", Ordered, func() { | ||
var testApp App | ||
|
||
BeforeAll(func() { | ||
By("creating the test app") | ||
testApp = App{ | ||
kubernetesClient: k8sClient, | ||
repositories: repositories.NewRepositories(mockMRClient), | ||
logger: logger, | ||
} | ||
}) | ||
|
||
It("should show that KubeflowUserIDHeaderValue ([email protected]) is a cluster-admin", func() { | ||
By("creating the http request") | ||
req, err := http.NewRequest(http.MethodGet, UserPath, nil) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
req.Header.Set(kubeflowUserId, KubeflowUserIDHeaderValue) | ||
|
||
By("creating the http test infrastructure") | ||
rr := httptest.NewRecorder() | ||
|
||
By("invoking the UserHandler") | ||
testApp.UserHandler(rr, req, nil) | ||
rs := rr.Result() | ||
defer rs.Body.Close() | ||
body, err := io.ReadAll(rs.Body) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
By("unmarshalling the user response") | ||
var actual UserEnvelope | ||
err = json.Unmarshal(body, &actual) | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(rr.Code).To(Equal(http.StatusOK)) | ||
|
||
By("checking that the user is cluster-admin") | ||
Expect(actual.Data.UserID).To(Equal(KubeflowUserIDHeaderValue)) | ||
Expect(actual.Data.ClusterAdmin).To(BeTrue(), "Expected this user to be cluster-admin") | ||
}) | ||
|
||
It("should show that DoraNonAdminUser ([email protected]) is not a cluster-admin", func() { | ||
By("creating the http request") | ||
req, err := http.NewRequest(http.MethodGet, UserPath, nil) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
req.Header.Set(kubeflowUserId, DoraNonAdminUser) | ||
|
||
By("creating the http test infrastructure") | ||
rr := httptest.NewRecorder() | ||
|
||
By("invoking the UserHandler") | ||
testApp.UserHandler(rr, req, nil) | ||
rs := rr.Result() | ||
defer rs.Body.Close() | ||
body, err := io.ReadAll(rs.Body) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
By("unmarshalling the user response") | ||
var actual UserEnvelope | ||
err = json.Unmarshal(body, &actual) | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(rr.Code).To(Equal(http.StatusOK)) | ||
|
||
By("checking that the user is not cluster-admin") | ||
Expect(actual.Data.UserID).To(Equal(DoraNonAdminUser)) | ||
Expect(actual.Data.ClusterAdmin).To(BeFalse(), "Expected this user to not be cluster-admin") | ||
}) | ||
|
||
It("should show that a random non-existent user is not a cluster-admin", func() { | ||
randomUser := "[email protected]" | ||
|
||
By("creating the http request") | ||
req, err := http.NewRequest(http.MethodGet, UserPath, nil) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
req.Header.Set(kubeflowUserId, randomUser) | ||
|
||
By("creating the http test infrastructure") | ||
rr := httptest.NewRecorder() | ||
|
||
By("invoking the UserHandler") | ||
testApp.UserHandler(rr, req, nil) | ||
rs := rr.Result() | ||
defer rs.Body.Close() | ||
body, err := io.ReadAll(rs.Body) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
By("unmarshalling the user response") | ||
var actual UserEnvelope | ||
err = json.Unmarshal(body, &actual) | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(rr.Code).To(Equal(http.StatusOK)) | ||
|
||
By("checking that the user is not cluster-admin") | ||
Expect(actual.Data.UserID).To(Equal(randomUser)) | ||
Expect(actual.Data.ClusterAdmin).To(BeFalse(), "Expected this user to not be cluster-admin") | ||
}) | ||
}) | ||
|
||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.