mirror of
https://github.com/zitadel/zitadel.git
synced 2025-01-07 22:07:40 +00:00
feat(actions): allow getting metadata of organizations from user grants (#7782)
* feat(actions): allow getting metadata of (other) organizations from user grants * docs add action example
This commit is contained in:
parent
9d754d84b3
commit
74624018c2
@ -68,6 +68,19 @@ https://github.com/zitadel/actions/blob/main/examples/custom_roles.js
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
### Custom role mapping including org metadata in claims
|
||||||
|
|
||||||
|
There's even a possibility to use the metadata of organizations the user is granted to
|
||||||
|
|
||||||
|
<details open="">
|
||||||
|
<summary>Code example</summary>
|
||||||
|
|
||||||
|
```js reference
|
||||||
|
https://github.com/zitadel/actions/blob/main/examples/custom_roles_org_metadata.js
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
## Customize SAML response
|
## Customize SAML response
|
||||||
|
|
||||||
Append attributes returned on SAML requests.
|
Append attributes returned on SAML requests.
|
||||||
|
@ -210,3 +210,5 @@ This object represents a list of user grant stored in ZITADEL.
|
|||||||
The name of the organization, where the user was granted
|
The name of the organization, where the user was granted
|
||||||
- `projectId` *string*
|
- `projectId` *string*
|
||||||
- `projectName` *string*
|
- `projectName` *string*
|
||||||
|
- `getOrgMetadata()` [*metadataResult*](#metadata-result)
|
||||||
|
Get the metadata of the organization where the user was granted
|
@ -1,6 +1,7 @@
|
|||||||
package object
|
package object
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -77,6 +78,21 @@ func UserMetadataListFromSlice(c *actions.FieldConfig, metadata []query.UserMeta
|
|||||||
return c.Runtime.ToValue(result)
|
return c.Runtime.ToValue(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetOrganizationMetadata(ctx context.Context, queries *query.Queries, c *actions.FieldConfig, organizationID string) goja.Value {
|
||||||
|
metadata, err := queries.SearchOrgMetadata(
|
||||||
|
ctx,
|
||||||
|
true,
|
||||||
|
organizationID,
|
||||||
|
&query.OrgMetadataSearchQueries{},
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
logging.WithError(err).Info("unable to get org metadata in action")
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return OrgMetadataListFromQuery(c, metadata)
|
||||||
|
}
|
||||||
|
|
||||||
func metadataByteArrayToValue(val []byte, runtime *goja.Runtime) goja.Value {
|
func metadataByteArrayToValue(val []byte, runtime *goja.Runtime) goja.Value {
|
||||||
var value interface{}
|
var value interface{}
|
||||||
if !json.Valid(val) {
|
if !json.Valid(val) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package object
|
package object
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/dop251/goja"
|
"github.com/dop251/goja"
|
||||||
@ -44,6 +45,8 @@ type userGrant struct {
|
|||||||
|
|
||||||
ProjectId string
|
ProjectId string
|
||||||
ProjectName string
|
ProjectName string
|
||||||
|
|
||||||
|
GetOrgMetadata func(goja.FunctionCall) goja.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
func AppendGrantFunc(userGrants *UserGrants) func(c *actions.FieldConfig) func(call goja.FunctionCall) goja.Value {
|
func AppendGrantFunc(userGrants *UserGrants) func(c *actions.FieldConfig) func(call goja.FunctionCall) goja.Value {
|
||||||
@ -58,10 +61,11 @@ func AppendGrantFunc(userGrants *UserGrants) func(c *actions.FieldConfig) func(c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func UserGrantsFromQuery(c *actions.FieldConfig, userGrants *query.UserGrants) goja.Value {
|
func UserGrantsFromQuery(ctx context.Context, queries *query.Queries, c *actions.FieldConfig, userGrants *query.UserGrants) goja.Value {
|
||||||
if userGrants == nil {
|
if userGrants == nil {
|
||||||
return c.Runtime.ToValue(nil)
|
return c.Runtime.ToValue(nil)
|
||||||
}
|
}
|
||||||
|
orgMetadata := make(map[string]goja.Value)
|
||||||
grantList := &userGrantList{
|
grantList := &userGrantList{
|
||||||
Count: userGrants.Count,
|
Count: userGrants.Count,
|
||||||
Sequence: userGrants.Sequence,
|
Sequence: userGrants.Sequence,
|
||||||
@ -84,16 +88,24 @@ func UserGrantsFromQuery(c *actions.FieldConfig, userGrants *query.UserGrants) g
|
|||||||
UserGrantResourceOwnerName: grant.OrgName,
|
UserGrantResourceOwnerName: grant.OrgName,
|
||||||
ProjectId: grant.ProjectID,
|
ProjectId: grant.ProjectID,
|
||||||
ProjectName: grant.ProjectName,
|
ProjectName: grant.ProjectName,
|
||||||
|
GetOrgMetadata: func(call goja.FunctionCall) goja.Value {
|
||||||
|
if md, ok := orgMetadata[grant.ResourceOwner]; ok {
|
||||||
|
return md
|
||||||
|
}
|
||||||
|
orgMetadata[grant.ResourceOwner] = GetOrganizationMetadata(ctx, queries, c, grant.ResourceOwner)
|
||||||
|
return orgMetadata[grant.ResourceOwner]
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.Runtime.ToValue(grantList)
|
return c.Runtime.ToValue(grantList)
|
||||||
}
|
}
|
||||||
|
|
||||||
func UserGrantsFromSlice(c *actions.FieldConfig, userGrants []query.UserGrant) goja.Value {
|
func UserGrantsFromSlice(ctx context.Context, queries *query.Queries, c *actions.FieldConfig, userGrants []query.UserGrant) goja.Value {
|
||||||
if userGrants == nil {
|
if userGrants == nil {
|
||||||
return c.Runtime.ToValue(nil)
|
return c.Runtime.ToValue(nil)
|
||||||
}
|
}
|
||||||
|
orgMetadata := make(map[string]goja.Value)
|
||||||
grantList := &userGrantList{
|
grantList := &userGrantList{
|
||||||
Count: uint64(len(userGrants)),
|
Count: uint64(len(userGrants)),
|
||||||
Grants: make([]*userGrant, len(userGrants)),
|
Grants: make([]*userGrant, len(userGrants)),
|
||||||
@ -114,6 +126,13 @@ func UserGrantsFromSlice(c *actions.FieldConfig, userGrants []query.UserGrant) g
|
|||||||
UserGrantResourceOwnerName: grant.OrgName,
|
UserGrantResourceOwnerName: grant.OrgName,
|
||||||
ProjectId: grant.ProjectID,
|
ProjectId: grant.ProjectID,
|
||||||
ProjectName: grant.ProjectName,
|
ProjectName: grant.ProjectName,
|
||||||
|
GetOrgMetadata: func(goja.FunctionCall) goja.Value {
|
||||||
|
if md, ok := orgMetadata[grant.ResourceOwner]; ok {
|
||||||
|
return md
|
||||||
|
}
|
||||||
|
orgMetadata[grant.ResourceOwner] = GetOrganizationMetadata(ctx, queries, c, grant.ResourceOwner)
|
||||||
|
return orgMetadata[grant.ResourceOwner]
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,25 +490,16 @@ func (o *OPStorage) userinfoFlows(ctx context.Context, user *query.User, userGra
|
|||||||
return object.UserMetadataListFromQuery(c, metadata)
|
return object.UserMetadataListFromQuery(c, metadata)
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
actions.SetFields("grants", func(c *actions.FieldConfig) interface{} {
|
actions.SetFields("grants",
|
||||||
return object.UserGrantsFromQuery(c, userGrants)
|
func(c *actions.FieldConfig) interface{} {
|
||||||
}),
|
return object.UserGrantsFromQuery(ctx, o.query, c, userGrants)
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
actions.SetFields("org",
|
actions.SetFields("org",
|
||||||
actions.SetFields("getMetadata", func(c *actions.FieldConfig) interface{} {
|
actions.SetFields("getMetadata", func(c *actions.FieldConfig) interface{} {
|
||||||
return func(goja.FunctionCall) goja.Value {
|
return func(goja.FunctionCall) goja.Value {
|
||||||
metadata, err := o.query.SearchOrgMetadata(
|
return object.GetOrganizationMetadata(ctx, o.query, c, user.ResourceOwner)
|
||||||
ctx,
|
|
||||||
true,
|
|
||||||
user.ResourceOwner,
|
|
||||||
&query.OrgMetadataSearchQueries{},
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
logging.WithError(err).Info("unable to get org metadata in action")
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return object.OrgMetadataListFromQuery(c, metadata)
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
@ -714,24 +705,13 @@ func (o *OPStorage) privateClaimsFlows(ctx context.Context, userID string, userG
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
actions.SetFields("grants", func(c *actions.FieldConfig) interface{} {
|
actions.SetFields("grants", func(c *actions.FieldConfig) interface{} {
|
||||||
return object.UserGrantsFromQuery(c, userGrants)
|
return object.UserGrantsFromQuery(ctx, o.query, c, userGrants)
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
actions.SetFields("org",
|
actions.SetFields("org",
|
||||||
actions.SetFields("getMetadata", func(c *actions.FieldConfig) interface{} {
|
actions.SetFields("getMetadata", func(c *actions.FieldConfig) interface{} {
|
||||||
return func(goja.FunctionCall) goja.Value {
|
return func(goja.FunctionCall) goja.Value {
|
||||||
metadata, err := o.query.SearchOrgMetadata(
|
return object.GetOrganizationMetadata(ctx, o.query, c, user.ResourceOwner)
|
||||||
ctx,
|
|
||||||
true,
|
|
||||||
user.ResourceOwner,
|
|
||||||
&query.OrgMetadataSearchQueries{},
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
logging.WithError(err).Info("unable to get org metadata in action")
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return object.OrgMetadataListFromQuery(c, metadata)
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
@ -252,24 +252,13 @@ func (s *Server) userinfoFlows(ctx context.Context, qu *query.OIDCUserInfo, user
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
actions.SetFields("grants", func(c *actions.FieldConfig) interface{} {
|
actions.SetFields("grants", func(c *actions.FieldConfig) interface{} {
|
||||||
return object.UserGrantsFromSlice(c, qu.UserGrants)
|
return object.UserGrantsFromSlice(ctx, s.query, c, qu.UserGrants)
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
actions.SetFields("org",
|
actions.SetFields("org",
|
||||||
actions.SetFields("getMetadata", func(c *actions.FieldConfig) interface{} {
|
actions.SetFields("getMetadata", func(c *actions.FieldConfig) interface{} {
|
||||||
return func(goja.FunctionCall) goja.Value {
|
return func(goja.FunctionCall) goja.Value {
|
||||||
metadata, err := s.query.SearchOrgMetadata(
|
return object.GetOrganizationMetadata(ctx, s.query, c, qu.User.ResourceOwner)
|
||||||
ctx,
|
|
||||||
true,
|
|
||||||
qu.User.ResourceOwner,
|
|
||||||
&query.OrgMetadataSearchQueries{},
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
logging.WithError(err).Info("unable to get org metadata in action")
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return object.OrgMetadataListFromQuery(c, metadata)
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
@ -246,24 +246,13 @@ func (p *Storage) getCustomAttributes(ctx context.Context, user *query.User, use
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
actions.SetFields("grants", func(c *actions.FieldConfig) interface{} {
|
actions.SetFields("grants", func(c *actions.FieldConfig) interface{} {
|
||||||
return object.UserGrantsFromQuery(c, userGrants)
|
return object.UserGrantsFromQuery(ctx, p.query, c, userGrants)
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
actions.SetFields("org",
|
actions.SetFields("org",
|
||||||
actions.SetFields("getMetadata", func(c *actions.FieldConfig) interface{} {
|
actions.SetFields("getMetadata", func(c *actions.FieldConfig) interface{} {
|
||||||
return func(goja.FunctionCall) goja.Value {
|
return func(goja.FunctionCall) goja.Value {
|
||||||
metadata, err := p.query.SearchOrgMetadata(
|
return object.GetOrganizationMetadata(ctx, p.query, c, user.ResourceOwner)
|
||||||
ctx,
|
|
||||||
true,
|
|
||||||
user.ResourceOwner,
|
|
||||||
&query.OrgMetadataSearchQueries{},
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
logging.WithError(err).Info("unable to get org metadata in action")
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return object.OrgMetadataListFromQuery(c, metadata)
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user