Implement endpoint for APIv4: GET /users/{user_id}/audits (#5472)

Этот коммит содержится в:
Saturnino Abril
2017-02-21 21:07:57 +09:00
коммит произвёл George Goldberg
родитель 7068307a1c
Коммит 5c19d9be7f
7 изменённых файлов: 113 добавлений и 47 удалений

Просмотреть файл

@@ -36,6 +36,7 @@ func InitUser() {
BaseRoutes.User.Handle("/sessions", ApiSessionRequired(getSessions)).Methods("GET")
BaseRoutes.User.Handle("/sessions/revoke", ApiSessionRequired(revokeSession)).Methods("POST")
BaseRoutes.User.Handle("/audits", ApiSessionRequired(getAudits)).Methods("GET")
}
@@ -481,51 +482,71 @@ func Logout(c *Context, w http.ResponseWriter, r *http.Request) {
}
func getSessions(c *Context, w http.ResponseWriter, r *http.Request) {
c.RequireUserId()
if c.Err != nil {
return
}
c.RequireUserId()
if c.Err != nil {
return
}
if !app.SessionHasPermissionToUser(c.Session, c.Params.UserId) {
c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
return
}
if !app.SessionHasPermissionToUser(c.Session, c.Params.UserId) {
c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
return
}
if sessions, err := app.GetSessions(c.Params.UserId); err != nil {
c.Err = err
return
} else {
for _, session := range sessions {
session.Sanitize()
}
if sessions, err := app.GetSessions(c.Params.UserId); err != nil {
c.Err = err
return
} else {
for _, session := range sessions {
session.Sanitize()
}
w.Write([]byte(model.SessionsToJson(sessions)))
return
}
w.Write([]byte(model.SessionsToJson(sessions)))
return
}
}
func revokeSession(c *Context, w http.ResponseWriter, r *http.Request) {
c.RequireUserId()
if c.Err != nil {
return
}
c.RequireUserId()
if c.Err != nil {
return
}
if !app.SessionHasPermissionToUser(c.Session, c.Params.UserId) {
c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
return
}
if !app.SessionHasPermissionToUser(c.Session, c.Params.UserId) {
c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
return
}
props := model.MapFromJson(r.Body)
sessionId := props["session_id"]
props := model.MapFromJson(r.Body)
sessionId := props["session_id"]
if sessionId == "" {
c.SetInvalidParam("session_id")
}
if sessionId == "" {
c.SetInvalidParam("session_id")
}
if err := app.RevokeSessionById(sessionId); err != nil {
c.Err = err
return
}
if err := app.RevokeSessionById(sessionId); err != nil {
c.Err = err
return
}
ReturnStatusOK(w)
}
ReturnStatusOK(w)
}
func getAudits(c *Context, w http.ResponseWriter, r *http.Request) {
c.RequireUserId()
if c.Err != nil {
return
}
if !app.SessionHasPermissionToUser(c.Session, c.Params.UserId) {
c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
return
}
if audits, err := app.GetAuditsPage(c.Params.UserId, c.Params.Page, c.Params.PerPage); err != nil {
c.Err = err
return
} else {
w.Write([]byte(audits.ToJson()))
return
}
}

Просмотреть файл

