Files
opencloud/services/audit/pkg/service/service.go
Jörn Friedrich Dreyer 9b00f02383 bump reva to ec27f5f8feb3
Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
2023-02-15 15:26:07 +00:00

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
}
}
}