1
0
Fork 0
mirror of https://github.com/documize/community.git synced 2025-07-19 05:09:42 +02:00

event logging

This commit is contained in:
Harvey Kandola 2017-05-04 12:31:52 +01:00
parent b6c676149a
commit 93ed361705
48 changed files with 861 additions and 853 deletions

View file

@ -64,6 +64,8 @@ func AttachmentDownload(w http.ResponseWriter, r *http.Request) {
_, err = w.Write(attachment.Data)
log.IfErr(err)
p.RecordEvent(entity.EventTypeAttachmentDownload)
}
// GetAttachments is an end-point that returns all of the attachments of a particular documentID.
@ -125,7 +127,6 @@ func DeleteAttachment(w http.ResponseWriter, r *http.Request) {
}
tx, err := request.Db.Beginx()
if err != nil {
writeTransactionError(w, method, err)
return
@ -141,6 +142,8 @@ func DeleteAttachment(w http.ResponseWriter, r *http.Request) {
return
}
p.RecordEvent(entity.EventTypeAttachmentDelete)
log.IfErr(tx.Commit())
writeSuccessEmptyJSON(w)
@ -217,6 +220,8 @@ func AddAttachments(w http.ResponseWriter, r *http.Request) {
return
}
p.RecordEvent(entity.EventTypeAttachmentAdd)
log.IfErr(tx.Commit())
writeSuccessEmptyJSON(w)

View file

@ -90,7 +90,6 @@ func Authenticate(w http.ResponseWriter, r *http.Request) {
}
org, err := p.GetOrganizationByDomain(domain)
if err != nil {
writeUnauthorizedError(w)
return
@ -111,7 +110,6 @@ func Authenticate(w http.ResponseWriter, r *http.Request) {
authModel.User = user
json, err := json.Marshal(authModel)
if err != nil {
writeJSONMarshalError(w, method, "user", err)
return

View file

@ -245,6 +245,8 @@ func processDocument(p request.Persister, filename, job, folderID string, fileRe
SourceType: entity.ActivitySourceTypeDocument,
ActivityType: entity.ActivityTypeCreated})
p.RecordEvent(entity.EventTypeDocumentUpload)
log.IfErr(tx.Commit())
return

View file

@ -65,6 +65,8 @@ func SearchDocuments(w http.ResponseWriter, r *http.Request) {
return
}
p.RecordEvent(entity.EventTypeSearch)
writeSuccessBytes(w, data)
}
@ -110,17 +112,13 @@ func GetDocument(w http.ResponseWriter, r *http.Request) {
return
}
err = p.RecordUserActivity(entity.UserActivity{
_ = p.RecordUserActivity(entity.UserActivity{
LabelID: document.LabelID,
SourceID: document.RefID,
SourceType: entity.ActivitySourceTypeDocument,
ActivityType: entity.ActivityTypeRead})
if err != nil {
log.IfErr(p.Context.Transaction.Rollback())
log.Error("Cannot record user activity", err)
return
}
p.RecordEvent(entity.EventTypeDocumentView)
log.IfErr(p.Context.Transaction.Commit())
@ -301,6 +299,8 @@ func DeleteDocument(w http.ResponseWriter, r *http.Request) {
SourceType: entity.ActivitySourceTypeDocument,
ActivityType: entity.ActivityTypeDeleted})
p.RecordEvent(entity.EventTypeDocumentDelete)
log.IfErr(tx.Commit())
writeSuccessEmptyJSON(w)
@ -435,6 +435,8 @@ func UpdateDocument(w http.ResponseWriter, r *http.Request) {
return
}
p.RecordEvent(entity.EventTypeDocumentUpdate)
log.IfErr(tx.Commit())
writeSuccessEmptyJSON(w)

View file

@ -18,9 +18,11 @@ import (
"encoding/xml"
"fmt"
"github.com/documize/community/core/api/entity"
"github.com/documize/community/core/api/request"
"github.com/documize/community/core/api/util"
"github.com/documize/community/core/event"
"github.com/documize/community/core/log"
)
// GetSMTPConfig returns installation-wide SMTP settings
@ -160,6 +162,15 @@ func SaveLicense(w http.ResponseWriter, r *http.Request) {
event.Handler().Publish(string(event.TypeSystemLicenseChange))
p.Context.Transaction, err = request.Db.Beginx()
if err != nil {
writeTransactionError(w, method, err)
return
}
p.RecordEvent(entity.EventTypeSystemLicense)
log.IfErr(p.Context.Transaction.Commit())
util.WriteSuccessEmptyJSON(w)
}
@ -227,6 +238,8 @@ func SaveAuthConfig(w http.ResponseWriter, r *http.Request) {
return
}
p.RecordEvent(entity.EventTypeSystemAuth)
p.Context.Transaction.Commit()
util.WriteSuccessEmptyJSON(w)

View file

@ -81,6 +81,8 @@ func AddFolder(w http.ResponseWriter, r *http.Request) {
return
}
p.RecordEvent(entity.EventTypeSpaceAdd)
log.IfErr(tx.Commit())
folder, _ = p.GetLabel(id)
@ -254,6 +256,8 @@ func UpdateFolder(w http.ResponseWriter, r *http.Request) {
return
}
p.RecordEvent(entity.EventTypeSpaceUpdate)
log.IfErr(tx.Commit())
json, err := json.Marshal(folder)
@ -336,6 +340,8 @@ func RemoveFolder(w http.ResponseWriter, r *http.Request) {
return
}
p.RecordEvent(entity.EventTypeSpaceDelete)
log.IfErr(tx.Commit())
writeSuccessString(w, "{}")
@ -394,6 +400,8 @@ func DeleteFolder(w http.ResponseWriter, r *http.Request) {
return
}
p.RecordEvent(entity.EventTypeSpaceDelete)
log.IfErr(tx.Commit())
writeSuccessString(w, "{}")
@ -554,6 +562,8 @@ func SetFolderPermissions(w http.ResponseWriter, r *http.Request) {
log.Error("p.UpdateLabel()", p.UpdateLabel(label))
p.RecordEvent(entity.EventTypeSpacePermission)
log.Error("tx.Commit()", tx.Commit())
writeSuccessEmptyJSON(w)
@ -685,10 +695,11 @@ func AcceptSharedFolder(w http.ResponseWriter, r *http.Request) {
return
}
p.RecordEvent(entity.EventTypeSpaceJoin)
log.IfErr(tx.Commit())
data, err := json.Marshal(user)
if err != nil {
writeJSONMarshalError(w, method, "user", err)
return
@ -849,6 +860,8 @@ func InviteToFolder(w http.ResponseWriter, r *http.Request) {
}
}
p.RecordEvent(entity.EventTypeSpaceInvite)
log.IfErr(tx.Commit())
_, err = w.Write([]byte("{}"))

View file

@ -127,6 +127,8 @@ func AddDocumentPage(w http.ResponseWriter, r *http.Request) {
SourceType: entity.ActivitySourceTypeDocument,
ActivityType: entity.ActivityTypeCreated})
p.RecordEvent(entity.EventTypeSectionAdd)
log.IfErr(tx.Commit())
newPage, _ := p.GetPage(pageID)
@ -357,6 +359,8 @@ func DeleteDocumentPage(w http.ResponseWriter, r *http.Request) {
SourceType: entity.ActivitySourceTypeDocument,
ActivityType: entity.ActivityTypeDeleted})
p.RecordEvent(entity.EventTypeSectionDelete)
log.IfErr(tx.Commit())
writeSuccessEmptyJSON(w)
@ -439,6 +443,8 @@ func DeleteDocumentPages(w http.ResponseWriter, r *http.Request) {
SourceType: entity.ActivitySourceTypeDocument,
ActivityType: entity.ActivityTypeDeleted})
p.RecordEvent(entity.EventTypeSectionDelete)
log.IfErr(tx.Commit())
writeSuccessEmptyJSON(w)
@ -541,12 +547,13 @@ func UpdateDocumentPage(w http.ResponseWriter, r *http.Request) {
SourceType: entity.ActivitySourceTypeDocument,
ActivityType: entity.ActivityTypeEdited})
p.RecordEvent(entity.EventTypeSectionUpdate)
log.IfErr(p.Context.Transaction.Commit())
updatedPage, err := p.GetPage(pageID)
json, err := json.Marshal(updatedPage)
if err != nil {
writeJSONMarshalError(w, method, "page", err)
return
@ -613,6 +620,8 @@ func ChangeDocumentPageSequence(w http.ResponseWriter, r *http.Request) {
}
}
p.RecordEvent(entity.EventTypeSectionResequence)
log.IfErr(tx.Commit())
writeSuccessEmptyJSON(w)
@ -676,6 +685,8 @@ func ChangeDocumentPageLevel(w http.ResponseWriter, r *http.Request) {
}
}
p.RecordEvent(entity.EventTypeSectionResequence)
log.IfErr(tx.Commit())
writeSuccessEmptyJSON(w)
@ -801,6 +812,8 @@ func GetDocumentRevisions(w http.ResponseWriter, r *http.Request) {
return
}
p.RecordEvent(entity.EventTypeDocumentRevisions)
writeSuccessBytes(w, payload)
}
@ -1015,6 +1028,8 @@ func RollbackDocumentPage(w http.ResponseWriter, r *http.Request) {
SourceType: entity.ActivitySourceTypeDocument,
ActivityType: entity.ActivityTypeReverted})
p.RecordEvent(entity.EventTypeSectionRollback)
log.IfErr(tx.Commit())
payload, err := json.Marshal(page)
@ -1126,6 +1141,8 @@ func CopyPage(w http.ResponseWriter, r *http.Request) {
SourceType: entity.ActivitySourceTypeDocument,
ActivityType: entity.ActivityTypeEdited})
p.RecordEvent(entity.EventTypeSectionCopy)
log.IfErr(tx.Commit())
newPage, _ := p.GetPage(pageID)