@@ -811,7 +811,7 @@ func TestGetSessions(t *testing.T) {
user := th.BasicUser
Client.Login(user.Email, user.Password)
sessions, resp := Client.GetSessions(user.Id, "")
for _, session := range sessions {
if session.UserId != user.Id {
@@ -899,3 +899,28 @@ func TestRevokeSessions(t *testing.T) {
CheckNoError(t, resp)
}
func TestGetAudits(t *testing.T) {
th := Setup().InitBasic().InitSystemAdmin()
defer TearDown()
Client := th.Client
user := th.BasicUser
audits, resp := Client.GetAudits(user.Id, 0, 100, "")
for _, audit := range audits {
if audit.UserId != user.Id {
t.Fatal("user id does not match audit user id")
}
}
CheckNoError(t, resp)
_, resp = Client.GetAudits(th.BasicUser2.Id, 0, 100, "")
CheckForbiddenStatus(t, resp)
Client.Logout()
_, resp = Client.GetAudits(user.Id, 0, 100, "")
CheckUnauthorizedStatus(t, resp)
_, resp = th.SystemAdminClient.GetAudits(user.Id, 0, 100, "")
CheckNoError(t, resp)
}

Просмотреть файл

@@ -8,7 +8,15 @@ import (
)
func GetAudits(userId string, limit int) (model.Audits, *model.AppError) {
if result := <-Srv.Store.Audit().Get(userId, limit); result.Err != nil {
if result := <-Srv.Store.Audit().Get(userId, 0, limit); result.Err != nil {
return nil, result.Err
} else {
return result.Data.(model.Audits), nil
}
}
func GetAuditsPage(userId string, page int, perPage int) (model.Audits, *model.AppError) {
if result := <-Srv.Store.Audit().Get(userId, page*perPage, perPage); result.Err != nil {
return nil, result.Err
} else {
return result.Data.(model.Audits), nil

Просмотреть файл

@@ -459,6 +459,17 @@ func (c *Client4) RevokeSession(userId, sessionId string) (bool, *Response) {
}
}
// GetAudits returns a list of audit based on the provided user id string.
func (c *Client4) GetAudits(userId string, page int, perPage int, etag string) (Audits, *Response) {
query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage)
if r, err := c.DoApiGet(c.GetUserRoute(userId)+"/audits"+query, etag); err != nil {
return nil, &Response{StatusCode: r.StatusCode, Error: err}
} else {
defer closeBody(r)
return AuditsFromJson(r.Body), BuildResponse(r)
}
}
// Team Section
// CreateTeam creates a team in the system based on the provided team struct.

Просмотреть файл

@@ -54,7 +54,7 @@ func (s SqlAuditStore) Save(audit *model.Audit) StoreChannel {
return storeChannel
}
func (s SqlAuditStore) Get(user_id string, limit int) StoreChannel {
func (s SqlAuditStore) Get(user_id string, offset int, limit int) StoreChannel {
storeChannel := make(StoreChannel, 1)
@@ -75,10 +75,10 @@ func (s SqlAuditStore) Get(user_id string, limit int) StoreChannel {
query += " WHERE UserId = :user_id"
}
query += " ORDER BY CreateAt DESC LIMIT :limit"
query += " ORDER BY CreateAt DESC LIMIT :limit OFFSET :offset"
var audits model.Audits
if _, err := s.GetReplica().Select(&audits, query, map[string]interface{}{"user_id": user_id, "limit": limit}); err != nil {
if _, err := s.GetReplica().Select(&audits, query, map[string]interface{}{"user_id": user_id, "limit": limit, "offset": offset}); err != nil {
result.Err = model.NewLocAppError("SqlAuditStore.Get", "store.sql_audit.get.finding.app_error", nil, "user_id="+user_id)
} else {
result.Data = audits

Просмотреть файл

@@ -4,9 +4,10 @@
package store
import (
"github.com/mattermost/platform/model"
"testing"
"time"
"github.com/mattermost/platform/model"
)
func TestSqlAuditStore(t *testing.T) {
@@ -25,7 +26,7 @@ func TestSqlAuditStore(t *testing.T) {
time.Sleep(100 * time.Millisecond)
c := store.Audit().Get(audit.UserId, 100)
c := store.Audit().Get(audit.UserId, 0, 100)
result := <-c
audits := result.Data.(model.Audits)
@@ -37,7 +38,7 @@ func TestSqlAuditStore(t *testing.T) {
t.Fatal("Failed to save property for extra info")
}
c = store.Audit().Get("missing", 100)
c = store.Audit().Get("missing", 0, 100)
result = <-c
audits = result.Data.(model.Audits)
@@ -45,7 +46,7 @@ func TestSqlAuditStore(t *testing.T) {
t.Fatal("Should have returned empty because user_id is missing")
}
c = store.Audit().Get("", 100)
c = store.Audit().Get("", 0, 100)
result = <-c
audits = result.Data.(model.Audits)

Просмотреть файл

@@ -208,7 +208,7 @@ type SessionStore interface {
type AuditStore interface {
Save(audit *model.Audit) StoreChannel
Get(user_id string, limit int) StoreChannel
Get(user_id string, offset int, limit int) StoreChannel
PermanentDeleteByUser(userId string) StoreChannel
}