cold-motorcycle-49371
04/18/2023, 8:14 AMcurved-fountain-46946
04/18/2023, 11:11 AMfunc (oc *oryClient) authenticate(ctx context.Context) error {
flow, _, err := oc.FrontendApi.CreateNativeLoginFlow(ctx).Execute()
if err != nil {
return err
}
login, _, err := oc.FrontendApi.UpdateLoginFlow(ctx).Flow(flow.Id).UpdateLoginFlowBody(ory.UpdateLoginFlowBody{
UpdateLoginFlowWithPasswordMethod: ory.NewUpdateLoginFlowWithPasswordMethod(oc.nsContext.user, "password", oc.nsContext.password),
}).Execute()
if err != nil {
return err
}
oc.token = *login.SessionToken
return nil
}
func (oc *oryClient) patchProject(ctx context.Context, patch []ory.JsonPatch) (*ory.SuccessfulProjectUpdate, *gohttp.Response, error) {
return oc.ProjectApi.PatchProject(oc.AuthCtx(ctx), oc.nsContext.projectId).JsonPatch(patch).Execute()
}
func (oc *oryClient) UpdateNamespaces(ctx context.Context, namespaces map[string]int) (*ory.SuccessfulProjectUpdate, error) {
out := make([]Namespace, len(namespaces))
var i int
for name, id := range namespaces {
out[i] = Namespace{
Id: id,
Name: name,
}
i++
}
patch := []ory.JsonPatch{
{
Op: OpReplace,
Path: "/services/permission/config/" + NamespacesKey,
// We may have to encode something here, to like json or yaml, who knows?
Value: out,
},
}
success, res, err := oc.patchProject(ctx, patch)
if res != nil && res.StatusCode == gohttp.StatusUnauthorized {
if err := oc.authenticate(ctx); err != nil {
return nil, err
}
success, res, err = oc.patchProject(ctx, patch)
}
return success, oc.appendMessageIfError(res, err)
}
curved-fountain-46946
04/18/2023, 11:12 AMcurved-fountain-46946
04/18/2023, 11:13 AMfunc (oc *oryClient) getProject(ctx context.Context) (*ory.Project, *gohttp.Response, error) {
return oc.ProjectApi.GetProject(oc.AuthCtx(ctx), oc.nsContext.projectId).Execute()
}
func (oc *oryClient) ListNamespaces(ctx context.Context) (map[string]int, int, error) {
proj, res, err := oc.getProject(ctx)
if res != nil && res.StatusCode == gohttp.StatusUnauthorized {
if err := oc.authenticate(ctx); err != nil {
return nil, 0, err
}
proj, res, err = oc.getProject(ctx)
}
if err != nil {
return nil, 0, oc.appendMessageIfError(res, err)
}
namespacesConfig := proj.Services.Permission.GetConfig()[NamespacesKey]
namespaces, ok := namespacesConfig.([]interface{})
if !ok {
return nil, 0, fmt.Errorf("unable to assert namespace config as []interface{}")
}
var last int
out := make(map[string]int, len(namespaces))
for _, ns := range namespaces {
namespace, ok := ns.(map[string]interface{})
if !ok {
return nil, 0, fmt.Errorf("unable to assert namespace as map[string]interface{}")
}
id := int(namespace["id"].(float64))
name := namespace["name"].(string)
out[name] = id
if id > last {
last = id
}
}
return out, last, nil
}
curved-fountain-46946
04/18/2023, 11:15 AMcurved-fountain-46946
04/18/2023, 11:16 AMcurved-fountain-46946
04/18/2023, 11:24 AMconst NamespacesKey = "namespaces"
type Namespace struct {
Id int `json:"id" yaml:"id"`
Name string `json:"name" yaml:"name"`
}
type oryNamespacesContext struct {
user string
password string
projectId string
}
// This interface is kind of a hack, but the kind people at Ory
// have blessed me to solve this hurdle in this manner :)
type NamespaceClient interface {
ListNamespaces(ctx context.Context) (map[string]int, int, error)
UpdateNamespaces(ctx context.Context, namespaces map[string]int) (*ory.SuccessfulProjectUpdate, error)
}
func NewOryNamespaceClient(url *url.URL, user, password, projectId string, httpClient http.Client) NamespaceClient {
c := ory.NewConfiguration()
kratosUrl, _ := url.Parse("")
kratosUrl.Host = "project." + kratosUrl.Host
url.Host = "api." + url.Host
c.Servers = ory.ServerConfigurations{{URL: url.String()}}
c.HTTPClient = httpClient.(*gohttp.Client)
c.OperationServers["FrontendApiService.CreateNativeLoginFlow"] = ory.ServerConfigurations{{URL: kratosUrl.String()}}
c.OperationServers["FrontendApiService.UpdateLoginFlow"] = ory.ServerConfigurations{{URL: kratosUrl.String()}}
return &oryClient{
ory.NewAPIClient(c),
"",
&oryNamespacesContext{
user: user,
password: password,
projectId: projectId,
},
}
}
brainy-agency-86743
04/18/2023, 11:28 AMmagnificent-energy-493
cold-motorcycle-49371
06/19/2023, 5:44 PMPatchProject
which updates the config as we're introducing dynamic entities.curved-fountain-46946
06/19/2023, 5:53 PMcold-motorcycle-49371
06/19/2023, 6:00 PM