View file

@ -85,6 +85,8 @@ func AddPin(w http.ResponseWriter, r *http.Request) {
return
}
p.RecordEvent(entity.EventTypePinAdd)
log.IfErr(tx.Commit())
newPin, err := p.GetPin(pin.RefID)
@ -178,6 +180,8 @@ func DeleteUserPin(w http.ResponseWriter, r *http.Request) {
return
}
p.RecordEvent(entity.EventTypePinDelete)
log.IfErr(tx.Commit())
util.WriteSuccessEmptyJSON(w)
@ -238,6 +242,8 @@ func UpdatePinSequence(w http.ResponseWriter, r *http.Request) {
}
}
p.RecordEvent(entity.EventTypePinResequence)
log.IfErr(tx.Commit())
newPins, err := p.GetUserPins(userID)

View file

@ -234,6 +234,8 @@ func AddBlock(w http.ResponseWriter, r *http.Request) {
return
}
p.RecordEvent(entity.EventTypeBlockAdd)
log.IfErr(tx.Commit())
b, err = p.GetBlock(b.RefID)
@ -363,6 +365,8 @@ func UpdateBlock(w http.ResponseWriter, r *http.Request) {
return
}
p.RecordEvent(entity.EventTypeBlockUpdate)
log.IfErr(tx.Commit())
writeSuccessEmptyJSON(w)
@ -403,6 +407,8 @@ func DeleteBlock(w http.ResponseWriter, r *http.Request) {
return
}
p.RecordEvent(entity.EventTypeBlockDelete)
log.IfErr(tx.Commit())
writeSuccessEmptyJSON(w)

