mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-27 15:32:15 -05:00
179 lines
4.9 KiB
Go
179 lines
4.9 KiB
Go
package svc
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/cs3org/reva/v2/pkg/events"
|
|
"github.com/owncloud/ocis/v2/ocis-pkg/log"
|
|
"github.com/owncloud/ocis/v2/services/audit/pkg/config"
|
|
"github.com/owncloud/ocis/v2/services/audit/pkg/types"
|
|
)
|
|
|
|
// Log is used to log to different outputs
|
|
type Log func([]byte)
|
|
|
|
// Marshaller is used to marshal events
|
|
type Marshaller func(interface{}) ([]byte, error)
|
|
|
|
// AuditLoggerFromConfig will start a new AuditLogger generated from the config
|
|
func AuditLoggerFromConfig(ctx context.Context, cfg config.Auditlog, ch <-chan events.Event, log log.Logger) {
|
|
var logs []Log
|
|
|
|
if cfg.LogToConsole {
|
|
logs = append(logs, WriteToStdout())
|
|
}
|
|
|
|
if cfg.LogToFile {
|
|
logs = append(logs, WriteToFile(cfg.FilePath, log))
|
|
}
|
|
|
|
StartAuditLogger(ctx, ch, log, Marshal(cfg.Format, log), logs...)
|
|
|
|
}
|
|
|
|
// StartAuditLogger will block. run in separate go routine
|
|
//
|
|
//nolint:gocyclo
|
|
func StartAuditLogger(ctx context.Context, ch <-chan events.Event, log log.Logger, marshaller Marshaller, logto ...Log) {
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
case i := <-ch:
|
|
var auditEvent interface{}
|
|
switch ev := i.Event.(type) {
|
|
case events.ShareCreated:
|
|
auditEvent = types.ShareCreated(ev)
|
|
case events.LinkCreated:
|
|
auditEvent = types.LinkCreated(ev)
|
|
case events.ShareUpdated:
|
|
auditEvent = types.ShareUpdated(ev)
|
|
case events.LinkUpdated:
|
|
auditEvent = types.LinkUpdated(ev)
|
|
case events.ShareRemoved:
|
|
auditEvent = types.ShareRemoved(ev)
|
|
case events.LinkRemoved:
|
|
auditEvent = types.LinkRemoved(ev)
|
|
case events.ReceivedShareUpdated:
|
|
auditEvent = types.ReceivedShareUpdated(ev)
|
|
case events.LinkAccessed:
|
|
auditEvent = types.LinkAccessed(ev)
|
|
case events.LinkAccessFailed:
|
|
auditEvent = types.LinkAccessFailed(ev)
|
|
case events.ContainerCreated:
|
|
auditEvent = types.ContainerCreated(ev)
|
|
case events.FileUploaded:
|
|
auditEvent = types.FileUploaded(ev)
|
|
case events.FileDownloaded:
|
|
auditEvent = types.FileDownloaded(ev)
|
|
case events.ItemMoved:
|
|
auditEvent = types.ItemMoved(ev)
|
|
case events.ItemTrashed:
|
|
auditEvent = types.ItemTrashed(ev)
|
|
case events.ItemPurged:
|
|
auditEvent = types.ItemPurged(ev)
|
|
case events.ItemRestored:
|
|
auditEvent = types.ItemRestored(ev)
|
|
case events.FileVersionRestored:
|
|
auditEvent = types.FileVersionRestored(ev)
|
|
case events.SpaceCreated:
|
|
auditEvent = types.SpaceCreated(ev)
|
|
case events.SpaceRenamed:
|
|
auditEvent = types.SpaceRenamed(ev)
|
|
case events.SpaceDisabled:
|
|
auditEvent = types.SpaceDisabled(ev)
|
|
case events.SpaceEnabled:
|
|
auditEvent = types.SpaceEnabled(ev)
|
|
case events.SpaceDeleted:
|
|
auditEvent = types.SpaceDeleted(ev)
|
|
case events.SpaceShared:
|
|
auditEvent = types.SpaceShared(ev)
|
|
case events.SpaceUnshared:
|
|
auditEvent = types.SpaceUnshared(ev)
|
|
case events.SpaceUpdated:
|
|
auditEvent = types.SpaceUpdated(ev)
|
|
case events.UserCreated:
|
|
auditEvent = types.UserCreated(ev)
|
|
case events.UserDeleted:
|
|
auditEvent = types.UserDeleted(ev)
|
|
case events.UserFeatureChanged:
|
|
auditEvent = types.UserFeatureChanged(ev)
|
|
case events.GroupCreated:
|
|
auditEvent = types.GroupCreated(ev)
|
|
case events.GroupDeleted:
|
|
auditEvent = types.GroupDeleted(ev)
|
|
case events.GroupMemberAdded:
|
|
auditEvent = types.GroupMemberAdded(ev)
|
|
case events.GroupMemberRemoved:
|
|
auditEvent = types.GroupMemberRemoved(ev)
|
|
default:
|
|
log.Error().Interface("event", ev).Msg(fmt.Sprintf("can't handle event of type '%T'", ev))
|
|
continue
|
|
|
|
}
|
|
|
|
b, err := marshaller(auditEvent)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("error marshaling the event")
|
|
continue
|
|
}
|
|
|
|
for _, l := range logto {
|
|
l(b)
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// WriteToFile returns a Log function writing to a file
|
|
func WriteToFile(path string, log log.Logger) Log {
|
|
return func(content []byte) {
|
|
file, err := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
|
|
if err != nil {
|
|
log.Error().Err(err).Msgf("error opening file '%s'", path)
|
|
return
|
|
}
|
|
defer file.Close()
|
|
if _, err := fmt.Fprintln(file, string(content)); err != nil {
|
|
log.Error().Err(err).Msgf("error writing to file '%s'", path)
|
|
}
|
|
}
|
|
}
|
|
|
|
// WriteToStdout return a Log function writing to Stdout
|
|
func WriteToStdout() Log {
|
|
return func(content []byte) {
|
|
fmt.Println(string(content))
|
|
}
|
|
}
|
|
|
|
// Marshal returns a Marshaller from the `format` string
|
|
func Marshal(format string, log log.Logger) Marshaller {
|
|
switch format {
|
|
default:
|
|
log.Error().Msgf("unknown format '%s'", format)
|
|
return nil
|
|
case "json":
|
|
return json.Marshal
|
|
case "minimal":
|
|
return func(ev interface{}) ([]byte, error) {
|
|
b, err := json.Marshal(ev)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
m := make(map[string]interface{})
|
|
if err := json.Unmarshal(b, &m); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
format := fmt.Sprintf("%s)\n %s", m["Action"], m["Message"])
|
|
return []byte(format), nil
|
|
}
|
|
}
|
|
}
|