feat(auth): My user changes (#318)

* fix: project by id loads project from view and from eventstore

* fix: correct search key for role

* feat(auth): my user changes

* fix: improve error handling in change converters

* fix: log-id
This commit is contained in:
Silvan
2020-07-01 07:18:05 +02:00
committed by GitHub
parent 4f3631acbb
commit cf7a906023
20 changed files with 3370 additions and 3655 deletions

View File

@@ -2,6 +2,7 @@ package eventstore
import (
"context"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/eventstore"
"github.com/caos/zitadel/internal/eventstore/sdk"
@@ -258,6 +259,21 @@ func (repo *UserRepo) UserByID(ctx context.Context, id string) (*model.UserView,
return usr_view_model.UserToModel(&userCopy), nil
}
func (repo *UserRepo) MyUserChanges(ctx context.Context, lastSequence uint64, limit uint64, sortAscending bool) (*model.UserChanges, error) {
changes, err := repo.UserEvents.UserChanges(ctx, auth.GetCtxData(ctx).UserID, lastSequence, limit, sortAscending)
if err != nil {
return nil, err
}
for _, change := range changes.Changes {
change.ModifierName = change.ModifierId
user, _ := repo.UserEvents.UserByID(ctx, change.ModifierId)
if user != nil {
change.ModifierName = user.DisplayName
}
}
return changes, nil
}
func checkIDs(ctx context.Context, obj es_models.ObjectRoot) error {
if obj.AggregateID != auth.GetCtxData(ctx).UserID {
return errors.ThrowPermissionDenied(nil, "EVENT-kFi9w", "object does not belong to user")

View File

@@ -2,6 +2,9 @@ package handler
import (
"context"
"strings"
"time"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/errors"
caos_errs "github.com/caos/zitadel/internal/errors"
@@ -22,8 +25,6 @@ import (
usr_es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
grant_es_model "github.com/caos/zitadel/internal/usergrant/repository/eventsourcing/model"
view_model "github.com/caos/zitadel/internal/usergrant/repository/view/model"
"strings"
"time"
)
type UserGrant struct {
@@ -171,7 +172,6 @@ func (u *UserGrant) processOrg(event *models.Event) (err error) {
default:
return u.view.ProcessedUserGrantSequence(event.Sequence)
}
return nil
}
func (u *UserGrant) processIamMember(event *models.Event, rolePrefix string, suffix bool) error {
@@ -341,6 +341,6 @@ func (u *UserGrant) fillOrgData(grant *view_model.UserGrantView, org *org_model.
}
func (u *UserGrant) OnError(event *models.Event, err error) error {
logging.LogWithFields("SPOOL-8is4s", "id", event.AggregateID).WithError(err).Warn("something went wrong in user handler")
logging.LogWithFields("SPOOL-UZmc7", "id", event.AggregateID).WithError(err).Warn("something went wrong in user grant handler")
return spooler.HandleError(event, err, u.view.GetLatestUserGrantFailedEvent, u.view.ProcessedUserGrantFailedEvent, u.view.ProcessedUserGrantSequence, u.errorCountUntilSkip)
}

View File

@@ -2,6 +2,7 @@ package repository
import (
"context"
org_model "github.com/caos/zitadel/internal/org/model"
"github.com/caos/zitadel/internal/user/model"
@@ -53,4 +54,6 @@ type myUserRepo interface {
AddMyMfaOTP(ctx context.Context) (*model.OTP, error)
VerifyMyMfaOTPSetup(ctx context.Context, code string) error
RemoveMyMfaOTP(ctx context.Context) error
MyUserChanges(ctx context.Context, lastSequence uint64, limit uint64, sortAscending bool) (*model.UserChanges, error)
}

View File

@@ -2,6 +2,9 @@ package handler
import (
"context"
"strings"
"time"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/errors"
caos_errs "github.com/caos/zitadel/internal/errors"
@@ -14,8 +17,6 @@ import (
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
proj_es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
view_model "github.com/caos/zitadel/internal/usergrant/repository/view/model"
"strings"
"time"
)
type UserGrant struct {
@@ -223,6 +224,6 @@ func (u *UserGrant) setIamProjectID() error {
}
func (u *UserGrant) OnError(event *models.Event, err error) error {
logging.LogWithFields("SPOOL-8is4s", "id", event.AggregateID).WithError(err).Warn("something went wrong in user handler")
logging.LogWithFields("SPOOL-VcVoJ", "id", event.AggregateID).WithError(err).Warn("something went wrong in user grant handler")
return spooler.HandleError(event, err, u.view.GetLatestUserGrantFailedEvent, u.view.ProcessedUserGrantFailedEvent, u.view.ProcessedUserGrantSequence, u.errorCountUntilSkip)
}

View File

@@ -3,12 +3,11 @@ package bigcache
import (
"bytes"
"encoding/gob"
"github.com/caos/logging"
"reflect"
"github.com/caos/zitadel/internal/errors"
a_cache "github.com/allegro/bigcache"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/errors"
)
type Bigcache struct {
@@ -30,19 +29,19 @@ func NewBigcache(c *Config) (*Bigcache, error) {
func (c *Bigcache) Set(key string, object interface{}) error {
if key == "" || reflect.ValueOf(object).IsNil() {
return errors.ThrowInvalidArgument(nil, "FASTC-du73s", "key or value should not be empty")
return errors.ThrowInvalidArgument(nil, "BIGCA-du73s", "key or value should not be empty")
}
var b bytes.Buffer
enc := gob.NewEncoder(&b)
if err := enc.Encode(object); err != nil {
return errors.ThrowInvalidArgument(err, "FASTC-RUyxI", "unable to encode object")
return errors.ThrowInvalidArgument(err, "BIGCA-RUyxI", "unable to encode object")
}
return c.cache.Set(key, b.Bytes())
}
func (c *Bigcache) Get(key string, ptrToObject interface{}) error {
if key == "" || reflect.ValueOf(ptrToObject).IsNil() {
return errors.ThrowInvalidArgument(nil, "FASTC-dksoe", "key or value should not be empty")
return errors.ThrowInvalidArgument(nil, "BIGCA-dksoe", "key or value should not be empty")
}
value, err := c.cache.Get(key)
if err == a_cache.ErrEntryNotFound {
@@ -61,7 +60,7 @@ func (c *Bigcache) Get(key string, ptrToObject interface{}) error {
func (c *Bigcache) Delete(key string) error {
if key == "" {
return errors.ThrowInvalidArgument(nil, "FASTC-clsi2", "key should not be empty")
return errors.ThrowInvalidArgument(nil, "BIGCA-clsi2", "key should not be empty")
}
return c.cache.Delete(key)
}

View File

@@ -50,7 +50,7 @@ func (p *ProjectGrant) Reduce(event *models.Event) (err error) {
if err != nil {
return err
}
p.updateExistingProjects(project)
return p.updateExistingProjects(project)
case es_model.ProjectGrantAdded:
err = grantedProject.AppendEvent(event)
if err != nil {
@@ -107,19 +107,25 @@ func (p *ProjectGrant) getProject(projectID string) (*proj_model.Project, error)
return p.projectEvents.ProjectByID(context.Background(), projectID)
}
func (p *ProjectGrant) updateExistingProjects(project *view_model.ProjectView) {
projects, err := p.view.ProjectGrantsByProjectID(project.ProjectID)
func (p *ProjectGrant) updateExistingProjects(project *view_model.ProjectView) error {
projectGrants, err := p.view.ProjectGrantsByProjectID(project.ProjectID)
if err != nil {
logging.LogWithFields("SPOOL-los03", "id", project.ProjectID).WithError(err).Warn("could not update existing projects")
}
for _, existing := range projects {
for _, existing := range projectGrants {
existing.Name = project.Name
err := p.view.PutProjectGrant(existing)
logging.LogWithFields("SPOOL-sjwi3", "id", existing.ProjectID).WithError(err).Warn("could not update existing project")
if err != nil {
logging.LogWithFields("SPOOL-sjwi3", "id", existing.ProjectID).WithError(err).Warn("could not update existing project")
return err
}
}
return p.view.ProcessedProjectGrantSequence(project.Sequence)
}
func (p *ProjectGrant) OnError(event *models.Event, err error) error {
logging.LogWithFields("SPOOL-is8wa", "id", event.AggregateID).WithError(err).Warn("something went wrong in granted projecthandler")
return spooler.HandleError(event, err, p.view.GetLatestProjectGrantFailedEvent, p.view.ProcessedProjectGrantFailedEvent, p.view.ProcessedProjectGrantSequence, p.errorCountUntilSkip)
}

View File

@@ -13,7 +13,7 @@ type PolicyCache struct {
func StartCache(conf *config.CacheConfig) (*PolicyCache, error) {
policyCache, err := conf.Config.NewCache()
logging.Log("EVENT-vDneN").OnError(err).Panic("unable to create policy cache")
logging.Log("EVENT-L7ZcH").OnError(err).Panic("unable to create policy cache")
return &PolicyCache{policyCache: policyCache}, nil
}
@@ -21,7 +21,7 @@ func StartCache(conf *config.CacheConfig) (*PolicyCache, error) {
func (c *PolicyCache) getPolicy(id string) (policy *PasswordComplexityPolicy) {
policy = &PasswordComplexityPolicy{ObjectRoot: models.ObjectRoot{AggregateID: id}}
if err := c.policyCache.Get(id, policy); err != nil {
logging.Log("EVENT-4eTZh").WithError(err).Debug("error in getting cache")
logging.Log("EVENT-tkUue").WithError(err).Debug("error in getting cache")
}
return policy
}
@@ -29,6 +29,6 @@ func (c *PolicyCache) getPolicy(id string) (policy *PasswordComplexityPolicy) {
func (c *PolicyCache) cachePolicy(policy *PasswordComplexityPolicy) {
err := c.policyCache.Set(policy.AggregateID, policy)
if err != nil {
logging.Log("EVENT-ThnBb").WithError(err).Debug("error in setting policy cache")
logging.Log("EVENT-DVcpF").WithError(err).Debug("error in setting policy cache")
}
}

View File

@@ -14,7 +14,7 @@ type ProjectCache struct {
func StartCache(conf *config.CacheConfig) (*ProjectCache, error) {
projectCache, err := conf.Config.NewCache()
logging.Log("EVENT-vDneN").OnError(err).Panic("unable to create project cache")
logging.Log("EVENT-CsHdo").OnError(err).Panic("unable to create project cache")
return &ProjectCache{projectCache: projectCache}, nil
}
@@ -22,7 +22,7 @@ func StartCache(conf *config.CacheConfig) (*ProjectCache, error) {
func (c *ProjectCache) getProject(ID string) (project *model.Project) {
project = &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: ID}}
if err := c.projectCache.Get(ID, project); err != nil {
logging.Log("EVENT-4eTZh").WithError(err).Debug("error in getting cache")
logging.Log("EVENT-tMydV").WithError(err).Debug("error in getting cache")
}
return project
}
@@ -30,6 +30,6 @@ func (c *ProjectCache) getProject(ID string) (project *model.Project) {
func (c *ProjectCache) cacheProject(project *model.Project) {
err := c.projectCache.Set(project.AggregateID, project)
if err != nil {
logging.Log("EVENT-ThnBb").WithError(err).Debug("error in setting project cache")
logging.Log("EVENT-3wKzj").WithError(err).Debug("error in setting project cache")
}
}

View File

@@ -9,58 +9,51 @@ import (
)
func ProjectGrantByProjectAndOrg(db *gorm.DB, table, projectID, orgID string) (*model.ProjectGrantView, error) {
project := new(model.ProjectGrantView)
projectGrant := new(model.ProjectGrantView)
projectIDQuery := model.ProjectGrantSearchQuery{Key: proj_model.GrantedProjectSearchKeyProjectID, Value: projectID, Method: global_model.SearchMethodEquals}
orgIDQuery := model.ProjectGrantSearchQuery{Key: proj_model.GrantedProjectSearchKeyOrgID, Value: orgID, Method: global_model.SearchMethodEquals}
query := repository.PrepareGetByQuery(table, projectIDQuery, orgIDQuery)
err := query(db, project)
return project, err
err := query(db, projectGrant)
return projectGrant, err
}
func ProjectGrantByID(db *gorm.DB, table, grantID string) (*model.ProjectGrantView, error) {
project := new(model.ProjectGrantView)
projectGrant := new(model.ProjectGrantView)
grantIDQuery := model.ProjectGrantSearchQuery{Key: proj_model.GrantedProjectSearchKeyGrantID, Value: grantID, Method: global_model.SearchMethodEquals}
query := repository.PrepareGetByQuery(table, grantIDQuery)
err := query(db, project)
return project, err
err := query(db, projectGrant)
return projectGrant, err
}
func ProjectGrantsByProjectID(db *gorm.DB, table, projectID string) ([]*model.ProjectGrantView, error) {
projects := make([]*model.ProjectGrantView, 0)
projectGrants := make([]*model.ProjectGrantView, 0)
queries := []*proj_model.ProjectGrantViewSearchQuery{
&proj_model.ProjectGrantViewSearchQuery{Key: proj_model.GrantedProjectSearchKeyProjectID, Value: projectID, Method: global_model.SearchMethodEquals},
{Key: proj_model.GrantedProjectSearchKeyProjectID, Value: projectID, Method: global_model.SearchMethodEquals},
}
query := repository.PrepareSearchQuery(table, model.ProjectGrantSearchRequest{Queries: queries})
_, err := query(db, &projects)
if err != nil {
return nil, err
}
return projects, nil
_, err := query(db, &projectGrants)
return projectGrants, err
}
func ProjectGrantsByProjectIDAndRoleKey(db *gorm.DB, table, projectID, roleKey string) ([]*model.ProjectGrantView, error) {
projects := make([]*model.ProjectGrantView, 0)
projectGrants := make([]*model.ProjectGrantView, 0)
queries := []*proj_model.ProjectGrantViewSearchQuery{
&proj_model.ProjectGrantViewSearchQuery{Key: proj_model.GrantedProjectSearchKeyProjectID, Value: projectID, Method: global_model.SearchMethodEquals},
&proj_model.ProjectGrantViewSearchQuery{Key: proj_model.GrantedProjectSearchKeyRoleKeys, Value: roleKey, Method: global_model.SearchMethodListContains},
{Key: proj_model.GrantedProjectSearchKeyProjectID, Value: projectID, Method: global_model.SearchMethodEquals},
{Key: proj_model.GrantedProjectSearchKeyRoleKeys, Value: roleKey, Method: global_model.SearchMethodListContains},
}
query := repository.PrepareSearchQuery(table, model.ProjectGrantSearchRequest{Queries: queries})
_, err := query(db, &projects)
if err != nil {
return nil, err
}
return projects, nil
_, err := query(db, &projectGrants)
return projectGrants, err
}
func SearchProjectGrants(db *gorm.DB, table string, req *proj_model.ProjectGrantViewSearchRequest) ([]*model.ProjectGrantView, int, error) {
projects := make([]*model.ProjectGrantView, 0)
projectGrants := make([]*model.ProjectGrantView, 0)
query := repository.PrepareSearchQuery(table, model.ProjectGrantSearchRequest{Limit: req.Limit, Offset: req.Offset, Queries: req.Queries})
count, err := query(db, &projects)
if err != nil {
return nil, 0, err
}
return projects, count, nil
count, err := query(db, &projectGrants)
return projectGrants, count, err
}
func PutProjectGrant(db *gorm.DB, table string, project *model.ProjectGrantView) error {

View File

@@ -14,7 +14,7 @@ type UserCache struct {
func StartCache(conf *config.CacheConfig) (*UserCache, error) {
userCache, err := conf.Config.NewCache()
logging.Log("EVENT-vDneN").OnError(err).Panic("unable to create user cache")
logging.Log("EVENT-vJG2j").OnError(err).Panic("unable to create user cache")
return &UserCache{userCache: userCache}, nil
}
@@ -22,7 +22,7 @@ func StartCache(conf *config.CacheConfig) (*UserCache, error) {
func (c *UserCache) getUser(ID string) *model.User {
user := &model.User{ObjectRoot: models.ObjectRoot{AggregateID: ID}}
if err := c.userCache.Get(ID, user); err != nil {
logging.Log("EVENT-4eTZh").WithError(err).Debug("error in getting cache")
logging.Log("EVENT-AtS0S").WithError(err).Debug("error in getting cache")
}
return user
}
@@ -30,6 +30,6 @@ func (c *UserCache) getUser(ID string) *model.User {
func (c *UserCache) cacheUser(user *model.User) {
err := c.userCache.Set(user.AggregateID, user)
if err != nil {
logging.Log("EVENT-ThnBb").WithError(err).Debug("error in setting project cache")
logging.Log("EVENT-0V2gX").WithError(err).Debug("error in setting project cache")
}
}

View File

@@ -14,7 +14,7 @@ type UserGrantCache struct {
func StartCache(conf *config.CacheConfig) (*UserGrantCache, error) {
userGrantCache, err := conf.Config.NewCache()
logging.Log("EVENT-vDneN").OnError(err).Panic("unable to create user cache")
logging.Log("EVENT-8EhUZ").OnError(err).Panic("unable to create user grant cache")
return &UserGrantCache{userGrantCache: userGrantCache}, nil
}
@@ -22,13 +22,13 @@ func StartCache(conf *config.CacheConfig) (*UserGrantCache, error) {
func (c *UserGrantCache) getUserGrant(ID string) *model.UserGrant {
user := &model.UserGrant{ObjectRoot: models.ObjectRoot{AggregateID: ID}}
err := c.userGrantCache.Get(ID, user)
logging.Log("EVENT-4eTZh").OnError(err).Debug("error in getting cache")
logging.Log("EVENT-QAd7T").OnError(err).Debug("error in getting cache")
return user
}
func (c *UserGrantCache) cacheUserGrant(grant *model.UserGrant) {
err := c.userGrantCache.Set(grant.AggregateID, grant)
logging.Log("EVENT-ThnBb").OnError(err).Debug("error in setting project cache")
logging.Log("EVENT-w2KNQ").OnError(err).Debug("error in setting user grant cache")
}

View File

@@ -2,6 +2,7 @@ package eventsourcing
import (
"context"
"github.com/caos/zitadel/internal/api/auth"
"github.com/caos/zitadel/internal/errors"
es_models "github.com/caos/zitadel/internal/eventstore/models"
@@ -209,10 +210,7 @@ func addUserGrantValidation(resourceOwner string, grant *model.UserGrant) func(.
if !existsUser {
return errors.ThrowPreconditionFailed(nil, "EVENT-Sl8uS", "user doesn't exist")
}
if err := checkProjectConditions(resourceOwner, grant, project); err != nil {
return err
}
return nil
return checkProjectConditions(resourceOwner, grant, project)
}
}