MM-14748: Allow to invalidate email invites (#10509)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
3c8975780d
Коммит
c370d30041
15
api4/team.go
15
api4/team.go
@@ -55,6 +55,7 @@ func (api *API) InitTeam() {
|
||||
api.BaseRoutes.TeamMember.Handle("/schemeRoles", api.ApiSessionRequired(updateTeamMemberSchemeRoles)).Methods("PUT")
|
||||
api.BaseRoutes.Team.Handle("/import", api.ApiSessionRequired(importTeam)).Methods("POST")
|
||||
api.BaseRoutes.Team.Handle("/invite/email", api.ApiSessionRequired(inviteUsersToTeam)).Methods("POST")
|
||||
api.BaseRoutes.Teams.Handle("/invites/email", api.ApiSessionRequired(invalidateAllEmailInvites)).Methods("DELETE")
|
||||
api.BaseRoutes.Teams.Handle("/invite/{invite_id:[A-Za-z0-9]+}", api.ApiHandler(getInviteInfo)).Methods("GET")
|
||||
}
|
||||
|
||||
@@ -789,6 +790,20 @@ func getInviteInfo(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(model.MapToJson(result)))
|
||||
}
|
||||
|
||||
func invalidateAllEmailInvites(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if !c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_MANAGE_SYSTEM) {
|
||||
c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
|
||||
return
|
||||
}
|
||||
|
||||
if err := c.App.InvalidateAllEmailInvites(); err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
ReturnStatusOK(w)
|
||||
}
|
||||
|
||||
func getTeamIcon(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
c.RequireTeamId()
|
||||
if c.Err != nil {
|
||||
|
||||
@@ -1256,3 +1256,10 @@ func (a *App) RemoveTeamIcon(teamId string) *model.AppError {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) InvalidateAllEmailInvites() *model.AppError {
|
||||
if result := <-a.Srv.Store.Token().RemoveAllTokensByType(TOKEN_TYPE_TEAM_INVITATION); result.Err != nil {
|
||||
return model.NewAppError("InvalidateAllEmailInvites", "api.team.invalidate_all_email_invites.app_error", nil, result.Err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1778,6 +1778,10 @@
|
||||
"id": "api.team.import_team.unavailable.app_error",
|
||||
"translation": "Malformed request: filesize field is not present."
|
||||
},
|
||||
{
|
||||
"id": "api.team.invalidate_all_email_invites.app_error",
|
||||
"translation": "Error invalidating email invites."
|
||||
},
|
||||
{
|
||||
"id": "api.team.invite_members.disabled.app_error",
|
||||
"translation": "Email invitations are disabled."
|
||||
@@ -6022,6 +6026,10 @@
|
||||
"id": "store.sql_recover.delete.app_error",
|
||||
"translation": "Unable to delete token"
|
||||
},
|
||||
{
|
||||
"id": "store.sql_recover.remove_all_tokens_by_type.app_error",
|
||||
"translation": "Unable to remove all the tokens of a type"
|
||||
},
|
||||
{
|
||||
"id": "store.sql_recover.get_by_code.app_error",
|
||||
"translation": "Unable to get a token with this code"
|
||||
|
||||
@@ -75,3 +75,12 @@ func (s SqlTokenStore) Cleanup() {
|
||||
mlog.Error("Unable to cleanup token store.")
|
||||
}
|
||||
}
|
||||
|
||||
func (s SqlTokenStore) RemoveAllTokensByType(tokenType string) store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
if _, err := s.GetMaster().Exec("DELETE FROM Tokens WHERE Type = :TokenType", map[string]interface{}{"TokenType": tokenType}); err != nil {
|
||||
result.Err = model.NewAppError("SqlTokenStore.RemoveAllTokensByType", "store.sql_recover.remove_all_tokens_by_type.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -443,6 +443,7 @@ type TokenStore interface {
|
||||
Delete(token string) StoreChannel
|
||||
GetByToken(token string) StoreChannel
|
||||
Cleanup()
|
||||
RemoveAllTokensByType(tokenType string) StoreChannel
|
||||
}
|
||||
|
||||
type EmojiStore interface {
|
||||
|
||||
@@ -98,6 +98,22 @@ func (_m *PostStore) Get(id string) store.StoreChannel {
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetDirectPostParentsForExportAfter provides a mock function with given fields: limit, afterId
|
||||
func (_m *PostStore) GetDirectPostParentsForExportAfter(limit int, afterId string) store.StoreChannel {
|
||||
ret := _m.Called(limit, afterId)
|
||||
|
||||
var r0 store.StoreChannel
|
||||
if rf, ok := ret.Get(0).(func(int, string) store.StoreChannel); ok {
|
||||
r0 = rf(limit, afterId)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(store.StoreChannel)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetEtag provides a mock function with given fields: channelId, allowFromCache
|
||||
func (_m *PostStore) GetEtag(channelId string, allowFromCache bool) store.StoreChannel {
|
||||
ret := _m.Called(channelId, allowFromCache)
|
||||
@@ -470,18 +486,3 @@ func (_m *PostStore) Update(newPost *model.Post, oldPost *model.Post) store.Stor
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
func (_m *PostStore) GetDirectPostParentsForExportAfter(limit int, afterId string) store.StoreChannel {
|
||||
ret := _m.Called(limit, afterId)
|
||||
|
||||
var r0 store.StoreChannel
|
||||
if rf, ok := ret.Get(0).(func(int, string) store.StoreChannel); ok {
|
||||
r0 = rf(limit, afterId)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(store.StoreChannel)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ package mocks
|
||||
import gorp "github.com/mattermost/gorp"
|
||||
import mock "github.com/stretchr/testify/mock"
|
||||
|
||||
import squirrel "github.com/Masterminds/squirrel"
|
||||
import store "github.com/mattermost/mattermost-server/store"
|
||||
|
||||
// SqlStore is an autogenerated mock type for the SqlStore type
|
||||
@@ -855,3 +856,17 @@ func (_m *SqlStore) Webhook() store.WebhookStore {
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// getQueryBuilder provides a mock function with given fields:
|
||||
func (_m *SqlStore) getQueryBuilder() squirrel.StatementBuilderType {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 squirrel.StatementBuilderType
|
||||
if rf, ok := ret.Get(0).(func() squirrel.StatementBuilderType); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(squirrel.StatementBuilderType)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
@@ -50,6 +50,22 @@ func (_m *TokenStore) GetByToken(token string) store.StoreChannel {
|
||||
return r0
|
||||
}
|
||||
|
||||
// RemoveAllTokensByType provides a mock function with given fields: tokenType
|
||||
func (_m *TokenStore) RemoveAllTokensByType(tokenType string) store.StoreChannel {
|
||||
ret := _m.Called(tokenType)
|
||||
|
||||
var r0 store.StoreChannel
|
||||
if rf, ok := ret.Get(0).(func(string) store.StoreChannel); ok {
|
||||
r0 = rf(tokenType)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(store.StoreChannel)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Save provides a mock function with given fields: recovery
|
||||
func (_m *TokenStore) Save(recovery *model.Token) store.StoreChannel {
|
||||
ret := _m.Called(recovery)
|
||||
|
||||
Ссылка в новой задаче
Block a user