View file

@ -34,8 +34,8 @@ var Product core.ProdInfo
func init() {
Product.Major = "1"
Product.Minor = "46"
Product.Patch = "2"
Product.Minor = "47"
Product.Patch = "0"
Product.Version = fmt.Sprintf("%s.%s.%s", Product.Major, Product.Minor, Product.Patch)
Product.Edition = "Community"
Product.Title = fmt.Sprintf("%s Edition", Product.Edition)

View file

@ -169,6 +169,8 @@ func SaveAsTemplate(w http.ResponseWriter, r *http.Request) {
}
}
p.RecordEvent(entity.EventTypeTemplateAdd)
// Commit and return new document template
log.IfErr(tx.Commit())
@ -180,7 +182,6 @@ func SaveAsTemplate(w http.ResponseWriter, r *http.Request) {
}
d, err := json.Marshal(doc)
if err != nil {
writeJSONMarshalError(w, method, "document", err)
return
@ -452,6 +453,8 @@ func StartDocumentFromSavedTemplate(w http.ResponseWriter, r *http.Request) {
}
}
p.RecordEvent(entity.EventTypeTemplateUse)
log.IfErr(tx.Commit())
newDocument, err := p.GetDocument(documentID)

View file

@ -163,6 +163,16 @@ func AddUser(w http.ResponseWriter, r *http.Request) {
}
}
if addUser {
event.Handler().Publish(string(event.TypeAddUser))
p.RecordEvent(entity.EventTypeUserAdd)
}
if addAccount {
event.Handler().Publish(string(event.TypeAddAccount))
p.RecordEvent(entity.EventTypeAccountAdd)
}
log.IfErr(tx.Commit())
// If we did not add user or give them access (account) then we error back
@ -175,14 +185,6 @@ func AddUser(w http.ResponseWriter, r *http.Request) {
inviter, err := p.GetUser(p.Context.UserID)
log.IfErr(err)
if addUser {
event.Handler().Publish(string(event.TypeAddUser))
}
if addAccount {
event.Handler().Publish(string(event.TypeAddAccount))
}
// Prepare invitation email (that contains SSO link)
if addUser && addAccount {
size := len(requestedPassword)
@ -393,6 +395,8 @@ func DeleteUser(w http.ResponseWriter, r *http.Request) {
err = p.ChangeLabelOwner(userID, p.Context.UserID)
log.IfErr(err)
p.RecordEvent(entity.EventTypeUserDelete)
log.IfErr(tx.Commit())
event.Handler().Publish(string(event.TypeRemoveUser))
@ -485,6 +489,8 @@ func UpdateUser(w http.ResponseWriter, r *http.Request) {
return
}
p.RecordEvent(entity.EventTypeUserUpdate)
log.IfErr(tx.Commit())
json, err := json.Marshal(user)
@ -701,6 +707,8 @@ func ResetUserPassword(w http.ResponseWriter, r *http.Request) {
return
}
p.RecordEvent(entity.EventTypeUserPasswordReset)
log.IfErr(tx.Commit())
_, err = w.Write([]byte("{}"))

View file

@ -508,3 +508,57 @@ const (
// ActivityTypeFeedback records user providing document feedback
ActivityTypeFeedback ActivityType = 10
)
// AppEvent represents an event initiated by a user.
type AppEvent struct {
ID uint64 `json:"-"`
OrgID string `json:"orgId"`
UserID string `json:"userId"`
Type string `json:"eventType"`
Created time.Time `json:"created"`
}
// EventType defines valid event entry types
type EventType string
const (
EventTypeDocumentAdd EventType = "added-document"
EventTypeDocumentUpload EventType = "uploaded-document"
EventTypeDocumentView EventType = "viewed-document"
EventTypeDocumentUpdate EventType = "updated-document"
EventTypeDocumentDelete EventType = "removed-document"
EventTypeDocumentRevisions EventType = "viewed-document-revisions"
EventTypeSpaceAdd EventType = "added-space"
EventTypeSpaceView EventType = "viewed-space"
EventTypeSpaceUpdate EventType = "updated-space"
EventTypeSpaceDelete EventType = "removed-space"
EventTypeSpacePermission EventType = "changed-space-permissions"
EventTypeSpaceJoin EventType = "joined-space"
EventTypeSpaceInvite EventType = "invited-space"
EventTypeSectionAdd EventType = "added-document-section"
EventTypeSectionUpdate EventType = "updated-document-section"
EventTypeSectionDelete EventType = "removed-document-section"
EventTypeSectionRollback EventType = "rolled-back-document-section"
EventTypeSectionResequence EventType = "resequenced-document-section"
EventTypeSectionCopy EventType = "copied-document-section"
EventTypeAttachmentAdd EventType = "added-attachment"
EventTypeAttachmentDownload EventType = "downloaded-attachment"
EventTypeAttachmentDelete EventType = "removed-attachment"
EventTypePinAdd EventType = "added-pin"
EventTypePinDelete EventType = "removed-pin"
EventTypePinResequence EventType = "resequenced-pin"
EventTypeBlockAdd EventType = "added-reusable-block"
EventTypeBlockUpdate EventType = "updated-reusable-block"
EventTypeBlockDelete EventType = "removed-reusable-block"
EventTypeTemplateAdd EventType = "added-document-template"
EventTypeTemplateUse EventType = "used-document-template"
EventTypeUserAdd EventType = "added-user"
EventTypeUserUpdate EventType = "updated-user"
EventTypeUserDelete EventType = "removed-user"
EventTypeUserPasswordReset EventType = "reset-user-password"
EventTypeAccountAdd EventType = "added-account"
EventTypeSystemLicense EventType = "changed-license"
EventTypeSystemAuth EventType = "changed-auth-config"
EventTypeSessionStart EventType = "started-session"
EventTypeSearch EventType = "searched"
)

58
core/api/request/event.go Normal file
View file

@ -0,0 +1,58 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
package request
import (
"time"
"github.com/documize/community/core/api/entity"
"github.com/documize/community/core/log"
)
// RecordEvent adds event entry for specified user.
func (p *Persister) RecordEvent(t entity.EventType) {
e := entity.AppEvent{}
e.OrgID = p.Context.OrgID
e.UserID = p.Context.UserID
e.Created = time.Now().UTC()
e.Type = string(t)
if e.OrgID == "" || e.UserID == "" {
log.Info("Missing OrgID/UserID for event record " + e.Type)
return
}
tx, err := Db.Beginx()
if err != nil {
log.Error("Unable to prepare insert RecordEvent", err)
return
}
stmt, err := tx.Preparex("INSERT INTO userevent (orgid, userid, eventtype, created) VALUES (?, ?, ?, ?)")
if err != nil {
tx.Rollback()
log.Error("Unable to prepare insert RecordEvent", err)
return
}
_, err = stmt.Exec(e.OrgID, e.UserID, e.Type, e.Created)
if err != nil {
log.Error("Unable to execute insert RecordEvent", err)
tx.Rollback()
return
}
stmt.Close()
tx.Commit()
return
}