mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 23:27:31 +00:00
fix: bugs (#208)
* fix: add iam roles to permissions * fix: show state initial on usersearch * fix: search project roles returns only roles of project * fix: add project member owner on project create * fix: create new object oon failed event * feat: parse error body on chat message * feat: remove comment
This commit is contained in:
@@ -2,6 +2,8 @@ InternalAuthZ:
|
|||||||
RolePermissionMappings:
|
RolePermissionMappings:
|
||||||
- Role: 'IAM_OWNER'
|
- Role: 'IAM_OWNER'
|
||||||
Permissions:
|
Permissions:
|
||||||
|
- "iam.read"
|
||||||
|
- "iam.write"
|
||||||
- "org.read"
|
- "org.read"
|
||||||
- "org.write"
|
- "org.write"
|
||||||
- "org.member.read"
|
- "org.member.read"
|
||||||
|
@@ -36,7 +36,7 @@ export SMTP_PASSWORD=$(gopass zitadel-secrets/zitadel/google/emailappkey)
|
|||||||
export EMAIL_SENDER_ADDRESS=noreply@caos.ch
|
export EMAIL_SENDER_ADDRESS=noreply@caos.ch
|
||||||
export EMAIL_SENDER_NAME=CAOS AG
|
export EMAIL_SENDER_NAME=CAOS AG
|
||||||
export SMTP_TLS=TRUE
|
export SMTP_TLS=TRUE
|
||||||
export CHAT_URL=$(gopass zitadel-secrets/zitadel/dev/google-chat-url | base64 -D)
|
export CHAT_URL=$(gopass zitadel-secrets/zitadel/dev/google-chat-url)
|
||||||
|
|
||||||
#OIDC
|
#OIDC
|
||||||
export ZITADEL_ISSUER=http://localhost:50022
|
export ZITADEL_ISSUER=http://localhost:50022
|
||||||
|
@@ -3,8 +3,10 @@ package chat
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/caos/logging"
|
||||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||||
"github.com/caos/zitadel/internal/notification/providers"
|
"github.com/caos/zitadel/internal/notification/providers"
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
@@ -51,10 +53,19 @@ func (chat *Chat) SendMessage(message providers.Message) error {
|
|||||||
return caos_errs.ThrowInternal(err, "PROVI-s8uie", "Could not unmarshal content")
|
return caos_errs.ThrowInternal(err, "PROVI-s8uie", "Could not unmarshal content")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = http.Post(chat.URL.String(), "application/json; charset=UTF-8", bytes.NewReader(req))
|
response, err := http.Post(chat.URL.String(), "application/json; charset=UTF-8", bytes.NewReader(req))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return caos_errs.ThrowInternal(err, "PROVI-si93s", "unable to send message")
|
return caos_errs.ThrowInternal(err, "PROVI-si93s", "unable to send message")
|
||||||
}
|
}
|
||||||
|
if response.StatusCode != 200 {
|
||||||
|
defer response.Body.Close()
|
||||||
|
bodyBytes, err := ioutil.ReadAll(response.Body)
|
||||||
|
if err != nil {
|
||||||
|
return caos_errs.ThrowInternal(err, "PROVI-PSLd3", "unable to read response message")
|
||||||
|
}
|
||||||
|
logging.LogWithFields("PROVI-PS0kx", "Body", string(bodyBytes)).Warn("Chat Message post didnt get 200 OK")
|
||||||
|
return caos_errs.ThrowInternal(nil, "PROVI-LSopw", string(bodyBytes))
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -56,3 +56,6 @@ func (r *ProjectMemberSearchRequest) EnsureLimit(limit uint64) {
|
|||||||
r.Limit = limit
|
r.Limit = limit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func (r *ProjectMemberSearchRequest) AppendProjectQuery(projectID string) {
|
||||||
|
r.Queries = append(r.Queries, &ProjectMemberSearchQuery{Key: PROJECTMEMBERSEARCHKEY_PROJECT_ID, Method: model.SEARCHMETHOD_EQUALS, Value: projectID})
|
||||||
|
}
|
||||||
|
@@ -51,6 +51,9 @@ type ProjectRoleSearchResponse struct {
|
|||||||
func (r *ProjectRoleSearchRequest) AppendMyOrgQuery(orgID string) {
|
func (r *ProjectRoleSearchRequest) AppendMyOrgQuery(orgID string) {
|
||||||
r.Queries = append(r.Queries, &ProjectRoleSearchQuery{Key: PROJECTROLESEARCHKEY_ORGID, Method: model.SEARCHMETHOD_EQUALS, Value: orgID})
|
r.Queries = append(r.Queries, &ProjectRoleSearchQuery{Key: PROJECTROLESEARCHKEY_ORGID, Method: model.SEARCHMETHOD_EQUALS, Value: orgID})
|
||||||
}
|
}
|
||||||
|
func (r *ProjectRoleSearchRequest) AppendProjectQuery(projectID string) {
|
||||||
|
r.Queries = append(r.Queries, &ProjectRoleSearchQuery{Key: PROJECTROLESEARCHKEY_PROJECTID, Method: model.SEARCHMETHOD_EQUALS, Value: projectID})
|
||||||
|
}
|
||||||
|
|
||||||
func (r *ProjectRoleSearchRequest) EnsureLimit(limit uint64) {
|
func (r *ProjectRoleSearchRequest) EnsureLimit(limit uint64) {
|
||||||
if r.Limit == 0 || r.Limit > limit {
|
if r.Limit == 0 || r.Limit > limit {
|
||||||
|
@@ -2,6 +2,7 @@ package eventsourcing
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/caos/zitadel/internal/api/auth"
|
||||||
"github.com/caos/zitadel/internal/cache/config"
|
"github.com/caos/zitadel/internal/cache/config"
|
||||||
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
||||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||||
@@ -15,6 +16,10 @@ import (
|
|||||||
proj_model "github.com/caos/zitadel/internal/project/model"
|
proj_model "github.com/caos/zitadel/internal/project/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
projectOwnerRole = "PROJECT_OWNER"
|
||||||
|
)
|
||||||
|
|
||||||
type ProjectEventstore struct {
|
type ProjectEventstore struct {
|
||||||
es_int.Eventstore
|
es_int.Eventstore
|
||||||
projectCache *ProjectCache
|
projectCache *ProjectCache
|
||||||
@@ -70,8 +75,12 @@ func (es *ProjectEventstore) CreateProject(ctx context.Context, project *proj_mo
|
|||||||
project.AggregateID = id
|
project.AggregateID = id
|
||||||
project.State = proj_model.PROJECTSTATE_ACTIVE
|
project.State = proj_model.PROJECTSTATE_ACTIVE
|
||||||
repoProject := model.ProjectFromModel(project)
|
repoProject := model.ProjectFromModel(project)
|
||||||
|
member := &model.ProjectMember{
|
||||||
|
UserID: auth.GetCtxData(ctx).UserID,
|
||||||
|
Roles: []string{projectOwnerRole},
|
||||||
|
}
|
||||||
|
|
||||||
createAggregate := ProjectCreateAggregate(es.AggregateCreator(), repoProject)
|
createAggregate := ProjectCreateAggregate(es.AggregateCreator(), repoProject, member)
|
||||||
err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, createAggregate)
|
err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, createAggregate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@@ -33,10 +33,10 @@ func ProjectAggregate(ctx context.Context, aggCreator *es_models.AggregateCreato
|
|||||||
return aggCreator.NewAggregate(ctx, project.AggregateID, model.ProjectAggregate, model.ProjectVersion, project.Sequence)
|
return aggCreator.NewAggregate(ctx, project.AggregateID, model.ProjectAggregate, model.ProjectVersion, project.Sequence)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProjectCreateAggregate(aggCreator *es_models.AggregateCreator, project *model.Project) func(ctx context.Context) (*es_models.Aggregate, error) {
|
func ProjectCreateAggregate(aggCreator *es_models.AggregateCreator, project *model.Project, member *model.ProjectMember) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
if project == nil {
|
if project == nil || member == nil {
|
||||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-kdie6", "project should not be nil")
|
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-kdie6", "project and member should not be nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
agg, err := ProjectAggregate(ctx, aggCreator, project)
|
agg, err := ProjectAggregate(ctx, aggCreator, project)
|
||||||
@@ -48,7 +48,11 @@ func ProjectCreateAggregate(aggCreator *es_models.AggregateCreator, project *mod
|
|||||||
EventTypesFilter(model.ProjectAdded, model.ProjectChanged, model.ProjectRemoved)
|
EventTypesFilter(model.ProjectAdded, model.ProjectChanged, model.ProjectRemoved)
|
||||||
|
|
||||||
validation := addProjectValidation(project.Name)
|
validation := addProjectValidation(project.Name)
|
||||||
return agg.SetPrecondition(validationQuery, validation).AppendEvent(model.ProjectAdded, project)
|
agg, err = agg.SetPrecondition(validationQuery, validation).AppendEvent(model.ProjectAdded, project)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return agg.AppendEvent(model.ProjectMemberAdded, member)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -488,7 +492,7 @@ func addProjectValidation(projectName string) func(...*es_models.Event) error {
|
|||||||
}
|
}
|
||||||
for _, p := range projects {
|
for _, p := range projects {
|
||||||
if p.Name == projectName {
|
if p.Name == projectName {
|
||||||
return errors.ThrowPreconditionFailed(nil, "EVENT-s9oPw", "conditions not met")
|
return errors.ThrowPreconditionFailed(nil, "EVENT-s9oPw", "project already exists on resourceowner")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@@ -164,11 +164,12 @@ func TestProjectCreateAggregate(t *testing.T) {
|
|||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
new *model.Project
|
new *model.Project
|
||||||
|
member *model.ProjectMember
|
||||||
aggCreator *models.AggregateCreator
|
aggCreator *models.AggregateCreator
|
||||||
}
|
}
|
||||||
type res struct {
|
type res struct {
|
||||||
eventLen int
|
eventLen int
|
||||||
eventType models.EventType
|
eventType []models.EventType
|
||||||
wantErr bool
|
wantErr bool
|
||||||
errFunc func(err error) bool
|
errFunc func(err error) bool
|
||||||
}
|
}
|
||||||
@@ -182,11 +183,12 @@ func TestProjectCreateAggregate(t *testing.T) {
|
|||||||
args: args{
|
args: args{
|
||||||
ctx: auth.NewMockContext("orgID", "userID"),
|
ctx: auth.NewMockContext("orgID", "userID"),
|
||||||
new: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.PROJECTSTATE_ACTIVE)},
|
new: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.PROJECTSTATE_ACTIVE)},
|
||||||
|
member: &model.ProjectMember{UserID: "UserID"},
|
||||||
aggCreator: models.NewAggregateCreator("Test"),
|
aggCreator: models.NewAggregateCreator("Test"),
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
eventLen: 1,
|
eventLen: 2,
|
||||||
eventType: model.ProjectAdded,
|
eventType: []models.EventType{model.ProjectAdded, model.ProjectMemberAdded},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -194,11 +196,23 @@ func TestProjectCreateAggregate(t *testing.T) {
|
|||||||
args: args{
|
args: args{
|
||||||
ctx: auth.NewMockContext("orgID", "userID"),
|
ctx: auth.NewMockContext("orgID", "userID"),
|
||||||
new: nil,
|
new: nil,
|
||||||
|
member: &model.ProjectMember{UserID: "UserID"},
|
||||||
|
aggCreator: models.NewAggregateCreator("Test"),
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
wantErr: true,
|
||||||
|
errFunc: caos_errs.IsPreconditionFailed,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "new member nil",
|
||||||
|
args: args{
|
||||||
|
ctx: auth.NewMockContext("orgID", "userID"),
|
||||||
|
new: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.PROJECTSTATE_ACTIVE)},
|
||||||
|
member: nil,
|
||||||
aggCreator: models.NewAggregateCreator("Test"),
|
aggCreator: models.NewAggregateCreator("Test"),
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
eventLen: 1,
|
|
||||||
eventType: model.ProjectAdded,
|
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
errFunc: caos_errs.IsPreconditionFailed,
|
errFunc: caos_errs.IsPreconditionFailed,
|
||||||
},
|
},
|
||||||
@@ -206,17 +220,23 @@ func TestProjectCreateAggregate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
agg, err := ProjectCreateAggregate(tt.args.aggCreator, tt.args.new)(tt.args.ctx)
|
agg, err := ProjectCreateAggregate(tt.args.aggCreator, tt.args.new, tt.args.member)(tt.args.ctx)
|
||||||
|
|
||||||
if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen {
|
if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen {
|
||||||
t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events))
|
t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events))
|
||||||
}
|
}
|
||||||
if !tt.res.wantErr && agg.Events[0].Type != tt.res.eventType {
|
|
||||||
t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String())
|
if !tt.res.wantErr {
|
||||||
|
for i, _ := range agg.Events {
|
||||||
|
if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventType[i] {
|
||||||
|
t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[i].Type.String())
|
||||||
}
|
}
|
||||||
if !tt.res.wantErr && agg.Events[0].Data == nil {
|
if !tt.res.wantErr && agg.Events[i].Data == nil {
|
||||||
t.Errorf("should have data in event")
|
t.Errorf("should have data in event")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if tt.res.wantErr && !tt.res.errFunc(err) {
|
if tt.res.wantErr && !tt.res.errFunc(err) {
|
||||||
t.Errorf("got wrong err: %v ", err)
|
t.Errorf("got wrong err: %v ", err)
|
||||||
}
|
}
|
||||||
|
@@ -81,10 +81,11 @@ func LatestFailedEvent(db *gorm.DB, table, viewName string, sequence uint64) (*F
|
|||||||
}
|
}
|
||||||
|
|
||||||
if errors.IsNotFound(err) {
|
if errors.IsNotFound(err) {
|
||||||
failedEvent.ViewName = viewName
|
return &FailedEvent{
|
||||||
failedEvent.FailedSequence = sequence
|
ViewName: viewName,
|
||||||
failedEvent.FailureCount = 0
|
FailedSequence: sequence,
|
||||||
return failedEvent, nil
|
FailureCount: 0,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
return nil, errors.ThrowInternalf(err, "VIEW-9LyCB", "unable to get failed events of %s", viewName)
|
return nil, errors.ThrowInternalf(err, "VIEW-9LyCB", "unable to get failed events of %s", viewName)
|
||||||
|
|
||||||
|
@@ -3,6 +3,7 @@ package grpc
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/caos/zitadel/internal/api"
|
"github.com/caos/zitadel/internal/api"
|
||||||
|
"github.com/caos/zitadel/internal/api/auth"
|
||||||
grpc_util "github.com/caos/zitadel/internal/api/grpc"
|
grpc_util "github.com/caos/zitadel/internal/api/grpc"
|
||||||
"github.com/caos/zitadel/internal/errors"
|
"github.com/caos/zitadel/internal/errors"
|
||||||
"github.com/golang/protobuf/ptypes/empty"
|
"github.com/golang/protobuf/ptypes/empty"
|
||||||
@@ -104,8 +105,8 @@ func (s *Server) RemoveProjectRole(ctx context.Context, in *ProjectRoleRemove) (
|
|||||||
|
|
||||||
func (s *Server) SearchProjectRoles(ctx context.Context, in *ProjectRoleSearchRequest) (*ProjectRoleSearchResponse, error) {
|
func (s *Server) SearchProjectRoles(ctx context.Context, in *ProjectRoleSearchRequest) (*ProjectRoleSearchResponse, error) {
|
||||||
request := projectRoleSearchRequestsToModel(in)
|
request := projectRoleSearchRequestsToModel(in)
|
||||||
orgID := grpc_util.GetHeader(ctx, api.ZitadelOrgID)
|
request.AppendMyOrgQuery(auth.GetCtxData(ctx).OrgID)
|
||||||
request.AppendMyOrgQuery(orgID)
|
request.AppendProjectQuery(in.ProjectId)
|
||||||
response, err := s.project.SearchProjectRoles(ctx, request)
|
response, err := s.project.SearchProjectRoles(ctx, request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@@ -2,7 +2,6 @@ package grpc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/golang/protobuf/ptypes/empty"
|
"github.com/golang/protobuf/ptypes/empty"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -11,7 +10,9 @@ func (s *Server) GetProjectMemberRoles(ctx context.Context, _ *empty.Empty) (*Pr
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) SearchProjectMembers(ctx context.Context, in *ProjectMemberSearchRequest) (*ProjectMemberSearchResponse, error) {
|
func (s *Server) SearchProjectMembers(ctx context.Context, in *ProjectMemberSearchRequest) (*ProjectMemberSearchResponse, error) {
|
||||||
response, err := s.project.SearchProjectMembers(ctx, projectMemberSearchRequestsToModel(in))
|
request := projectMemberSearchRequestsToModel(in)
|
||||||
|
request.AppendProjectQuery(in.ProjectId)
|
||||||
|
response, err := s.project.SearchProjectMembers(ctx, request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@@ -341,6 +341,10 @@ func userStateFromModel(state usr_model.UserState) UserState {
|
|||||||
return UserState_USERSTATE_INACTIVE
|
return UserState_USERSTATE_INACTIVE
|
||||||
case usr_model.USERSTATE_LOCKED:
|
case usr_model.USERSTATE_LOCKED:
|
||||||
return UserState_USERSTATE_LOCKED
|
return UserState_USERSTATE_LOCKED
|
||||||
|
case usr_model.USERSTATE_INITIAL:
|
||||||
|
return UserState_USERSTATE_INITIAL
|
||||||
|
case usr_model.USERSTATE_SUSPEND:
|
||||||
|
return UserState_USERSTATE_SUSPEND
|
||||||
default:
|
default:
|
||||||
return UserState_USERSTATE_UNSPECIFIED
|
return UserState_USERSTATE_UNSPECIFIED
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user