From b0081599fd904865278791b3ff922b2638a2752b Mon Sep 17 00:00:00 2001 From: Ryan Oberlander Date: Thu, 16 Feb 2023 11:44:03 -0600 Subject: [PATCH] fix more errors from removing clientID [#346] --- .secrets.baseline | 11 +- core/application.go | 4 +- core/interfaces.go | 119 +++++++++-------- core/model/authman.go | 24 ++-- core/model/event.go | 2 + core/services.go | 157 +++++++++++++++------- driven/authman/adapter.go | 44 ++---- driven/corebb/adapter.go | 25 +--- driven/rewards/adapter.go | 4 +- driven/storage/adapter.go | 251 ++++++++++++++--------------------- driver/web/rest/adminapis.go | 12 +- driver/web/rest/apis.go | 198 ++++++++------------------- driver/web/rest/internal.go | 47 +++---- 13 files changed, 387 insertions(+), 511 deletions(-) diff --git a/.secrets.baseline b/.secrets.baseline index feca059c..22856d7a 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -117,6 +117,15 @@ "line_number": 23 } ], + "driven/authman/adapter.go": [ + { + "type": "Secret Keyword", + "filename": "driven/authman/adapter.go", + "hashed_secret": "941b2c7dc20fdba5a806569a85d022d4fc919525", + "is_verified": false, + "line_number": 39 + } + ], "driven/rewards/adapter.go": [ { "type": "Secret Keyword", @@ -180,5 +189,5 @@ } ] }, - "generated_at": "2023-02-15T23:05:12Z" + "generated_at": "2023-02-16T17:43:38Z" } diff --git a/core/application.go b/core/application.go index b41c5b95..6217ae1d 100644 --- a/core/application.go +++ b/core/application.go @@ -82,8 +82,8 @@ func (app *Application) FindUser(appID string, orgID string, id *string, externa } // LoginUser refactors the user using the new id -func (app *Application) LoginUser(clientID string, current *model.User, newID string) error { - return app.storage.LoginUser(clientID, current) +func (app *Application) LoginUser(current *model.User) error { + return app.storage.LoginUser(current) } // CreateUser creates an user diff --git a/core/interfaces.go b/core/interfaces.go index ca3576e6..bb4920d7 100644 --- a/core/interfaces.go +++ b/core/interfaces.go @@ -28,21 +28,21 @@ import ( type Services interface { GetVersion() string - LoginUser(clientID string, currentGetUserGroups *model.User) error + LoginUser(current *model.User) error // TODO: Deprecate this method due to missed CurrentMember! - GetGroupEntity(clientID string, id string) (*model.Group, error) - GetGroupEntityByTitle(clientID string, title string) (*model.Group, error) + GetGroupEntity(appID string, orgID string, id string) (*model.Group, error) + GetGroupEntityByTitle(appID string, orgID string, title string) (*model.Group, error) IsGroupAdmin(clientID string, groupID string, userID string) (bool, error) - CreateGroup(clientID string, current *model.User, group *model.Group) (*string, *utils.GroupError) - UpdateGroup(clientID string, current *model.User, group *model.Group) *utils.GroupError - UpdateGroupDateUpdated(clientID string, groupID string) error - DeleteGroup(clientID string, current *model.User, id string) error + CreateGroup(current *model.User, group *model.Group) (*string, *utils.GroupError) + UpdateGroup(userID *string, group *model.Group) *utils.GroupError + UpdateGroupDateUpdated(appID string, orgID string, groupID string) error + DeleteGroup(appID string, orgID string, id string) error GetAllGroups(appID string, orgID string) ([]model.Group, error) GetGroups(userID *string, filter model.GroupsFilter) ([]model.Group, error) GetUserGroups(userID string, filter model.GroupsFilter) ([]model.Group, error) - DeleteUser(clientID string, current *model.User) error + DeleteUser(current *model.User) error GetGroup(current *model.User, id string) (*model.Group, error) GetGroupStats(clientID string, id string) (*model.GroupStats, error) @@ -50,19 +50,19 @@ type Services interface { ApplyMembershipApproval(clientID string, current *model.User, membershipID string, approve bool, rejectReason string) error UpdateMembership(membership *model.GroupMembership, status *string, dateAttended *time.Time, notificationsPreferences *model.NotificationsPreferences) error - GetEvents(clientID string, current *model.User, groupID string, filterByToMembers bool) ([]model.Event, error) - CreateEvent(clientID string, current *model.User, eventID string, group *model.Group, toMemberList []model.ToMember, creator *model.Creator) (*model.Event, error) + GetEvents(current *model.User, groupID string, filterByToMembers bool) ([]model.Event, error) + CreateEvent(appID string, orgID string, eventID string, group *model.Group, toMemberList []model.ToMember, creator *model.Creator) (*model.Event, error) UpdateEvent(clientID string, current *model.User, eventID string, groupID string, toMemberList []model.ToMember) error - DeleteEvent(clientID string, current *model.User, eventID string, groupID string) error + DeleteEvent(appID string, orgID string, eventID string, groupID string) error - GetPosts(clientID string, current *model.User, groupID string, filterPrivatePostsValue *bool, filterByToMembers bool, offset *int64, limit *int64, order *string) ([]*model.Post, error) + GetPosts(current *model.User, groupID string, filterPrivatePostsValue *bool, filterByToMembers bool, offset *int64, limit *int64, order *string) ([]*model.Post, error) GetPost(clientID string, userID *string, groupID string, postID string, skipMembershipCheck bool, filterByToMembers bool) (*model.Post, error) - GetUserPostCount(clientID string, userID string) (*int64, error) + GetUserPostCount(appID string, orgID string, userID string) (*int64, error) CreatePost(clientID string, current *model.User, post *model.Post, group *model.Group) (*model.Post, error) UpdatePost(clientID string, current *model.User, group *model.Group, post *model.Post) (*model.Post, error) ReactToPost(clientID string, current *model.User, groupID string, postID string, reaction string) error ReportPostAsAbuse(current *model.User, group *model.Group, post *model.Post, comment string, sendToDean bool, sendToGroupAdmins bool) error - DeletePost(clientID string, current *model.User, groupID string, postID string, force bool) error + DeletePost(current *model.User, groupID string, postID string, force bool) error SynchronizeAuthman(appID string, orgID string) error SynchronizeAuthmanGroup(appID string, orgID string, groupID string) error @@ -71,7 +71,7 @@ type Services interface { CheckUserGroupMembershipPermission(current *model.User, groupID string) (*model.Group, bool) FindGroupsV3(filter model.GroupsFilter) ([]model.Group, error) FindGroupMemberships(filter model.MembershipFilter) (model.MembershipCollection, error) - FindGroupMembership(clientID string, groupID string, userID string) (*model.GroupMembership, error) + FindGroupMembership(appID string, orgID string, groupID string, userID string) (*model.GroupMembership, error) FindGroupMembershipByID(appID string, orgID string, id string) (*model.GroupMembership, error) FindUserGroupMemberships(appID string, orgID string, userID string) (model.MembershipCollection, error) CreateMembership(current *model.User, group *model.Group, membership *model.GroupMembership) error @@ -94,32 +94,32 @@ func (s *servicesImpl) GetVersion() string { } // TODO: Deprecate this method due to missed CurrentMember! -func (s *servicesImpl) GetGroupEntity(clientID string, id string) (*model.Group, error) { - return s.app.getGroupEntity(clientID, id) +func (s *servicesImpl) GetGroupEntity(appID string, orgID string, id string) (*model.Group, error) { + return s.app.getGroupEntity(appID, orgID, id) } -func (s *servicesImpl) GetGroupEntityByTitle(clientID string, title string) (*model.Group, error) { - return s.app.getGroupEntityByTitle(clientID, title) +func (s *servicesImpl) GetGroupEntityByTitle(appID string, orgID string, title string) (*model.Group, error) { + return s.app.getGroupEntityByTitle(appID, orgID, title) } func (s *servicesImpl) IsGroupAdmin(clientID string, groupID string, userID string) (bool, error) { return s.app.isGroupAdmin(clientID, groupID, userID) } -func (s *servicesImpl) CreateGroup(clientID string, current *model.User, group *model.Group) (*string, *utils.GroupError) { - return s.app.createGroup(clientID, current, group) +func (s *servicesImpl) CreateGroup(current *model.User, group *model.Group) (*string, *utils.GroupError) { + return s.app.createGroup(current, group) } -func (s *servicesImpl) UpdateGroup(clientID string, current *model.User, group *model.Group) *utils.GroupError { - return s.app.updateGroup(clientID, current, group) +func (s *servicesImpl) UpdateGroup(userID *string, group *model.Group) *utils.GroupError { + return s.app.updateGroup(userID, group) } -func (s *servicesImpl) UpdateGroupDateUpdated(clientID string, groupID string) error { - return s.app.updateGroupDateUpdated(clientID, groupID) +func (s *servicesImpl) UpdateGroupDateUpdated(appID string, orgID string, groupID string) error { + return s.app.updateGroupDateUpdated(appID, orgID, groupID) } -func (s *servicesImpl) DeleteGroup(clientID string, current *model.User, id string) error { - return s.app.deleteGroup(clientID, current, id) +func (s *servicesImpl) DeleteGroup(appID string, orgID, id string) error { + return s.app.deleteGroup(appID, orgID, id) } func (s *servicesImpl) GetGroups(userID *string, filter model.GroupsFilter) ([]model.Group, error) { @@ -134,12 +134,12 @@ func (s *servicesImpl) GetUserGroups(userID string, filter model.GroupsFilter) ( return s.app.getUserGroups(userID, filter) } -func (s *servicesImpl) LoginUser(clientID string, current *model.User) error { - return s.app.loginUser(clientID, current) +func (s *servicesImpl) LoginUser(current *model.User) error { + return s.app.storage.LoginUser(current) } -func (s *servicesImpl) DeleteUser(clientID string, current *model.User) error { - return s.app.deleteUser(clientID, current) +func (s *servicesImpl) DeleteUser(current *model.User) error { + return s.app.deleteUser(current) } func (s *servicesImpl) GetGroup(current *model.User, id string) (*model.Group, error) { @@ -158,32 +158,32 @@ func (s *servicesImpl) UpdateMembership(membership *model.GroupMembership, statu return s.app.updateMembership(membership, status, dateAttended, notificationsPreferences) } -func (s *servicesImpl) GetEvents(clientID string, current *model.User, groupID string, filterByToMembers bool) ([]model.Event, error) { - return s.app.getEvents(clientID, current, groupID, filterByToMembers) +func (s *servicesImpl) GetEvents(current *model.User, groupID string, filterByToMembers bool) ([]model.Event, error) { + return s.app.getEvents(current, groupID, filterByToMembers) } -func (s *servicesImpl) CreateEvent(clientID string, current *model.User, eventID string, group *model.Group, toMemberList []model.ToMember, creator *model.Creator) (*model.Event, error) { - return s.app.createEvent(clientID, current, eventID, group, toMemberList, creator) +func (s *servicesImpl) CreateEvent(appID string, orgID string, eventID string, group *model.Group, toMemberList []model.ToMember, creator *model.Creator) (*model.Event, error) { + return s.app.createEvent(appID, orgID, eventID, group, toMemberList, creator) } func (s *servicesImpl) UpdateEvent(clientID string, current *model.User, eventID string, groupID string, toMemberList []model.ToMember) error { return s.app.updateEvent(clientID, current, eventID, groupID, toMemberList) } -func (s *servicesImpl) DeleteEvent(clientID string, current *model.User, eventID string, groupID string) error { - return s.app.deleteEvent(clientID, current, eventID, groupID) +func (s *servicesImpl) DeleteEvent(appID string, orgID string, eventID string, groupID string) error { + return s.app.deleteEvent(appID, orgID, eventID, groupID) } -func (s *servicesImpl) GetPosts(clientID string, current *model.User, groupID string, filterPrivatePostsValue *bool, filterByToMembers bool, offset *int64, limit *int64, order *string) ([]*model.Post, error) { - return s.app.getPosts(clientID, current, groupID, filterPrivatePostsValue, filterByToMembers, offset, limit, order) +func (s *servicesImpl) GetPosts(current *model.User, groupID string, filterPrivatePostsValue *bool, filterByToMembers bool, offset *int64, limit *int64, order *string) ([]*model.Post, error) { + return s.app.getPosts(current, groupID, filterPrivatePostsValue, filterByToMembers, offset, limit, order) } func (s *servicesImpl) GetPost(clientID string, userID *string, groupID string, postID string, skipMembershipCheck bool, filterByToMembers bool) (*model.Post, error) { return s.app.getPost(clientID, userID, groupID, postID, skipMembershipCheck, filterByToMembers) } -func (s *servicesImpl) GetUserPostCount(clientID string, userID string) (*int64, error) { - return s.app.getUserPostCount(clientID, userID) +func (s *servicesImpl) GetUserPostCount(appID string, orgID string, userID string) (*int64, error) { + return s.app.storage.GetUserPostCount(appID, orgID, userID) } func (s *servicesImpl) CreatePost(clientID string, current *model.User, post *model.Post, group *model.Group) (*model.Post, error) { @@ -202,8 +202,8 @@ func (s *servicesImpl) ReportPostAsAbuse(current *model.User, group *model.Group return s.app.reportPostAsAbuse(current, group, post, comment, sendToDean, sendToGroupAdmins) } -func (s *servicesImpl) DeletePost(clientID string, current *model.User, groupID string, postID string, force bool) error { - return s.app.deletePost(clientID, current.ID, groupID, postID, force) +func (s *servicesImpl) DeletePost(current *model.User, groupID string, postID string, force bool) error { + return s.app.deletePost(nil, current.AppID, current.OrgID, current.ID, groupID, postID, force) } func (s *servicesImpl) SynchronizeAuthman(appID string, orgID string) error { @@ -228,8 +228,8 @@ func (s *servicesImpl) FindGroupMemberships(filter model.MembershipFilter) (mode return s.app.findGroupMemberships(filter) } -func (s *servicesImpl) FindGroupMembership(clientID string, groupID string, userID string) (*model.GroupMembership, error) { - return s.app.findGroupMembership(clientID, groupID, userID) +func (s *servicesImpl) FindGroupMembership(appID string, orgID string, groupID string, userID string) (*model.GroupMembership, error) { + return s.app.storage.FindGroupMembershipWithContext(nil, appID, orgID, groupID, userID) } func (s *servicesImpl) FindGroupMembershipByID(appID string, orgID string, id string) (*model.GroupMembership, error) { @@ -325,36 +325,37 @@ type Storage interface { FindUser(appID string, orgID string, id string, external bool) (*model.User, error) FindUsers(clientID string, ids []string, external bool) ([]model.User, error) - GetUserPostCount(clientID string, userID string) (*int64, error) - LoginUser(clientID string, current *model.User) error + FindAllUserPosts(context storage.TransactionContext, appID string, orgID string, userID string) ([]model.Post, error) + GetUserPostCount(appID string, orgID string, userID string) (*int64, error) + LoginUser(current *model.User) error CreateUser(id string, appID string, orgID string, externalID string, email string, name string) (*model.User, error) - DeleteUser(appID string, orgID string, userID string) error + DeleteUserWithContext(context storage.TransactionContext, appID string, orgID string, userID string) error - CreateGroup(clientID string, current *model.User, group *model.Group, memberships []model.GroupMembership) (*string, *utils.GroupError) - UpdateGroupWithMemberships(clientID string, current *model.User, group *model.Group, memberships []model.GroupMembership) *utils.GroupError + CreateGroup(current *model.User, group *model.Group, memberships []model.GroupMembership) (*string, *utils.GroupError) + UpdateGroup(userID *string, group *model.Group, memberships []model.GroupMembership) *utils.GroupError UpdateGroupSyncTimes(context storage.TransactionContext, clientID string, group *model.Group) error UpdateGroupStats(context storage.TransactionContext, appID string, orgID string, id string, resetUpdateDate bool, resetMembershipUpdateDate bool, resetManagedMembershipUpdateDate bool, resetStats bool) error - UpdateGroupDateUpdated(clientID string, groupID string) error - DeleteGroup(clientID string, id string) error + UpdateGroupDateUpdated(appID string, orgID string, groupID string) error + DeleteGroup(appID string, orgID string, id string) error FindGroupWithContext(context storage.TransactionContext, appID string, orgID string, groupID string, userID *string) (*model.Group, error) - FindGroupByTitle(clientID string, title string) (*model.Group, error) + FindGroupByTitle(appID string, orgID string, title string) (*model.Group, error) FindGroups(userID *string, filter model.GroupsFilter) ([]model.Group, error) FindUserGroups(userID string, filter model.GroupsFilter) ([]model.Group, error) FindUserGroupsCount(clientID string, userID string) (*int64, error) - FindEvents(clientID string, current *model.User, groupID string, filterByToMembers bool) ([]model.Event, error) - CreateEvent(clientID string, eventID string, groupID string, toMemberList []model.ToMember, creator *model.Creator) (*model.Event, error) + FindEvents(current *model.User, groupID string, filterByToMembers bool) ([]model.Event, error) + CreateEvent(appID string, orgID string, eventID string, groupID string, toMemberList []model.ToMember, creator *model.Creator) (*model.Event, error) UpdateEvent(clientID string, eventID string, groupID string, toMemberList []model.ToMember) error - DeleteEvent(clientID string, eventID string, groupID string) error + DeleteEventWithContext(context storage.TransactionContext, appID string, orgID string, eventID string, groupID string) error - FindPosts(clientID string, current *model.User, groupID string, filterPrivatePostsValue *bool, filterByToMembers bool, offset *int64, limit *int64, order *string) ([]*model.Post, error) + FindPosts(current *model.User, groupID string, filterPrivatePostsValue *bool, filterByToMembers bool, offset *int64, limit *int64, order *string) ([]*model.Post, error) FindPost(context storage.TransactionContext, clientID string, userID *string, groupID string, postID string, skipMembershipCheck bool, filterByToMembers bool) (*model.Post, error) FindPostsByParentID(context storage.TransactionContext, clientID string, userID string, groupID string, parentID string, skipMembershipCheck bool, filterByToMembers bool, recursive bool, order *string) ([]*model.Post, error) CreatePost(clientID string, current *model.User, post *model.Post) (*model.Post, error) UpdatePost(clientID string, userID string, post *model.Post) (*model.Post, error) ReportPostAsAbuse(post *model.Post) error ReactToPost(context storage.TransactionContext, userID string, postID string, reaction string, on bool) error - DeletePost(ctx storage.TransactionContext, clientID string, userID string, groupID string, postID string, force bool) error + DeletePost(ctx storage.TransactionContext, appID string, orgID string, userID string, groupID string, postID string, force bool) error FindAuthmanGroups(clientID string) ([]model.Group, error) FindAuthmanGroupByKey(clientID string, authmanGroupKey string) (*model.Group, error) @@ -398,7 +399,7 @@ type Notifications interface { type Authman interface { RetrieveAuthmanGroupMembers(groupName string) ([]string, error) RetrieveAuthmanUsers(externalIDs []string) (map[string]model.AuthmanSubject, error) - RetrieveAuthmanStemGroups(stemName string) (*model.АuthmanGroupsResponse, error) + RetrieveAuthmanStemGroups(stemName string) (*model.AuthmanGroupsResponse, error) AddAuthmanMemberToGroup(groupName string, uin string) error RemoveAuthmanMemberFromGroup(groupName string, uin string) error } diff --git a/core/model/authman.go b/core/model/authman.go index ffe709c3..9f8fb96a 100644 --- a/core/model/authman.go +++ b/core/model/authman.go @@ -59,25 +59,25 @@ type AuthmanGroupResponse struct { } `json:"WsGetMembersLiteResult"` } -// АuthmanUserRequest Authman user request wrapper -type АuthmanUserRequest struct { - WsRestGetSubjectsRequest АuthmanUserData `json:"WsRestGetSubjectsRequest"` +// AuthmanUserRequest Authman user request wrapper +type AuthmanUserRequest struct { + WsRestGetSubjectsRequest AuthmanUserData `json:"WsRestGetSubjectsRequest"` } -// АuthmanUserData Authman user data -type АuthmanUserData struct { - WsSubjectLookups []АuthmanSubjectLookup `json:"wsSubjectLookups"` +// AuthmanUserData Authman user data +type AuthmanUserData struct { + WsSubjectLookups []AuthmanSubjectLookup `json:"wsSubjectLookups"` SubjectAttributeNames []string `json:"subjectAttributeNames"` } -// АuthmanSubjectLookup Authman subject lookup -type АuthmanSubjectLookup struct { +// AuthmanSubjectLookup Authman subject lookup +type AuthmanSubjectLookup struct { SubjectID string `json:"subjectId"` SubjectSourceID string `json:"subjectSourceId"` } -// АuthmanUserResponse Authman user response wrapper -type АuthmanUserResponse struct { +// AuthmanUserResponse Authman user response wrapper +type AuthmanUserResponse struct { WsGetSubjectsResults struct { ResultMetadata struct { Success string `json:"success"` @@ -93,8 +93,8 @@ type АuthmanUserResponse struct { } `json:"WsGetSubjectsResults"` } -// АuthmanGroupsResponse Authman groups response wrapper -type АuthmanGroupsResponse struct { +// AuthmanGroupsResponse Authman groups response wrapper +type AuthmanGroupsResponse struct { WsFindGroupsResults struct { GroupResults []AuthmanGroupEntry `json:"groupResults"` ResultMetadata struct { diff --git a/core/model/event.go b/core/model/event.go index 39d15629..04548397 100644 --- a/core/model/event.go +++ b/core/model/event.go @@ -22,6 +22,8 @@ import ( // Event represents event entity type Event struct { ClientID string `json:"client_id" bson:"client_id"` + AppID string `json:"app_id" bson:"app_id"` + OrgID string `json:"org_id" bson:"org_id"` EventID string `json:"event_id" bson:"event_id"` GroupID string `json:"group_id" bson:"group_id"` DateCreated time.Time `json:"date_created" bson:"date_created"` diff --git a/core/services.go b/core/services.go index 990d68a1..20e4f023 100644 --- a/core/services.go +++ b/core/services.go @@ -56,16 +56,16 @@ func (app *Application) getVersion() string { return app.version } -func (app *Application) getGroupEntity(clientID string, id string) (*model.Group, error) { - group, err := app.storage.FindGroup(nil, clientID, id, nil) +func (app *Application) getGroupEntity(appID string, orgID string, id string) (*model.Group, error) { + group, err := app.storage.FindGroupWithContext(nil, appID, orgID, id, nil) if err != nil { return nil, err } return group, nil } -func (app *Application) getGroupEntityByTitle(clientID string, title string) (*model.Group, error) { - group, err := app.storage.FindGroupByTitle(clientID, title) +func (app *Application) getGroupEntityByTitle(appID string, orgID string, title string) (*model.Group, error) { + group, err := app.storage.FindGroupByTitle(appID, orgID, title) if err != nil { return nil, err } @@ -84,8 +84,8 @@ func (app *Application) isGroupAdmin(clientID string, groupID string, userID str return true, nil } -func (app *Application) createGroup(clientID string, current *model.User, group *model.Group) (*string, *utils.GroupError) { - insertedID, err := app.storage.CreateGroup(clientID, current, group, nil) +func (app *Application) createGroup(current *model.User, group *model.Group) (*string, *utils.GroupError) { + insertedID, err := app.storage.CreateGroup(current, group, nil) if err != nil { return nil, err } @@ -122,25 +122,25 @@ func (app *Application) createGroup(clientID string, current *model.User, group return insertedID, nil } -func (app *Application) updateGroup(clientID string, current *model.User, group *model.Group) *utils.GroupError { +func (app *Application) updateGroup(userID *string, group *model.Group) *utils.GroupError { - err := app.storage.UpdateGroup(clientID, current, group) + err := app.storage.UpdateGroup(userID, group, nil) if err != nil { return err } return nil } -func (app *Application) updateGroupDateUpdated(clientID string, groupID string) error { - err := app.storage.UpdateGroupDateUpdated(clientID, groupID) +func (app *Application) updateGroupDateUpdated(appID string, orgID string, groupID string) error { + err := app.storage.UpdateGroupDateUpdated(appID, orgID, groupID) if err != nil { return err } return nil } -func (app *Application) deleteGroup(clientID string, current *model.User, id string) error { - err := app.storage.DeleteGroup(clientID, id) +func (app *Application) deleteGroup(appID string, orgID string, id string) error { + err := app.storage.DeleteGroup(appID, orgID, id) if err != nil { return err } @@ -177,12 +177,37 @@ func (app *Application) getUserGroups(userID string, filter model.GroupsFilter) return groups, nil } -func (app *Application) loginUser(clientID string, current *model.User) error { - return app.storage.LoginUser(clientID, current) -} +func (app *Application) deleteUser(current *model.User) error { + return app.storage.PerformTransaction(func(sessionContext storage.TransactionContext) error { + posts, err := app.storage.FindAllUserPosts(sessionContext, current.AppID, current.OrgID, current.ID) + if err != nil { + log.Printf("error on find all posts for user (%s) - %s", current.ID, err.Error()) + return err + } + for _, post := range posts { + err = app.deletePost(sessionContext, current.AppID, current.OrgID, current.ID, post.GroupID, post.ID, true) + if err != nil { + log.Printf("error on delete all posts for user (%s) - %s", current.ID, err.Error()) + return err + } + } + + memberships, err := app.storage.FindGroupMembershipsWithContext(sessionContext, model.MembershipFilter{AppID: current.AppID, OrgID: current.OrgID, UserID: ¤t.ID}) + if err != nil { + log.Printf("error getting user memberships - %s", err.Error()) + return err + } + for _, membership := range memberships.Items { + err = app.storage.DeleteMembershipWithContext(sessionContext, membership.AppID, membership.OrgID, membership.GroupID, membership.UserID) + if err != nil { + log.Printf("error deleting user membership - %s", err.Error()) + return err + } + } + + return app.storage.DeleteUserWithContext(sessionContext, current.AppID, current.OrgID, current.ID) + }) -func (app *Application) deleteUser(clientID string, current *model.User) error { - return app.storage.DeleteUser(clientID, current.ID) } func (app *Application) getGroup(current *model.User, id string) (*model.Group, error) { @@ -291,29 +316,22 @@ func (app *Application) updateMembership(membership *model.GroupMembership, stat return nil } -func (app *Application) getEvents(clientID string, current *model.User, groupID string, filterByToMembers bool) ([]model.Event, error) { - events, err := app.storage.FindEvents(clientID, current, groupID, filterByToMembers) +func (app *Application) getEvents(current *model.User, groupID string, filterByToMembers bool) ([]model.Event, error) { + events, err := app.storage.FindEvents(current, groupID, filterByToMembers) if err != nil { return nil, err } return events, nil } -func (app *Application) createEvent(clientID string, current *model.User, eventID string, group *model.Group, toMemberList []model.ToMember, creator *model.Creator) (*model.Event, error) { +func (app *Application) createEvent(appID string, orgID string, eventID string, group *model.Group, toMemberList []model.ToMember, creator *model.Creator) (*model.Event, error) { var skipUserID *string - if current != nil && creator == nil { - creator = &model.Creator{ - UserID: current.ID, - Name: current.Name, - Email: current.Email, - } - } if creator != nil { skipUserID = &creator.UserID } - event, err := app.storage.CreateEvent(clientID, eventID, group.ID, toMemberList, creator) + event, err := app.storage.CreateEvent(appID, orgID, eventID, group.ID, toMemberList, creator) if err != nil { return nil, err } @@ -324,8 +342,10 @@ func (app *Application) createEvent(clientID string, current *model.User, eventI userIDs = event.GetMembersAsUserIDs(skipUserID) } - result, _ := app.storage.FindGroupMemberships(clientID, model.MembershipFilter{ + result, _ := app.storage.FindGroupMembershipsWithContext(nil, appID, orgID, model.MembershipFilter{ GroupIDs: []string{group.ID}, + AppID: appID, + OrgID: orgID, UserIDs: userIDs, Statuses: []string{"member", "admin"}, }) @@ -350,8 +370,8 @@ func (app *Application) createEvent(clientID string, current *model.User, eventI "entity_name": group.Title, }, nil, - current.AppID, - current.OrgID, + appID, + orgID, ) } @@ -362,26 +382,25 @@ func (app *Application) updateEvent(clientID string, _ *model.User, eventID stri return app.storage.UpdateEvent(clientID, eventID, groupID, toMemberList) } -func (app *Application) deleteEvent(clientID string, _ *model.User, eventID string, groupID string) error { - err := app.storage.DeleteEvent(clientID, eventID, groupID) - if err != nil { - return err - } - return nil +func (app *Application) deleteEvent(appID string, orgID string, eventID string, groupID string) error { + return app.storage.PerformTransaction(func(context storage.TransactionContext) error { + err := app.storage.DeleteEventWithContext(context, appID, orgID, eventID, groupID) + if err != nil { + return err + } + + return app.storage.UpdateGroupStats(context, appID, orgID, groupID, true, false, false, false) + }) } -func (app *Application) getPosts(clientID string, current *model.User, groupID string, filterPrivatePostsValue *bool, filterByToMembers bool, offset *int64, limit *int64, order *string) ([]*model.Post, error) { - return app.storage.FindPosts(clientID, current, groupID, filterPrivatePostsValue, filterByToMembers, offset, limit, order) +func (app *Application) getPosts(current *model.User, groupID string, filterPrivatePostsValue *bool, filterByToMembers bool, offset *int64, limit *int64, order *string) ([]*model.Post, error) { + return app.storage.FindPosts(current, groupID, filterPrivatePostsValue, filterByToMembers, offset, limit, order) } func (app *Application) getPost(clientID string, userID *string, groupID string, postID string, skipMembershipCheck bool, filterByToMembers bool) (*model.Post, error) { return app.storage.FindPost(nil, clientID, userID, groupID, postID, skipMembershipCheck, filterByToMembers) } -func (app *Application) getUserPostCount(clientID string, userID string) (*int64, error) { - return app.storage.GetUserPostCount(clientID, userID) -} - func (app *Application) createPost(clientID string, current *model.User, post *model.Post, group *model.Group) (*model.Post, error) { if group.Settings != nil && !group.Settings.PostPreferences.CanSendPostToAdmins { @@ -660,8 +679,46 @@ Reported comment: %s return nil } -func (app *Application) deletePost(clientID string, userID string, groupID string, postID string, force bool) error { - return app.storage.DeletePost(nil, clientID, userID, groupID, postID, force) +func (app *Application) deletePost(context storage.TransactionContext, appID string, orgID string, userID string, groupID string, postID string, force bool) error { + deleteWrapper := func(transactionContext storage.TransactionContext) error { + membership, _ := app.storage.FindGroupMembershipWithContext(transactionContext, appID, orgID, groupID, userID) + filterToMembers := true + if membership != nil && membership.IsAdmin() { + filterToMembers = false + } + + originalPost, _ := app.storage.FindPost(transactionContext, clientID, &userID, groupID, postID, true, filterToMembers) + if originalPost == nil { + return fmt.Errorf("unable to find post with id (%s) ", postID) + } + + if !force { + if originalPost == nil || membership == nil || (!membership.IsAdmin() && originalPost.Creator.UserID != userID) { + return fmt.Errorf("only creator of the post or group admin can delete it") + } + } + + childPosts, err := app.storage.FindPostsByParentID(transactionContext, clientID, userID, groupID, postID, true, false, false, nil) + if len(childPosts) > 0 && err == nil { + for _, post := range childPosts { + app.deletePost(transactionContext, appID, orgID, userID, groupID, post.ID, true) + } + } + + err = app.storage.DeletePost(transactionContext, appID, orgID, userID, groupID, postID, force) + if err != nil { + return err + } + + return app.storage.UpdateGroupStats(transactionContext, clientID, groupID, true, false, false, false) + } + + if context != nil { + return deleteWrapper(context) + } + return app.storage.PerformTransaction(func(transactionContext storage.TransactionContext) error { + return deleteWrapper(transactionContext) + }) } // TODO this logic needs to be refactored because it's over complicated! @@ -783,7 +840,9 @@ func (app *Application) synchronizeAuthman(appID string, orgID string, checkThre } emptyText := "" - _, err := app.storage.CreateGroup(clientID, nil, &model.Group{ + _, err := app.storage.CreateGroup(nil, &model.Group{ + AppID: appID, + OrgID: orgID, Title: title, Description: &emptyText, Category: "Academic", // Hardcoded. @@ -853,7 +912,7 @@ func (app *Application) synchronizeAuthman(appID string, orgID string, checkThre } if groupUpdated { - err := app.storage.UpdateGroupWithMembership(clientID, nil, storedStemGroup, membershipsForUpdate) + err := app.storage.UpdateGroup(nil, storedStemGroup, membershipsForUpdate) if err != nil { log.Printf("error app.synchronizeAuthmanGroup() - unable to update group admins of '%s' - %s", storedStemGroup.Title, err) } @@ -1238,10 +1297,6 @@ func (app *Application) sendNotification(recipients []notifications.Recipient, t app.notifications.SendNotification(recipients, topic, title, text, data, nil, appID, orgID) } -func (app *Application) findGroupMembership(clientID string, groupID string, userID string) (*model.GroupMembership, error) { - return app.storage.FindGroupMembership(clientID, groupID, userID) -} - func (app *Application) getResearchProfileUserCount(clientID string, current *model.User, researchProfile map[string]map[string][]string) (int64, error) { searchParams := app.formatCoreAccountSearchParams(researchProfile) return app.corebb.GetAccountsCount(searchParams, ¤t.AppID, ¤t.OrgID) diff --git a/driven/authman/adapter.go b/driven/authman/adapter.go index 0173cc6a..6e01a040 100644 --- a/driven/authman/adapter.go +++ b/driven/authman/adapter.go @@ -18,7 +18,7 @@ import ( "encoding/json" "fmt" "groups/core/model" - "io/ioutil" + "io" "log" "net/http" "strings" @@ -63,14 +63,8 @@ func (a *Adapter) RetrieveAuthmanGroupMembers(groupName string) ([]string, error return nil, fmt.Errorf("RetrieveAuthmanGroupMembersError: error with response code != 200") } - data, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Printf("RetrieveAuthmanGroupMembersError: unable to read json: %s", err) - return nil, fmt.Errorf("RetrieveAuthmanGroupMembersError: unable to parse json: %s", err) - } - var authmanData model.AuthmanGroupResponse - err = json.Unmarshal(data, &authmanData) + err = json.NewDecoder(resp.Body).Decode(&authmanData) if err != nil { log.Printf("RetrieveAuthmanGroupMembersError: unable to parse json: %s", err) return nil, fmt.Errorf("RetrieveAuthmanGroupMembersError: unable to parse json: %s", err) @@ -150,16 +144,16 @@ func (a *Adapter) RemoveAuthmanMemberFromGroup(groupName string, uin string) err func (a *Adapter) RetrieveAuthmanUsers(externalIDs []string) (map[string]model.AuthmanSubject, error) { externalIDCount := len(externalIDs) if externalIDCount > 0 { - subjectLookups := make([]model.АuthmanSubjectLookup, externalIDCount) + subjectLookups := make([]model.AuthmanSubjectLookup, externalIDCount) for i, externalID := range externalIDs { - subjectLookups[i] = model.АuthmanSubjectLookup{ + subjectLookups[i] = model.AuthmanSubjectLookup{ SubjectID: externalID, SubjectSourceID: SubjectsourceidUofinetid, } } - requestBodyStruct := model.АuthmanUserRequest{ - WsRestGetSubjectsRequest: model.АuthmanUserData{ + requestBodyStruct := model.AuthmanUserRequest{ + WsRestGetSubjectsRequest: model.AuthmanUserData{ WsSubjectLookups: subjectLookups, SubjectAttributeNames: []string{"userprincipalname"}, }, @@ -188,7 +182,7 @@ func (a *Adapter) RetrieveAuthmanUsers(externalIDs []string) (map[string]model.A } defer resp.Body.Close() if resp.StatusCode != 200 { - errordata, err := ioutil.ReadAll(resp.Body) + errordata, err := io.ReadAll(resp.Body) if err != nil { log.Printf("RetrieveAuthmanUsers: unable to read error response: %s", errordata) return nil, fmt.Errorf("RetrieveAuthmanUsers: unable to error response: %s", errordata) @@ -197,14 +191,8 @@ func (a *Adapter) RetrieveAuthmanUsers(externalIDs []string) (map[string]model.A return nil, fmt.Errorf("RetrieveAuthmanUsers: error with response code - %d: Response: %s", resp.StatusCode, string(errordata)) } - data, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Printf("RetrieveAuthmanUsers: unable to read json: %s", err) - return nil, fmt.Errorf("RetrieveAuthmanUsers: unable to read json: %s", err) - } - - var authmanData model.АuthmanUserResponse - err = json.Unmarshal(data, &authmanData) + var authmanData model.AuthmanUserResponse + err = json.NewDecoder(resp.Body).Decode(&authmanData) if err != nil { log.Printf("RetrieveAuthmanUsers: unable to parse json: %s", err) return nil, fmt.Errorf("RetrieveAuthmanUsers: unable to parse json: %s", err) @@ -220,7 +208,7 @@ func (a *Adapter) RetrieveAuthmanUsers(externalIDs []string) (map[string]model.A } // RetrieveAuthmanStemGroups retrieve Authman user data based on external IDs for a given stem -func (a *Adapter) RetrieveAuthmanStemGroups(stemName string) (*model.АuthmanGroupsResponse, error) { +func (a *Adapter) RetrieveAuthmanStemGroups(stemName string) (*model.AuthmanGroupsResponse, error) { // Hardcoded until it needs to be configurable requestBody := fmt.Sprintf(`{ @@ -250,7 +238,7 @@ func (a *Adapter) RetrieveAuthmanStemGroups(stemName string) (*model.АuthmanGro } defer resp.Body.Close() if resp.StatusCode != 200 { - errordata, err := ioutil.ReadAll(resp.Body) + errordata, err := io.ReadAll(resp.Body) if err != nil { log.Printf("RetrieveAuthmanStemGroups: unable to read error response: %s", errordata) return nil, fmt.Errorf("RetrieveAuthmanStemGroups: unable to error response: %s", errordata) @@ -259,14 +247,8 @@ func (a *Adapter) RetrieveAuthmanStemGroups(stemName string) (*model.АuthmanGro return nil, fmt.Errorf("RetrieveAuthmanStemGroups: error with response code - %d: Response: %s", resp.StatusCode, string(errordata)) } - data, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Printf("RetrieveAuthmanStemGroups: unable to read json: %s", err) - return nil, fmt.Errorf("RetrieveAuthmanStemGroups: unable to read json: %s", err) - } - - var authmanData model.АuthmanGroupsResponse - err = json.Unmarshal(data, &authmanData) + var authmanData model.AuthmanGroupsResponse + err = json.NewDecoder(resp.Body).Decode(&authmanData) if err != nil { log.Printf("RetrieveAuthmanStemGroups: unable to parse json: %s", err) return nil, fmt.Errorf("RetrieveAuthmanStemGroups: unable to parse json: %s", err) diff --git a/driven/corebb/adapter.go b/driven/corebb/adapter.go index 05481a94..3d093fac 100644 --- a/driven/corebb/adapter.go +++ b/driven/corebb/adapter.go @@ -20,7 +20,6 @@ import ( "errors" "fmt" "groups/core/model" - "io/ioutil" "log" "net/http" "strings" @@ -62,14 +61,8 @@ func (a *Adapter) RetrieveCoreUserAccount(token string) (*model.CoreAccount, err return nil, fmt.Errorf("RetrieveCoreUserAccount: error with response code != 200") } - data, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Printf("RetrieveCoreUserAccount: unable to read json: %s", err) - return nil, fmt.Errorf("RetrieveCoreUserAccount: unable to parse json: %s", err) - } - var coreAccount model.CoreAccount - err = json.Unmarshal(data, &coreAccount) + err = json.NewDecoder(resp.Body).Decode(&coreAccount) if err != nil { log.Printf("RetrieveCoreUserAccount: unable to parse json: %s", err) return nil, fmt.Errorf("RetrieveAuthmanGroupMembersError: unable to parse json: %s", err) @@ -102,14 +95,8 @@ func (a *Adapter) RetrieveCoreServices(serviceIDs []string) ([]model.CoreService return nil, fmt.Errorf("RetrieveCoreUserAccount: error with response code != 200") } - data, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Printf("RetrieveCoreServices: unable to read json: %s", err) - return nil, fmt.Errorf("RetrieveCoreUserAccount: unable to parse json: %s", err) - } - var coreServices []model.CoreService - err = json.Unmarshal(data, &coreServices) + err = json.NewDecoder(resp.Body).Decode(&coreServices) if err != nil { log.Printf("RetrieveCoreServices: unable to parse json: %s", err) return nil, fmt.Errorf("RetrieveCoreServices: unable to parse json: %s", err) @@ -172,14 +159,8 @@ func (a *Adapter) GetAccountsCount(searchParams map[string]interface{}, appID *s return 0, fmt.Errorf("GetAccountsCount: error with response code != 200") } - data, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Printf("GetAccountsCount: unable to read json: %s", err) - return 0, fmt.Errorf("GetAccountsCount: unable to parse json: %s", err) - } - var count int64 - err = json.Unmarshal(data, &count) + err = json.NewDecoder(resp.Body).Decode(&count) if err != nil { log.Printf("GetAccountsCount: unable to parse json: %s", err) return 0, fmt.Errorf("GetAccountsCount: unable to parse json: %s", err) diff --git a/driven/rewards/adapter.go b/driven/rewards/adapter.go index d8beeda6..80053f29 100644 --- a/driven/rewards/adapter.go +++ b/driven/rewards/adapter.go @@ -17,7 +17,7 @@ package rewards import ( "encoding/json" "fmt" - "io/ioutil" + "io" "log" "net/http" "strings" @@ -87,7 +87,7 @@ func (a *Adapter) CreateUserReward(userID string, rewardType string, description } defer resp.Body.Close() if resp.StatusCode != 200 { - errorBody, err := ioutil.ReadAll(resp.Body) + errorBody, err := io.ReadAll(resp.Body) if err != nil { log.Printf("CreateUserReward: unable to read json: %s", err) return fmt.Errorf("CreateUserReward: unable to parse json: %s", err) diff --git a/driven/storage/adapter.go b/driven/storage/adapter.go index bc95d836..f93ee7c3 100644 --- a/driven/storage/adapter.go +++ b/driven/storage/adapter.go @@ -342,7 +342,7 @@ func (sa *Adapter) FindUsers(clientID string, id []string, external bool) ([]mod } // LoginUser Login a user's and refactor legacy record if need -func (sa *Adapter) LoginUser(clientID string, current *model.User) error { +func (sa *Adapter) LoginUser(current *model.User) error { now := time.Now() @@ -354,7 +354,8 @@ func (sa *Adapter) LoginUser(clientID string, current *model.User) error { if current.IsCoreUser { // Repopulate and keep sync of external_id & user_id. Part 1 filter := bson.D{ - primitive.E{Key: "client_id", Value: clientID}, + primitive.E{Key: "app_id", Value: current.AppID}, + primitive.E{Key: "org_id", Value: current.OrgID}, primitive.E{Key: "external_id", Value: current.ExternalID}, } update := bson.D{ @@ -375,7 +376,8 @@ func (sa *Adapter) LoginUser(clientID string, current *model.User) error { // Repopulate and keep sync of external_id & user_id. Part 2 filter = bson.D{ - primitive.E{Key: "client_id", Value: clientID}, + primitive.E{Key: "app_id", Value: current.AppID}, + primitive.E{Key: "org_id", Value: current.OrgID}, primitive.E{Key: "user_id", Value: current.ID}, } update = bson.D{ @@ -396,7 +398,8 @@ func (sa *Adapter) LoginUser(clientID string, current *model.User) error { // Repopulate and keep sync of user in the user table. Part 3 filter = bson.D{ - primitive.E{Key: "client_id", Value: clientID}, + primitive.E{Key: "app_id", Value: current.AppID}, + primitive.E{Key: "org_id", Value: current.OrgID}, primitive.E{Key: "_id", Value: current.ID}, } update = bson.D{ @@ -440,10 +443,11 @@ type getUserPostCountResult struct { } // GetUserPostCount gets the number of posts for the specified user -func (sa *Adapter) GetUserPostCount(clientID string, userID string) (*int64, error) { +func (sa *Adapter) GetUserPostCount(appID string, orgID string, userID string) (*int64, error) { pipeline := []primitive.M{ {"$match": primitive.M{ - "client_id": clientID, + "app_id": appID, + "org_id": orgID, "member.user_id": userID, }}, {"$count": "posts_count"}, @@ -459,55 +463,25 @@ func (sa *Adapter) GetUserPostCount(clientID string, userID string) (*int64, err return nil, nil } -// DeleteUser Deletes a user with all information -func (sa *Adapter) DeleteUser(appID string, orgID string, userID string) error { - - return sa.PerformTransaction(func(sessionContext TransactionContext) error { - posts, err := sa.FindAllUserPosts(sessionContext, clientID, userID) - if err != nil { - log.Printf("error on find all posts for user (%s) - %s", userID, err.Error()) - return err - } - if len(posts) > 0 { - for _, post := range posts { - err = sa.DeletePost(sessionContext, clientID, userID, post.GroupID, post.ID, true) - if err != nil { - log.Printf("error on delete all posts for user (%s) - %s", userID, err.Error()) - return err - } - } - } - - memberships, err := sa.FindGroupMembershipsWithContext(sessionContext, model.MembershipFilter{AppID: appID, OrgID: orgID, UserID: &userID}) - if err != nil { - log.Printf("error getting user memberships - %s", err.Error()) - return err - } - for _, membership := range memberships.Items { - err = sa.DeleteMembershipWithContext(sessionContext, clientID, membership.GroupID, membership.UserID) - if err != nil { - log.Printf("error deleting user membership - %s", err.Error()) - return err - } - } - - // delete the user - filter := bson.D{ - primitive.E{Key: "_id", Value: userID}, - primitive.E{Key: "client_id", Value: clientID}, - } - _, err = sa.db.users.DeleteOneWithContext(sessionContext, filter, nil) - if err != nil { - log.Printf("error deleting user - %s", err.Error()) - return err - } +// DeleteUserWithContext Deletes a user +func (sa *Adapter) DeleteUserWithContext(context TransactionContext, appID string, orgID string, userID string) error { + // delete the user + filter := bson.D{ + primitive.E{Key: "_id", Value: userID}, + primitive.E{Key: "app_id", Value: appID}, + primitive.E{Key: "org_id", Value: orgID}, + } + _, err := sa.db.users.DeleteOneWithContext(context, filter, nil) + if err != nil { + log.Printf("error deleting user - %s", err.Error()) + return err + } - return nil - }) + return nil } // CreateGroup creates a group. Returns the id of the created group -func (sa *Adapter) CreateGroup(clientID string, current *model.User, group *model.Group, defaultMemberships []model.GroupMembership) (*string, *utils.GroupError) { +func (sa *Adapter) CreateGroup(current *model.User, group *model.Group, defaultMemberships []model.GroupMembership) (*string, *utils.GroupError) { insertedID := uuid.NewString() now := time.Now() @@ -535,7 +509,6 @@ func (sa *Adapter) CreateGroup(clientID string, current *model.User, group *mode // insert the group and the admin member group.ID = insertedID - group.ClientID = clientID group.DateCreated = now if group.Settings == nil { settings := model.DefaultGroupSettings() @@ -560,7 +533,8 @@ func (sa *Adapter) CreateGroup(clientID string, current *model.User, group *mode ID: uuid.NewString(), GroupID: insertedID, UserID: current.ID, - ClientID: clientID, + AppID: current.AppID, + OrgID: current.OrgID, ExternalID: current.ExternalID, Email: current.Email, NetID: current.NetID, @@ -577,7 +551,7 @@ func (sa *Adapter) CreateGroup(clientID string, current *model.User, group *mode } } - err = sa.UpdateGroupStats(context, clientID, group.ID, false, false, false, true) + err = sa.UpdateGroupStats(context, group.AppID, group.OrgID, group.ID, false, false, false, true) if err != nil { return err } @@ -597,12 +571,8 @@ func (sa *Adapter) CreateGroup(clientID string, current *model.User, group *mode return &insertedID, nil } -// UpdateGroupWithMemberships updates a group along with the memberships -func (sa *Adapter) UpdateGroupWithMemberships(clientID string, current *model.User, group *model.Group, memberships []model.GroupMembership) *utils.GroupError { - return sa.updateGroup(clientID, current, group, memberships) -} - -func (sa *Adapter) updateGroup(clientID string, current *model.User, group *model.Group, memberships []model.GroupMembership) *utils.GroupError { +// UpdateGroup updates a group along with the memberships +func (sa *Adapter) UpdateGroup(userID *string, group *model.Group, memberships []model.GroupMembership) *utils.GroupError { // // [#301] Research Groups don't support automatic join feature!!! @@ -656,12 +626,7 @@ func (sa *Adapter) updateGroup(clientID string, current *model.User, group *mode setOperation = append(setOperation, primitive.E{Key: "tags", Value: tags}) } } else if group.Category != "" || len(group.Tags) > 0 { - - var userID *string - if current != nil { - userID = ¤t.ID - } - persistedGroup, err := sa.FindGroup(context, clientID, group.ID, userID) + persistedGroup, err := sa.FindGroupWithContext(context, group.AppID, group.OrgID, group.ID, userID) if err != nil { return err } @@ -691,7 +656,8 @@ func (sa *Adapter) updateGroup(clientID string, current *model.User, group *mode _, err := sa.db.groups.UpdateOneWithContext( context, bson.D{primitive.E{Key: "_id", Value: group.ID}, - primitive.E{Key: "client_id", Value: clientID}, + primitive.E{Key: "app_id", Value: group.AppID}, + primitive.E{Key: "org_id", Value: group.OrgID}, }, updateOperation, nil) if err != nil { return err @@ -709,7 +675,8 @@ func (sa *Adapter) updateGroup(clientID string, current *model.User, group *mode } else { filter := bson.D{ primitive.E{Key: "_id", Value: group.ID}, - primitive.E{Key: "client_id", Value: clientID}, + primitive.E{Key: "app_id", Value: group.AppID}, + primitive.E{Key: "org_id", Value: group.OrgID}, } err = sa.db.groupMemberships.ReplaceOneWithContext(context, filter, membership, nil) if err != nil { @@ -719,7 +686,7 @@ func (sa *Adapter) updateGroup(clientID string, current *model.User, group *mode } } - err = sa.UpdateGroupStats(context, clientID, group.ID, true, len(memberships) > 0, false, true) + err = sa.UpdateGroupStats(context, group.AppID, group.OrgID, group.ID, true, len(memberships) > 0, false, true) if err != nil { return err } @@ -739,13 +706,14 @@ func (sa *Adapter) updateGroup(clientID string, current *model.User, group *mode } // DeleteGroup deletes a group. -func (sa *Adapter) DeleteGroup(clientID string, id string) error { +func (sa *Adapter) DeleteGroup(appID string, orgID string, id string) error { err := sa.PerformTransaction(func(context TransactionContext) error { // 1. delete mapped group events _, err := sa.db.events.DeleteManyWithContext(context, bson.D{ primitive.E{Key: "group_id", Value: id}, - primitive.E{Key: "client_id", Value: clientID}, + primitive.E{Key: "app_id", Value: appID}, + primitive.E{Key: "org_id", Value: orgID}, }, nil) if err != nil { return err @@ -754,7 +722,8 @@ func (sa *Adapter) DeleteGroup(clientID string, id string) error { // 2. delete mapped group posts _, err = sa.db.posts.DeleteManyWithContext(context, bson.D{ primitive.E{Key: "group_id", Value: id}, - primitive.E{Key: "client_id", Value: clientID}, + primitive.E{Key: "app_id", Value: appID}, + primitive.E{Key: "org_id", Value: orgID}, }, nil) if err != nil { return err @@ -763,7 +732,8 @@ func (sa *Adapter) DeleteGroup(clientID string, id string) error { // 3. delete mapped group memberships _, err = sa.db.groupMemberships.DeleteManyWithContext(context, bson.D{ primitive.E{Key: "group_id", Value: id}, - primitive.E{Key: "client_id", Value: clientID}, + primitive.E{Key: "app_id", Value: appID}, + primitive.E{Key: "org_id", Value: orgID}, }, nil) if err != nil { return err @@ -772,7 +742,8 @@ func (sa *Adapter) DeleteGroup(clientID string, id string) error { // 4. delete the group _, err = sa.db.groups.DeleteOneWithContext(context, bson.D{ primitive.E{Key: "_id", Value: id}, - primitive.E{Key: "client_id", Value: clientID}, + primitive.E{Key: "app_id", Value: appID}, + primitive.E{Key: "org_id", Value: orgID}, }, nil) if err != nil { return err @@ -810,9 +781,10 @@ func (sa *Adapter) FindGroupWithContext(context TransactionContext, appID string } // FindGroupByTitle finds group by membership -func (sa *Adapter) FindGroupByTitle(clientID string, title string) (*model.Group, error) { +func (sa *Adapter) FindGroupByTitle(appID string, orgID string, title string) (*model.Group, error) { filter := bson.D{ - primitive.E{Key: "client_id", Value: clientID}, + primitive.E{Key: "app_id", Value: appID}, + primitive.E{Key: "org_id", Value: orgID}, primitive.E{Key: "title", Value: title}, } var result []model.Group @@ -837,7 +809,7 @@ func (sa *Adapter) FindGroups(userID *string, groupsFilter model.GroupsFilter) ( var memberships model.MembershipCollection if userID != nil { // find group memberships - memberships, err = sa.FindUserGroupMemberships(clientID, *userID) + memberships, err = sa.FindGroupMembershipsWithContext(nil, model.MembershipFilter{AppID: groupsFilter.AppID, OrgID: groupsFilter.OrgID, UserID: userID}) if err != nil { return nil, err } @@ -1034,7 +1006,7 @@ func (sa *Adapter) FindUserGroups(userID string, groupsFilter model.GroupsFilter // TODO: Merge the filter logic in a common method (FindGroups, FindGroupsV3, FindUserGroups) // find group memberships - memberships, err := sa.FindUserGroupMemberships(clientID, userID) + memberships, err := sa.FindGroupMembershipsWithContext(nil, model.MembershipFilter{AppID: groupsFilter.AppID, OrgID: groupsFilter.OrgID, UserID: &userID}) if err != nil { return nil, err } @@ -1136,10 +1108,11 @@ func (sa *Adapter) FindUserGroups(userID string, groupsFilter model.GroupsFilter } // FindEvents finds the events for a group -func (sa *Adapter) FindEvents(clientID string, current *model.User, groupID string, filterByToMembers bool) ([]model.Event, error) { +func (sa *Adapter) FindEvents(current *model.User, groupID string, filterByToMembers bool) ([]model.Event, error) { filter := bson.D{ primitive.E{Key: "group_id", Value: groupID}, - primitive.E{Key: "client_id", Value: clientID}, + primitive.E{Key: "app_id", Value: current.AppID}, + primitive.E{Key: "org_id", Value: current.OrgID}, } if filterByToMembers && current != nil { filter = append(filter, primitive.E{Key: "$or", Value: []primitive.M{ @@ -1156,9 +1129,10 @@ func (sa *Adapter) FindEvents(clientID string, current *model.User, groupID stri } // CreateEvent creates a group event -func (sa *Adapter) CreateEvent(clientID string, eventID string, groupID string, toMemberList []model.ToMember, creator *model.Creator) (*model.Event, error) { +func (sa *Adapter) CreateEvent(appID string, orgID string, eventID string, groupID string, toMemberList []model.ToMember, creator *model.Creator) (*model.Event, error) { event := model.Event{ - ClientID: clientID, + AppID: appID, + OrgID: orgID, EventID: eventID, GroupID: groupID, DateCreated: time.Now().UTC(), @@ -1172,7 +1146,7 @@ func (sa *Adapter) CreateEvent(clientID string, eventID string, groupID string, return err } - return sa.UpdateGroupStats(context, clientID, groupID, true, false, false, false) + return sa.UpdateGroupStats(context, appID, orgID, groupID, true, false, false, false) }) return &event, err @@ -1201,37 +1175,36 @@ func (sa *Adapter) UpdateEvent(clientID string, eventID string, groupID string, }) } -// DeleteEvent deletes a group event -func (sa *Adapter) DeleteEvent(clientID string, eventID string, groupID string) error { - return sa.PerformTransaction(func(context TransactionContext) error { - filter := bson.D{primitive.E{Key: "event_id", Value: eventID}, - primitive.E{Key: "group_id", Value: groupID}, - primitive.E{Key: "client_id", Value: clientID}} - result, err := sa.db.events.DeleteOneWithContext(context, filter, nil) - if err != nil { - return err - } - if result == nil { - return errors.New("result is nil for event with event id " + eventID) - } - deletedCount := result.DeletedCount - if deletedCount != 1 { - return errors.New("error occured while deleting an event with event id " + eventID) - } +// DeleteEventWithContext deletes a group event +func (sa *Adapter) DeleteEventWithContext(context TransactionContext, appID string, orgID string, eventID string, groupID string) error { + filter := bson.D{primitive.E{Key: "event_id", Value: eventID}, + primitive.E{Key: "group_id", Value: groupID}, + primitive.E{Key: "app_id", Value: appID}, + primitive.E{Key: "org_id", Value: orgID}} + result, err := sa.db.events.DeleteOneWithContext(context, filter, nil) + if err != nil { + return err + } + if result == nil { + return errors.New("result is nil for event with event id " + eventID) + } + deletedCount := result.DeletedCount + if deletedCount != 1 { + return errors.New("error occured while deleting an event with event id " + eventID) + } - return sa.UpdateGroupStats(context, clientID, groupID, true, false, false, false) - }) + return nil } // FindPosts Retrieves posts for a group -func (sa *Adapter) FindPosts(clientID string, current *model.User, groupID string, filterPrivatePostsValue *bool, filterByToMembers bool, offset *int64, limit *int64, order *string) ([]*model.Post, error) { +func (sa *Adapter) FindPosts(current *model.User, groupID string, filterPrivatePostsValue *bool, filterByToMembers bool, offset *int64, limit *int64, order *string) ([]*model.Post, error) { var userID *string if current != nil { userID = ¤t.ID } - group, errGr := sa.FindGroup(nil, clientID, groupID, userID) + group, errGr := sa.FindGroupWithContext(nil, current.AppID, current.OrgID, groupID, userID) if group == nil { if errGr != nil { log.Printf("unable to find group with id %s: %s", groupID, errGr) @@ -1242,8 +1215,9 @@ func (sa *Adapter) FindPosts(clientID string, current *model.User, groupID strin } filter := bson.D{ - primitive.E{Key: "client_id", Value: clientID}, primitive.E{Key: "group_id", Value: groupID}, + primitive.E{Key: "app_id", Value: group.AppID}, + primitive.E{Key: "org_id", Value: group.OrgID}, } if filterByToMembers { @@ -1292,7 +1266,7 @@ func (sa *Adapter) FindPosts(clientID string, current *model.User, groupID strin if paging && len(list) > 0 { for _, post := range list { - childPosts, err := sa.FindPostsByTopParentID(clientID, current, groupID, post.ID, true, order) + childPosts, err := sa.FindPostsByTopParentID(current, groupID, post.ID, true, order) if err == nil && childPosts != nil { for _, childPost := range childPosts { if childPost.UserCanSeePost(current.ID) { @@ -1330,9 +1304,10 @@ func (sa *Adapter) FindPosts(clientID string, current *model.User, groupID strin // FindAllUserPosts Retrieves all user posts across all existing groups // This method doesn't construct tree hierarchy! -func (sa *Adapter) FindAllUserPosts(context TransactionContext, clientID string, userID string) ([]model.Post, error) { +func (sa *Adapter) FindAllUserPosts(context TransactionContext, appID string, orgID string, userID string) ([]model.Post, error) { filter := bson.D{ - primitive.E{Key: "client_id", Value: clientID}, + primitive.E{Key: "app_id", Value: appID}, + primitive.E{Key: "org_id", Value: orgID}, primitive.E{Key: "member.user_id", Value: userID}, } @@ -1457,11 +1432,11 @@ func (sa *Adapter) FindPostsByParentID(ctx TransactionContext, clientID string, // FindPostsByTopParentID Retrieves a post by groupID and top parent id // This method doesn't construct tree hierarchy! -func (sa *Adapter) FindPostsByTopParentID(clientID string, current *model.User, groupID string, topParentID string, skipMembershipCheck bool, order *string) ([]*model.Post, error) { - filter := bson.D{primitive.E{Key: "client_id", Value: clientID}, primitive.E{Key: "top_parent_id", Value: topParentID}} +func (sa *Adapter) FindPostsByTopParentID(current *model.User, groupID string, topParentID string, skipMembershipCheck bool, order *string) ([]*model.Post, error) { + filter := bson.D{primitive.E{Key: "app_id", Value: current.AppID}, primitive.E{Key: "org_id", Value: current.OrgID}, primitive.E{Key: "top_parent_id", Value: topParentID}} if !skipMembershipCheck { - membership, err := sa.FindGroupMembership(clientID, groupID, current.ID) + membership, err := sa.FindGroupMembershipWithContext(nil, current.AppID, current.OrgID, groupID, current.ID) if membership == nil || err != nil || !membership.IsAdminOrMember() { return nil, fmt.Errorf("the user is not member or admin of the group") } @@ -1642,49 +1617,18 @@ func (sa *Adapter) ReactToPost(context TransactionContext, userID string, postID } // DeletePost Deletes a post -func (sa *Adapter) DeletePost(ctx TransactionContext, clientID string, userID string, groupID string, postID string, force bool) error { - - deleteWrapper := func(transactionContext TransactionContext) error { - membership, _ := sa.FindGroupMembershipWithContext(transactionContext, clientID, groupID, userID) - filterToMembers := true - if membership != nil && membership.IsAdmin() { - filterToMembers = false - } +func (sa *Adapter) DeletePost(ctx TransactionContext, appID string, orgID string, userID string, groupID string, postID string, force bool) error { + filter := bson.D{primitive.E{Key: "app_id", Value: appID}, primitive.E{Key: "org_id", Value: orgID}, primitive.E{Key: "_id", Value: postID}} - originalPost, _ := sa.FindPost(transactionContext, clientID, &userID, groupID, postID, true, filterToMembers) - if originalPost == nil { - return fmt.Errorf("unable to find post with id (%s) ", postID) - } - - if !force { - if originalPost == nil || membership == nil || (!membership.IsAdmin() && originalPost.Creator.UserID != userID) { - return fmt.Errorf("only creator of the post or group admin can delete it") - } - } - - childPosts, err := sa.FindPostsByParentID(transactionContext, clientID, userID, groupID, postID, true, false, false, nil) - if len(childPosts) > 0 && err == nil { - for _, post := range childPosts { - sa.DeletePost(transactionContext, clientID, userID, groupID, post.ID, true) - } - } - - filter := bson.D{primitive.E{Key: "client_id", Value: clientID}, primitive.E{Key: "_id", Value: postID}} - - _, err = sa.db.posts.DeleteOneWithContext(transactionContext, filter, nil) - if err != nil { - return err - } - - return sa.UpdateGroupStats(transactionContext, clientID, groupID, true, false, false, false) + res, err := sa.db.posts.DeleteOneWithContext(ctx, filter, nil) + if err != nil { + return err } - - if ctx != nil { - return deleteWrapper(ctx) + if res.DeletedCount != 1 { + return fmt.Errorf("unexpected deleted post count: %d", res.DeletedCount) } - return sa.PerformTransaction(func(transactionContext TransactionContext) error { - return deleteWrapper(transactionContext) - }) + + return nil } // UpdateGroupStats set the updated date to the current date time (now) @@ -1776,10 +1720,11 @@ func (sa *Adapter) UpdateGroupAttributeIndexes(group *model.Group) { } // UpdateGroupDateUpdated Updates group's date updated -func (sa *Adapter) UpdateGroupDateUpdated(clientID string, groupID string) error { +func (sa *Adapter) UpdateGroupDateUpdated(appID string, orgID string, groupID string) error { filter := bson.D{ primitive.E{Key: "_id", Value: groupID}, - primitive.E{Key: "client_id", Value: clientID}, + primitive.E{Key: "app_id", Value: appID}, + primitive.E{Key: "org_id", Value: orgID}, } update := bson.D{ primitive.E{Key: "$set", Value: bson.D{ diff --git a/driver/web/rest/adminapis.go b/driver/web/rest/adminapis.go index fe59e4ca..4a454ba3 100644 --- a/driver/web/rest/adminapis.go +++ b/driver/web/rest/adminapis.go @@ -494,7 +494,7 @@ func (h *AdminApisHandler) GetGroupPosts(current *model.User, w http.ResponseWri order = &orders[0] } - posts, err := h.app.Services.GetPosts(clientID, current, id, nil, false, offset, limit, order) + posts, err := h.app.Services.GetPosts(current, id, nil, false, offset, limit, order) if err != nil { log.Printf("error getting posts for group (%s) - %s", id, err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) @@ -533,7 +533,7 @@ func (h *AdminApisHandler) GetGroupEvents(current *model.User, w http.ResponseWr return } - events, err := h.app.Services.GetEvents(clientID, current, groupID, false) + events, err := h.app.Services.GetEvents(current, groupID, false) if err != nil { log.Printf("error getting group events - %s", err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) @@ -578,7 +578,7 @@ func (h *AdminApisHandler) DeleteGroup(current *model.User, w http.ResponseWrite return } - group, err := h.app.Services.GetGroupEntity(clientID, id) + group, err := h.app.Services.GetGroupEntity(current.AppID, current.OrgID, id) if err != nil { log.Println(err.Error()) http.Error(w, utils.NewServerError().JSONErrorString(), http.StatusInternalServerError) @@ -590,7 +590,7 @@ func (h *AdminApisHandler) DeleteGroup(current *model.User, w http.ResponseWrite return } - err = h.app.Services.DeleteGroup(clientID, current, id) + err = h.app.Services.DeleteGroup(current.AppID, current.OrgID, id) if err != nil { log.Printf("Error on deleting group - %s\n", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) @@ -630,7 +630,7 @@ func (h *AdminApisHandler) DeleteGroupEvent(current *model.User, w http.Response return } - err := h.app.Services.DeleteEvent(clientID, current, eventID, groupID) + err := h.app.Services.DeleteEvent(current.AppID, current.OrgID, eventID, groupID) if err != nil { log.Printf("Error on deleting an event - %s\n", err) http.Error(w, err.Error(), http.StatusInternalServerError) @@ -668,7 +668,7 @@ func (h *AdminApisHandler) DeleteGroupPost(current *model.User, w http.ResponseW return } - err := h.app.Services.DeletePost(clientID, current, groupID, postID, true) + err := h.app.Services.DeletePost(current, groupID, postID, true) if err != nil { log.Printf("error deleting posts for post (%s) - %s", postID, err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) diff --git a/driver/web/rest/apis.go b/driver/web/rest/apis.go index e92ab41f..ff2869df 100644 --- a/driver/web/rest/apis.go +++ b/driver/web/rest/apis.go @@ -20,8 +20,6 @@ import ( "groups/core" "groups/core/model" "groups/utils" - "io" - "io/ioutil" "log" "net/http" "strconv" @@ -102,15 +100,8 @@ func (h *ApisHandler) CreateGroup(current *model.User, w http.ResponseWriter, r // return // } - data, err := ioutil.ReadAll(r.Body) - if err != nil { - log.Printf("Error on marshal create a group - %s\n", err.Error()) - http.Error(w, utils.NewBadJSONError().JSONErrorString(), http.StatusBadRequest) - return - } - var requestData createGroupRequest - err = json.Unmarshal(data, &requestData) + err := json.NewDecoder(r.Body).Decode(&requestData) if err != nil { log.Printf("Error on unmarshal the create group data - %s\n", err.Error()) http.Error(w, utils.NewBadJSONError().JSONErrorString(), http.StatusBadRequest) @@ -138,7 +129,9 @@ func (h *ApisHandler) CreateGroup(current *model.User, w http.ResponseWriter, r return } - insertedID, groupErr := h.app.Services.CreateGroup(clientID, current, &model.Group{ + insertedID, groupErr := h.app.Services.CreateGroup(current, &model.Group{ + AppID: current.AppID, + OrgID: current.OrgID, Title: requestData.Title, Description: requestData.Description, Category: requestData.Category, @@ -167,7 +160,7 @@ func (h *ApisHandler) CreateGroup(current *model.User, w http.ResponseWriter, r return } - data, err = json.Marshal(createResponse{InsertedID: *insertedID}) + data, err := json.Marshal(createResponse{InsertedID: *insertedID}) if err != nil { log.Println("Error on marshal create group response") http.Error(w, utils.NewBadJSONError().JSONErrorString(), http.StatusBadRequest) @@ -227,15 +220,8 @@ func (h *ApisHandler) UpdateGroup(current *model.User, w http.ResponseWriter, r return } - data, err := ioutil.ReadAll(r.Body) - if err != nil { - log.Printf("Error on marshal the update group item - %s\n", err.Error()) - http.Error(w, utils.NewBadJSONError().JSONErrorString(), http.StatusBadRequest) - return - } - var requestData updateGroupRequest - err = json.Unmarshal(data, &requestData) + err := json.NewDecoder(r.Body).Decode(&requestData) if err != nil { log.Printf("Error on unmarshal the update group request data - %s\n", err.Error()) http.Error(w, utils.NewBadJSONError().JSONErrorString(), http.StatusBadRequest) @@ -251,7 +237,7 @@ func (h *ApisHandler) UpdateGroup(current *model.User, w http.ResponseWriter, r } //check if allowed to update - group, err := h.app.Services.GetGroup(clientID, current, id) + group, err := h.app.Services.GetGroup(current, id) if group.CurrentMember == nil || !group.CurrentMember.IsAdmin() { log.Printf("%s is not allowed to update group settings '%s'. Only group admin could update a group", current.Email, group.Title) http.Error(w, utils.NewForbiddenError().JSONErrorString(), http.StatusForbidden) @@ -268,7 +254,7 @@ func (h *ApisHandler) UpdateGroup(current *model.User, w http.ResponseWriter, r return } - groupErr := h.app.Services.UpdateGroup(clientID, current, &model.Group{ + groupErr := h.app.Services.UpdateGroup(¤t.ID, &model.Group{ ID: id, Title: requestData.Title, Description: requestData.Description, @@ -324,7 +310,7 @@ func (h *ApisHandler) GetGroupStats(current *model.User, w http.ResponseWriter, return } - group, err := h.app.Services.GetGroup(clientID, current, groupID) + group, err := h.app.Services.GetGroup(current, groupID) if err != nil { log.Printf("error getting group - %s", err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) @@ -371,7 +357,7 @@ func (h *ApisHandler) DeleteGroup(current *model.User, w http.ResponseWriter, r } //check if allowed to delete - group, err := h.app.Services.GetGroup(clientID, current, id) + group, err := h.app.Services.GetGroup(current, id) if err != nil { log.Println(err.Error()) http.Error(w, utils.NewServerError().JSONErrorString(), http.StatusInternalServerError) @@ -388,7 +374,7 @@ func (h *ApisHandler) DeleteGroup(current *model.User, w http.ResponseWriter, r return } - err = h.app.Services.DeleteGroup(clientID, current, id) + err = h.app.Services.DeleteGroup(current.AppID, current.OrgID, id) if err != nil { log.Printf("Error on deleting group - %s\n", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) @@ -464,7 +450,9 @@ func (h *ApisHandler) GetGroups(current *model.User, w http.ResponseWriter, r *h } } - groups, err := h.app.Services.GetGroups(clientID, current, groupsFilter) + groupsFilter.AppID = current.AppID + groupsFilter.OrgID = current.OrgID + groups, err := h.app.Services.GetGroups(¤t.ID, groupsFilter) if err != nil { log.Printf("apis.GetGroups() error getting groups - %s", err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) @@ -476,8 +464,10 @@ func (h *ApisHandler) GetGroups(current *model.User, w http.ResponseWriter, r *h groupIDs = append(groupIDs, grouop.ID) } - membershipCollection, err := h.app.Services.FindGroupMemberships(clientID, model.MembershipFilter{ + membershipCollection, err := h.app.Services.FindGroupMemberships(model.MembershipFilter{ GroupIDs: groupIDs, + AppID: current.AppID, + OrgID: current.OrgID, }) if err != nil { log.Printf("apis.GetGroups() unable to retrieve memberships: %s", err) @@ -591,22 +581,15 @@ func (h *ApisHandler) GetUserGroups(current *model.User, w http.ResponseWriter, groupsFilter.Order = &orders[0] } - requestData, err := io.ReadAll(r.Body) + err := json.NewDecoder(r.Body).Decode(&groupsFilter) if err != nil { - log.Printf("apis.GetUserGroups() error on marshal model.GroupsFilter request body - %s\n", err.Error()) - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) - return - } - - if len(requestData) > 0 { - err = json.Unmarshal(requestData, &groupsFilter) - if err != nil { - // just log an error and proceed and assume an empty filter - log.Printf("apis.GetUserGroups() error on unmarshal model.GroupsFilter request body - %s\n", err.Error()) - } + // just log an error and proceed and assume an empty filter + log.Printf("apis.GetUserGroups() error on unmarshal model.GroupsFilter request body - %s\n", err.Error()) } - groups, err := h.app.Services.GetUserGroups(clientID, current, groupsFilter) + groupsFilter.AppID = current.AppID + groupsFilter.OrgID = current.OrgID + groups, err := h.app.Services.GetUserGroups(current.ID, groupsFilter) if err != nil { log.Printf("apis.GetUserGroups() error getting user groups - %s", err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) @@ -618,8 +601,10 @@ func (h *ApisHandler) GetUserGroups(current *model.User, w http.ResponseWriter, groupIDs = append(groupIDs, grouop.ID) } - membershipCollection, err := h.app.Services.FindGroupMemberships(clientID, model.MembershipFilter{ + membershipCollection, err := h.app.Services.FindGroupMemberships(model.MembershipFilter{ GroupIDs: groupIDs, + AppID: current.AppID, + OrgID: current.OrgID, }) if err != nil { log.Printf("apis.GetUserGroups() unable to retrieve memberships: %s", err) @@ -653,7 +638,7 @@ func (h *ApisHandler) GetUserGroups(current *model.User, w http.ResponseWriter, // @Security APIKeyAuth // @Router /api/user/login [get] func (h *ApisHandler) LoginUser(current *model.User, w http.ResponseWriter, r *http.Request) { - err := h.app.Services.LoginUser(clientID, current) + err := h.app.Services.LoginUser(current) if err != nil { log.Printf("error login user - %s", err) http.Error(w, err.Error(), http.StatusInternalServerError) @@ -675,7 +660,7 @@ type getUserStatsResponse struct { // @Security AppUserAuth // @Router /api/user/stats [get] func (h *ApisHandler) GetUserStats(current *model.User, w http.ResponseWriter, r *http.Request) { - stats, err := h.app.Services.GetUserPostCount(clientID, current.ID) + stats, err := h.app.Services.GetUserPostCount(current.AppID, current.OrgID, current.ID) if err != nil { log.Printf("error getting user(%s) post count: %s", current.ID, err) http.Error(w, err.Error(), http.StatusInternalServerError) @@ -710,7 +695,7 @@ func (h *ApisHandler) GetUserStats(current *model.User, w http.ResponseWriter, r // @Security APIKeyAuth // @Router /api/user [delete] func (h *ApisHandler) DeleteUser(current *model.User, w http.ResponseWriter, r *http.Request) { - err := h.app.Services.DeleteUser(clientID, current) + err := h.app.Services.DeleteUser(current) if err != nil { log.Printf("error getting user groups - %s", err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) @@ -729,7 +714,7 @@ func (h *ApisHandler) DeleteUser(current *model.User, w http.ResponseWriter, r * // @Security AppUserAuth // @Router /api/user/group-memberships [get] func (h *ApisHandler) GetUserGroupMemberships(current *model.User, w http.ResponseWriter, r *http.Request) { - userGroups, err := h.app.Services.GetUserGroups(clientID, current, model.GroupsFilter{}) + userGroups, err := h.app.Services.GetUserGroups(current.ID, model.GroupsFilter{AppID: current.AppID, OrgID: current.OrgID}) if err != nil { log.Println("The user has no group memberships") http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) @@ -813,15 +798,17 @@ func (h *ApisHandler) GetGroup(current *model.User, w http.ResponseWriter, r *ht return } - group, err := h.app.Services.GetGroup(clientID, current, id) + group, err := h.app.Services.GetGroup(current, id) if err != nil { log.Printf("adminapis.GetGroupV2() error on getting group %s", err) http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } - membershipCollection, err := h.app.Services.FindGroupMemberships(clientID, model.MembershipFilter{ + membershipCollection, err := h.app.Services.FindGroupMemberships(model.MembershipFilter{ GroupIDs: []string{id}, + AppID: current.AppID, + OrgID: current.OrgID, }) if err != nil { log.Printf("Unable to retrieve memberships: %s", err) @@ -873,15 +860,8 @@ func (h *ApisHandler) CreatePendingMember(current *model.User, w http.ResponseWr return } - data, err := ioutil.ReadAll(r.Body) - if err != nil { - log.Printf("Error on marshal create a pending member - %s\n", err.Error()) - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) - return - } - var requestData createPendingMemberRequest - err = json.Unmarshal(data, &requestData) + err := json.NewDecoder(r.Body).Decode(&requestData) if err != nil { log.Printf("Error on unmarshal the create pending member data - %s\n", err.Error()) http.Error(w, err.Error(), http.StatusBadRequest) @@ -897,7 +877,7 @@ func (h *ApisHandler) CreatePendingMember(current *model.User, w http.ResponseWr return } - group, err := h.app.Services.GetGroupEntity(clientID, groupID) + group, err := h.app.Services.GetGroupEntity(current.AppID, current.OrgID, groupID) if err != nil { log.Printf("error getting a group - %s", err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) @@ -996,26 +976,19 @@ func (h *ApisHandler) GetGroupMembers(current *model.User, w http.ResponseWriter return } - requestData, err := ioutil.ReadAll(r.Body) - if err != nil { - log.Printf("Error on marshal model.MembershipFilter request body - %s\n", err.Error()) - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) - return - } - var request model.MembershipFilter - if len(requestData) > 0 { - err = json.Unmarshal(requestData, &request) - if err != nil { - // just log an error and proceed and assume an empty filter - log.Printf("Error on unmarshal model.MembershipFilter request body - %s\n", err.Error()) - } + err := json.NewDecoder(r.Body).Decode(&request) + if err != nil { + // just log an error and proceed and assume an empty filter + log.Printf("Error on unmarshal model.MembershipFilter request body - %s\n", err.Error()) } request.GroupIDs = append(request.GroupIDs, groupID) + request.AppID = current.AppID + request.OrgID = current.OrgID //check if allowed to update - members, err := h.app.Services.FindGroupMemberships(clientID, request) + members, err := h.app.Services.FindGroupMemberships(request) if err != nil { log.Printf("api.GetGroupMembers error: %s", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) @@ -1074,15 +1047,8 @@ func (h *ApisHandler) CreateMember(current *model.User, w http.ResponseWriter, r return } - data, err := ioutil.ReadAll(r.Body) - if err != nil { - log.Printf("Error on marshal create a pending member - %s\n", err.Error()) - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) - return - } - var requestData createMemberRequest - err = json.Unmarshal(data, &requestData) + err := json.NewDecoder(r.Body).Decode(&requestData) if err != nil { log.Printf("Error on unmarshal the create pending member data - %s\n", err.Error()) http.Error(w, err.Error(), http.StatusBadRequest) @@ -1108,7 +1074,7 @@ func (h *ApisHandler) CreateMember(current *model.User, w http.ResponseWriter, r } //check if allowed to update - group, err := h.app.Services.GetGroupEntity(clientID, groupID) + group, err := h.app.Services.GetGroupEntity(current.AppID, current.OrgID, groupID) if err != nil { log.Println(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) @@ -1120,7 +1086,7 @@ func (h *ApisHandler) CreateMember(current *model.User, w http.ResponseWriter, r return } - membership, _ := h.app.Services.FindGroupMembership(clientID, group.ID, current.ID) + membership, _ := h.app.Services.FindGroupMembership(current.AppID, current.OrgID, group.ID, current.ID) if membership == nil || !membership.IsAdmin() { log.Printf("error: api.CreateMember() - %s is not allowed to create group member", current.Email) w.WriteHeader(http.StatusForbidden) @@ -1211,15 +1177,8 @@ func (h *ApisHandler) MembershipApproval(current *model.User, w http.ResponseWri return } - data, err := ioutil.ReadAll(r.Body) - if err != nil { - log.Printf("Error on marshal the membership item - %s\n", err.Error()) - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) - return - } - var requestData membershipApprovalRequest - err = json.Unmarshal(data, &requestData) + err := json.NewDecoder(r.Body).Decode(&requestData) if err != nil { log.Printf("Error on unmarshal the membership request data - %s\n", err.Error()) http.Error(w, err.Error(), http.StatusBadRequest) @@ -1370,15 +1329,8 @@ func (h *ApisHandler) UpdateMembership(current *model.User, w http.ResponseWrite return } - data, err := ioutil.ReadAll(r.Body) - if err != nil { - log.Printf("Error on marshal the membership update item - %s\n", err.Error()) - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) - return - } - var requestData updateMembershipRequest - err = json.Unmarshal(data, &requestData) + err := json.NewDecoder(r.Body).Decode(&requestData) if err != nil { log.Printf("Error on unmarshal the membership request update data - %s\n", err.Error()) http.Error(w, err.Error(), http.StatusBadRequest) @@ -1622,15 +1574,8 @@ func (h *ApisHandler) CreateGroupEvent(current *model.User, w http.ResponseWrite return } - data, err := ioutil.ReadAll(r.Body) - if err != nil { - log.Printf("Error on marshal the create group item - %s\n", err.Error()) - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) - return - } - var requestData groupEventRequest - err = json.Unmarshal(data, &requestData) + err := json.NewDecoder(r.Body).Decode(&requestData) if err != nil { log.Printf("Error on unmarshal the create event request data - %s\n", err.Error()) http.Error(w, err.Error(), http.StatusBadRequest) @@ -1705,15 +1650,8 @@ func (h *ApisHandler) UpdateGroupEvent(current *model.User, w http.ResponseWrite return } - data, err := ioutil.ReadAll(r.Body) - if err != nil { - log.Printf("Error on marshal the update group item - %s\n", err.Error()) - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) - return - } - var requestData groupEventRequest - err = json.Unmarshal(data, &requestData) + err := json.NewDecoder(r.Body).Decode(&requestData) if err != nil { log.Printf("Error on unmarshal the update event request data - %s\n", err.Error()) http.Error(w, err.Error(), http.StatusBadRequest) @@ -1935,15 +1873,8 @@ func (h *ApisHandler) CreateGroupPost(current *model.User, w http.ResponseWriter return } - data, err := ioutil.ReadAll(r.Body) - if err != nil { - log.Printf("Error on marshal the create group item - %s\n", err.Error()) - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) - return - } - var post *model.Post - err = json.Unmarshal(data, &post) + err := json.NewDecoder(r.Body).Decode(&post) if err != nil { log.Printf("error on unmarshal posts for group - %s", err.Error()) http.Error(w, err.Error(), http.StatusBadRequest) @@ -2096,15 +2027,8 @@ func (h *ApisHandler) UpdateGroupPost(current *model.User, w http.ResponseWriter return } - data, err := ioutil.ReadAll(r.Body) - if err != nil { - log.Printf("Error on marshal the create group item - %s\n", err.Error()) - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) - return - } - var post *model.Post - err = json.Unmarshal(data, &post) + err := json.NewDecoder(r.Body).Decode(&post) if err != nil { log.Printf("error on unmarshal post (%s) - %s", postID, err.Error()) http.Error(w, err.Error(), http.StatusBadRequest) @@ -2187,15 +2111,8 @@ func (h *ApisHandler) ReactToGroupPost(current *model.User, w http.ResponseWrite return } - data, err := ioutil.ReadAll(r.Body) - if err != nil { - log.Printf("Error on read reactToGroupPostRequestBody - %s\n", err.Error()) - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) - return - } - var body reactToGroupPostRequestBody - err = json.Unmarshal(data, &body) + err := json.NewDecoder(r.Body).Decode(&body) if err != nil { log.Printf("error on unmarshal reactToGroupPostRequestBody (%s) - %s", postID, err.Error()) http.Error(w, err.Error(), http.StatusBadRequest) @@ -2272,15 +2189,8 @@ func (h *ApisHandler) ReportAbuseGroupPost(current *model.User, w http.ResponseW return } - data, err := ioutil.ReadAll(r.Body) - if err != nil { - log.Printf("Error on read reportAbuseGroupPostRequestBody - %s\n", err.Error()) - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) - return - } - var body *reportAbuseGroupPostRequestBody - err = json.Unmarshal(data, &body) + err := json.NewDecoder(r.Body).Decode(&body) if err != nil { log.Printf("error on unmarshal reportAbuseGroupPostRequestBody (%s) - %s", postID, err.Error()) http.Error(w, err.Error(), http.StatusBadRequest) diff --git a/driver/web/rest/internal.go b/driver/web/rest/internal.go index 910564e0..5b99fd8e 100644 --- a/driver/web/rest/internal.go +++ b/driver/web/rest/internal.go @@ -19,7 +19,6 @@ import ( "fmt" "groups/core" "groups/core/model" - "io/ioutil" "log" "net/http" "strconv" @@ -52,7 +51,9 @@ func (h *InternalApisHandler) IntGetUserGroupMemberships(appID string, orgID str } externalID := identifier - groups, err := h.app.Services.FindGroupsV3(clientID, model.GroupsFilter{ + groups, err := h.app.Services.FindGroupsV3(model.GroupsFilter{ + AppID: appID, + OrgID: orgID, MemberExternalID: &externalID, }) if err != nil { @@ -109,15 +110,17 @@ func (h *InternalApisHandler) IntGetGroup(appID string, orgID string, w http.Res return } - group, err := h.app.Services.GetGroupEntity(clientID, identifier) + group, err := h.app.Services.GetGroupEntity(appID, orgID, identifier) if err != nil { log.Printf("Unable to retrieve group with ID '%s': %s", identifier, err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } - membershipCollection, err := h.app.Services.FindGroupMemberships(clientID, model.MembershipFilter{ + membershipCollection, err := h.app.Services.FindGroupMemberships(model.MembershipFilter{ GroupIDs: []string{group.ID}, + AppID: appID, + OrgID: orgID, }) if err != nil { log.Printf("Unable to retrieve memberships: %s", err) @@ -172,15 +175,17 @@ func (h *InternalApisHandler) IntGetGroupMembersByGroupTitle(appID string, orgID } } - group, err := h.app.Services.GetGroupEntityByTitle(clientID, title) + group, err := h.app.Services.GetGroupEntityByTitle(appID, orgID, title) if err != nil { log.Printf("Unable to retrieve group with title '%s': %s", title, err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } - membershipCollection, err := h.app.Services.FindGroupMemberships(clientID, model.MembershipFilter{ + membershipCollection, err := h.app.Services.FindGroupMemberships(model.MembershipFilter{ GroupIDs: []string{group.ID}, + AppID: appID, + OrgID: orgID, Offset: offset, Limit: limit, }) @@ -282,7 +287,7 @@ func (h *InternalApisHandler) GroupStats(appID string, orgID string, w http.Resp data, err := json.Marshal(groupsStats) if err != nil { - log.Printf("Error GroupStats(%s): %s", clientID, err) + log.Printf("Error GroupStats(appID %s, orgID %s): %s", appID, orgID, err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } @@ -319,7 +324,7 @@ func (h *InternalApisHandler) UpdateGroupDateUpdated(appID string, orgID string, return } - err := h.app.Services.UpdateGroupDateUpdated(clientID, groupID) + err := h.app.Services.UpdateGroupDateUpdated(appID, orgID, groupID) if err != nil { log.Printf("Error on updating date updated of group %s - %s\n", groupID, err) http.Error(w, fmt.Sprintf("Error on updating date updated of group %s - %s\n", groupID, err), http.StatusInternalServerError) @@ -352,15 +357,8 @@ func (h *InternalApisHandler) CreateGroupEvent(appID string, orgID string, w htt return } - data, err := ioutil.ReadAll(r.Body) - if err != nil { - log.Printf("Error on marshal the create group event - %s\n", err.Error()) - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) - return - } - var requestData intCreateGroupEventRequestBody - err = json.Unmarshal(data, &requestData) + err := json.NewDecoder(r.Body).Decode(&requestData) if err != nil { log.Printf("Error on unmarshal the create event request data - %s\n", err.Error()) http.Error(w, err.Error(), http.StatusBadRequest) @@ -376,7 +374,7 @@ func (h *InternalApisHandler) CreateGroupEvent(appID string, orgID string, w htt } //check if allowed to create - group, err := h.app.Services.GetGroupEntity(clientID, groupID) + group, err := h.app.Services.GetGroupEntity(appID, orgID, groupID) if err != nil { log.Println(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) @@ -389,7 +387,7 @@ func (h *InternalApisHandler) CreateGroupEvent(appID string, orgID string, w htt return } - grEvent, err := h.app.Services.CreateEvent(clientID, nil, requestData.EventID, group, requestData.ToMembersList, requestData.Creator) + grEvent, err := h.app.Services.CreateEvent(appID, orgID, requestData.EventID, group, requestData.ToMembersList, requestData.Creator) if err != nil { log.Printf("Error on creating an event - %s\n", err) http.Error(w, fmt.Sprintf("Error on creating an event - %s\n", err), http.StatusInternalServerError) @@ -434,7 +432,7 @@ func (h *InternalApisHandler) DeleteGroupEvent(appID string, orgID string, w htt return } - err := h.app.Services.DeleteEvent(clientID, nil, eventID, groupID) + err := h.app.Services.DeleteEvent(appID, orgID, eventID, groupID) if err != nil { log.Printf("Error on deleting an event - %s\n", err) http.Error(w, err.Error(), http.StatusInternalServerError) @@ -477,15 +475,8 @@ func (h *InternalApisHandler) SendGroupNotification(appID string, orgID string, return } - data, err := ioutil.ReadAll(r.Body) - if err != nil { - log.Printf("Error on read the sendGroupNotificationRequestBody - %s\n", err.Error()) - http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) - return - } - var requestData sendGroupNotificationRequestBody - err = json.Unmarshal(data, &requestData) + err := json.NewDecoder(r.Body).Decode(&requestData) if err != nil { log.Printf("Error on unmarshal the sendGroupNotificationRequestBody - %s\n", err.Error()) http.Error(w, err.Error(), http.StatusBadRequest) @@ -510,7 +501,7 @@ func (h *InternalApisHandler) SendGroupNotification(appID string, orgID string, Topic: requestData.Topic, Data: requestData.Data, } - err = h.app.Services.SendGroupNotification(clientID, notification) + err = h.app.Services.SendGroupNotification(appID, orgID, notification) if err != nil { log.Println(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError)