rename folder extensions -> services
Signed-off-by: Christian Richter <crichter@owncloud.com>
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
SHELL := bash
|
||||
NAME := audit
|
||||
|
||||
include ../../.make/recursion.mk
|
||||
|
||||
############ tooling ############
|
||||
ifneq (, $(shell command -v go 2> /dev/null)) # suppress `command not found warnings` for non go targets in CI
|
||||
include ../../.bingo/Variables.mk
|
||||
endif
|
||||
|
||||
############ go tooling ############
|
||||
include ../../.make/go.mk
|
||||
|
||||
############ release ############
|
||||
include ../../.make/release.mk
|
||||
|
||||
############ docs generate ############
|
||||
include ../../.make/docs.mk
|
||||
|
||||
.PHONY: docs-generate
|
||||
docs-generate: config-docs-generate
|
||||
|
||||
############ generate ############
|
||||
include ../../.make/generate.mk
|
||||
|
||||
.PHONY: ci-go-generate
|
||||
ci-go-generate: # CI runs ci-node-generate automatically before this target
|
||||
|
||||
.PHONY: ci-node-generate
|
||||
ci-node-generate:
|
||||
|
||||
############ licenses ############
|
||||
.PHONY: ci-node-check-licenses
|
||||
ci-node-check-licenses:
|
||||
|
||||
.PHONY: ci-node-save-licenses
|
||||
ci-node-save-licenses:
|
||||
@@ -0,0 +1,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/owncloud/ocis/v2/extensions/audit/pkg/command"
|
||||
"github.com/owncloud/ocis/v2/extensions/audit/pkg/config/defaults"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := command.Execute(defaults.DefaultConfig()); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"github.com/owncloud/ocis/v2/extensions/audit/pkg/config"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// Health is the entrypoint for the health command.
|
||||
func Health(cfg *config.Config) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "health",
|
||||
Usage: "Check health status",
|
||||
Action: func(c *cli.Context) error {
|
||||
// Not implemented
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
|
||||
"github.com/owncloud/ocis/v2/extensions/audit/pkg/config"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/clihelper"
|
||||
ociscfg "github.com/owncloud/ocis/v2/ocis-pkg/config"
|
||||
"github.com/thejerf/suture/v4"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// GetCommands provides all commands for this service
|
||||
func GetCommands(cfg *config.Config) cli.Commands {
|
||||
return []*cli.Command{
|
||||
// start this service
|
||||
Server(cfg),
|
||||
|
||||
// interaction with this service
|
||||
|
||||
// infos about this service
|
||||
Health(cfg),
|
||||
Version(cfg),
|
||||
}
|
||||
}
|
||||
|
||||
// Execute is the entry point for the audit command.
|
||||
func Execute(cfg *config.Config) error {
|
||||
app := clihelper.DefaultApp(&cli.App{
|
||||
Name: "audit",
|
||||
Usage: "starts audit service",
|
||||
Commands: GetCommands(cfg),
|
||||
})
|
||||
|
||||
cli.HelpFlag = &cli.BoolFlag{
|
||||
Name: "help,h",
|
||||
Usage: "Show the help",
|
||||
}
|
||||
|
||||
return app.Run(os.Args)
|
||||
}
|
||||
|
||||
// SutureService allows for the audit command to be embedded and supervised by a suture supervisor tree.
|
||||
type SutureService struct {
|
||||
cfg *config.Config
|
||||
}
|
||||
|
||||
// NewSutureService creates a new audit.SutureService
|
||||
func NewSutureService(cfg *ociscfg.Config) suture.Service {
|
||||
cfg.Audit.Commons = cfg.Commons
|
||||
return SutureService{
|
||||
cfg: cfg.Audit,
|
||||
}
|
||||
}
|
||||
|
||||
func (s SutureService) Serve(ctx context.Context) error {
|
||||
s.cfg.Context = ctx
|
||||
if err := Execute(s.cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/cs3org/reva/v2/pkg/events"
|
||||
"github.com/cs3org/reva/v2/pkg/events/server"
|
||||
"github.com/go-micro/plugins/v4/events/natsjs"
|
||||
"github.com/owncloud/ocis/v2/extensions/audit/pkg/config"
|
||||
"github.com/owncloud/ocis/v2/extensions/audit/pkg/config/parser"
|
||||
"github.com/owncloud/ocis/v2/extensions/audit/pkg/logging"
|
||||
svc "github.com/owncloud/ocis/v2/extensions/audit/pkg/service"
|
||||
"github.com/owncloud/ocis/v2/extensions/audit/pkg/types"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// Server is the entrypoint for the server command.
|
||||
func Server(cfg *config.Config) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "server",
|
||||
Usage: fmt.Sprintf("start %s extension without runtime (unsupervised mode)", cfg.Service.Name),
|
||||
Category: "server",
|
||||
Before: func(c *cli.Context) error {
|
||||
err := parser.ParseConfig(cfg)
|
||||
if err != nil {
|
||||
fmt.Printf("%v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
return err
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
logger := logging.Configure(cfg.Service.Name, cfg.Log)
|
||||
|
||||
ctx := cfg.Context
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
evtsCfg := cfg.Events
|
||||
client, err := server.NewNatsStream(
|
||||
natsjs.Address(evtsCfg.Endpoint),
|
||||
natsjs.ClusterID(evtsCfg.Cluster),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
evts, err := events.Consume(client, evtsCfg.ConsumerGroup, types.RegisteredEvents()...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
svc.AuditLoggerFromConfig(ctx, cfg.Auditlog, evts, logger)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"github.com/owncloud/ocis/v2/extensions/audit/pkg/config"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// Version prints the service versions of all running instances.
|
||||
func Version(cfg *config.Config) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "version",
|
||||
Usage: "print the version of this binary and the running extension instances",
|
||||
Category: "info",
|
||||
Action: func(c *cli.Context) error {
|
||||
// not implemented
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/shared"
|
||||
)
|
||||
|
||||
// Config combines all available configuration parts.
|
||||
type Config struct {
|
||||
Commons *shared.Commons `yaml:"-"` // don't use this directly as configuration for a service
|
||||
|
||||
Service Service `yaml:"-"`
|
||||
|
||||
Log *Log `yaml:"log"`
|
||||
Debug Debug `yaml:"debug"`
|
||||
|
||||
Events Events `yaml:"events"`
|
||||
Auditlog Auditlog `yaml:"auditlog"`
|
||||
|
||||
Context context.Context `yaml:"-"`
|
||||
}
|
||||
|
||||
// Events combines the configuration options for the event bus.
|
||||
type Events struct {
|
||||
Endpoint string `yaml:"endpoint" env:"AUDIT_EVENTS_ENDPOINT" desc:"The address of the streaming service."`
|
||||
Cluster string `yaml:"cluster" env:"AUDIT_EVENTS_CLUSTER" desc:"The clusterID of the streaming service. Mandatory when using nats."`
|
||||
ConsumerGroup string `yaml:"group" env:"AUDIT_EVENTS_GROUP" desc:"The consumergroup of the service. One group will only get one copy of an event."`
|
||||
}
|
||||
|
||||
// Auditlog holds audit log information
|
||||
type Auditlog struct {
|
||||
LogToConsole bool `yaml:"log_to_console" env:"AUDIT_LOG_TO_CONSOLE" desc:"Logs to Stdout if true. Independent of the log to file option."`
|
||||
LogToFile bool `yaml:"log_to_file" env:"AUDIT_LOG_TO_FILE" desc:"Logs to file if true. Independent of the log to Stdout file option."`
|
||||
FilePath string `yaml:"filepath" env:"AUDIT_FILEPATH" desc:"Filepath to the logfile. Mandatory if LogToFile is true."`
|
||||
Format string `yaml:"format" env:"AUDIT_FORMAT" desc:"Log format. using json is advised."`
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package config
|
||||
|
||||
// Debug defines the available debug configuration.
|
||||
type Debug struct {
|
||||
Addr string `yaml:"addr" env:"AUDIT_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
|
||||
Token string `yaml:"token" env:"AUDIT_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
|
||||
Pprof bool `yaml:"pprof" env:"AUDIT_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
|
||||
Zpages bool `yaml:"zpages" env:"AUDIT_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package defaults
|
||||
|
||||
import (
|
||||
"github.com/owncloud/ocis/v2/extensions/audit/pkg/config"
|
||||
)
|
||||
|
||||
func FullDefaultConfig() *config.Config {
|
||||
cfg := DefaultConfig()
|
||||
EnsureDefaults(cfg)
|
||||
Sanitize(cfg)
|
||||
return cfg
|
||||
}
|
||||
|
||||
func DefaultConfig() *config.Config {
|
||||
return &config.Config{
|
||||
Debug: config.Debug{
|
||||
Addr: "127.0.0.1:9234",
|
||||
},
|
||||
Service: config.Service{
|
||||
Name: "audit",
|
||||
},
|
||||
Events: config.Events{
|
||||
Endpoint: "127.0.0.1:9233",
|
||||
Cluster: "ocis-cluster",
|
||||
ConsumerGroup: "audit",
|
||||
},
|
||||
Auditlog: config.Auditlog{
|
||||
LogToConsole: true,
|
||||
Format: "json",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func EnsureDefaults(cfg *config.Config) {
|
||||
// provide with defaults for shared logging, since we need a valid destination address for BindEnv.
|
||||
if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
|
||||
cfg.Log = &config.Log{
|
||||
Level: cfg.Commons.Log.Level,
|
||||
Pretty: cfg.Commons.Log.Pretty,
|
||||
Color: cfg.Commons.Log.Color,
|
||||
File: cfg.Commons.Log.File,
|
||||
}
|
||||
} else if cfg.Log == nil {
|
||||
cfg.Log = &config.Log{}
|
||||
}
|
||||
}
|
||||
|
||||
func Sanitize(cfg *config.Config) {
|
||||
// sanitize config
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package config
|
||||
|
||||
// Log defines the available log configuration.
|
||||
type Log struct {
|
||||
Level string `yaml:"level" env:"OCIS_LOG_LEVEL;AUDIT_LOG_LEVEL" desc:"The log level. Valid values are: \"panic\", \"fatal\", \"error\", \"warn\", \"info\", \"debug\", \"trace\"."`
|
||||
Pretty bool `yaml:"pretty" env:"OCIS_LOG_PRETTY;AUDIT_LOG_PRETTY" desc:"Activates pretty log output."`
|
||||
Color bool `yaml:"color" env:"OCIS_LOG_COLOR;AUDIT_LOG_COLOR" desc:"Activates colorized log output."`
|
||||
File string `yaml:"file" env:"OCIS_LOG_FILE;AUDIT_LOG_FILE" desc:"The path to the log file. Activates logging to this file if set."`
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/owncloud/ocis/v2/extensions/audit/pkg/config"
|
||||
"github.com/owncloud/ocis/v2/extensions/audit/pkg/config/defaults"
|
||||
ociscfg "github.com/owncloud/ocis/v2/ocis-pkg/config"
|
||||
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/config/envdecode"
|
||||
)
|
||||
|
||||
// ParseConfig loads configuration from known paths.
|
||||
func ParseConfig(cfg *config.Config) error {
|
||||
_, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defaults.EnsureDefaults(cfg)
|
||||
|
||||
// load all env variables relevant to the config in the current context.
|
||||
if err := envdecode.Decode(cfg); err != nil {
|
||||
// no environment variable set for this config is an expected "error"
|
||||
if !errors.Is(err, envdecode.ErrNoTargetFieldsAreSet) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
defaults.Sanitize(cfg)
|
||||
|
||||
return Validate(cfg)
|
||||
}
|
||||
|
||||
func Validate(cfg *config.Config) error {
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package config
|
||||
|
||||
// Service defines the available service configuration.
|
||||
type Service struct {
|
||||
Name string `yaml:"-"`
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package logging
|
||||
|
||||
import (
|
||||
"github.com/owncloud/ocis/v2/extensions/audit/pkg/config"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/log"
|
||||
)
|
||||
|
||||
// LoggerFromConfig initializes a service-specific logger instance.
|
||||
func Configure(name string, cfg *config.Log) log.Logger {
|
||||
return log.NewLogger(
|
||||
log.Name(name),
|
||||
log.Level(cfg.Level),
|
||||
log.Pretty(cfg.Pretty),
|
||||
log.Color(cfg.Color),
|
||||
log.File(cfg.File),
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
package svc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/cs3org/reva/v2/pkg/events"
|
||||
"github.com/owncloud/ocis/v2/extensions/audit/pkg/config"
|
||||
"github.com/owncloud/ocis/v2/extensions/audit/pkg/types"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/log"
|
||||
)
|
||||
|
||||
// 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 interface{}, 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 seperate go routine
|
||||
func StartAuditLogger(ctx context.Context, ch <-chan interface{}, log log.Logger, marshaller Marshaller, logto ...Log) {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case i := <-ch:
|
||||
var auditEvent interface{}
|
||||
switch ev := i.(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.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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,649 @@
|
||||
package svc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/cs3org/reva/v2/pkg/events"
|
||||
"github.com/owncloud/ocis/v2/extensions/audit/pkg/types"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/log"
|
||||
"github.com/test-go/testify/require"
|
||||
|
||||
group "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
|
||||
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
|
||||
link "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1"
|
||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
rtypes "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||
)
|
||||
|
||||
var testCases = []struct {
|
||||
Alias string
|
||||
SystemEvent interface{}
|
||||
CheckAuditEvent func(*testing.T, []byte)
|
||||
}{
|
||||
{
|
||||
Alias: "ShareCreated - user",
|
||||
SystemEvent: events.ShareCreated{
|
||||
Sharer: userID("sharing-userid"),
|
||||
GranteeUserID: userID("beshared-userid"),
|
||||
GranteeGroupID: nil,
|
||||
ItemID: resourceID("storage-1", "itemid-1"),
|
||||
CTime: timestamp(0),
|
||||
},
|
||||
CheckAuditEvent: func(t *testing.T, b []byte) {
|
||||
ev := types.AuditEventShareCreated{}
|
||||
require.NoError(t, json.Unmarshal(b, &ev))
|
||||
|
||||
// AuditEvent fields
|
||||
checkBaseAuditEvent(t, ev.AuditEvent, "sharing-userid", "1970-01-01T00:00:00Z", "user 'sharing-userid' shared file 'itemid-1' with 'beshared-userid'", "file_shared")
|
||||
// AuditEventSharing fields
|
||||
checkSharingAuditEvent(t, ev.AuditEventSharing, "itemid-1", "sharing-userid", "")
|
||||
// AuditEventShareCreated fields
|
||||
require.Equal(t, "", ev.ItemType)
|
||||
require.Equal(t, "", ev.ExpirationDate)
|
||||
require.Equal(t, false, ev.SharePass)
|
||||
//require.Equal(t, "stat:true ", ev.Permissions) // TODO: BUG! Should work
|
||||
require.Equal(t, "user", ev.ShareType)
|
||||
require.Equal(t, "beshared-userid", ev.ShareWith)
|
||||
require.Equal(t, "sharing-userid", ev.ShareOwner)
|
||||
require.Equal(t, "", ev.ShareToken)
|
||||
},
|
||||
}, {
|
||||
Alias: "ShareCreated - group",
|
||||
SystemEvent: events.ShareCreated{
|
||||
Sharer: userID("sharing-userid"),
|
||||
GranteeUserID: nil,
|
||||
GranteeGroupID: groupID("beshared-groupid"),
|
||||
ItemID: resourceID("storage-1", "itemid-1"),
|
||||
CTime: timestamp(10e8),
|
||||
},
|
||||
CheckAuditEvent: func(t *testing.T, b []byte) {
|
||||
ev := types.AuditEventShareCreated{}
|
||||
require.NoError(t, json.Unmarshal(b, &ev))
|
||||
|
||||
// AuditEvent fields
|
||||
checkBaseAuditEvent(t, ev.AuditEvent, "sharing-userid", "2001-09-09T01:46:40Z", "user 'sharing-userid' shared file 'itemid-1' with 'beshared-groupid'", "file_shared")
|
||||
// AuditEventSharing fields
|
||||
checkSharingAuditEvent(t, ev.AuditEventSharing, "itemid-1", "sharing-userid", "")
|
||||
// AuditEventShareCreated fields
|
||||
require.Equal(t, "", ev.ItemType)
|
||||
require.Equal(t, "", ev.ExpirationDate)
|
||||
require.Equal(t, false, ev.SharePass)
|
||||
//require.Equal(t, "stat:true ", ev.Permissions) // TODO: BUG! Should work
|
||||
require.Equal(t, "group", ev.ShareType)
|
||||
require.Equal(t, "beshared-groupid", ev.ShareWith)
|
||||
require.Equal(t, "sharing-userid", ev.ShareOwner)
|
||||
require.Equal(t, "", ev.ShareToken)
|
||||
|
||||
},
|
||||
}, {
|
||||
Alias: "ShareUpdated",
|
||||
SystemEvent: events.ShareUpdated{
|
||||
ShareID: shareID("shareid"),
|
||||
Sharer: userID("sharing-userid"),
|
||||
GranteeUserID: nil,
|
||||
GranteeGroupID: groupID("beshared-groupid"),
|
||||
ItemID: resourceID("storage-1", "itemid-1"),
|
||||
Permissions: sharePermissions("stat", "get_quota"),
|
||||
MTime: timestamp(10e8),
|
||||
Updated: "permissions",
|
||||
},
|
||||
CheckAuditEvent: func(t *testing.T, b []byte) {
|
||||
ev := types.AuditEventShareUpdated{}
|
||||
require.NoError(t, json.Unmarshal(b, &ev))
|
||||
|
||||
// AuditEvent fields
|
||||
checkBaseAuditEvent(t, ev.AuditEvent, "sharing-userid", "2001-09-09T01:46:40Z", "user 'sharing-userid' updated field 'permissions' of share 'shareid'", "share_permission_updated")
|
||||
// AuditEventSharing fields
|
||||
checkSharingAuditEvent(t, ev.AuditEventSharing, "itemid-1", "sharing-userid", "shareid")
|
||||
// AuditEventShareUpdated fields
|
||||
require.Equal(t, "", ev.ItemType) // not implemented atm
|
||||
require.Equal(t, "", ev.ExpirationDate) // no expiration for shares
|
||||
require.Equal(t, false, ev.SharePass)
|
||||
require.Equal(t, "get_quota:true stat:true ", ev.Permissions)
|
||||
require.Equal(t, "group", ev.ShareType)
|
||||
require.Equal(t, "beshared-groupid", ev.ShareWith)
|
||||
require.Equal(t, "sharing-userid", ev.ShareOwner)
|
||||
require.Equal(t, "", ev.ShareToken) // token not filled for shares
|
||||
},
|
||||
}, {
|
||||
Alias: "LinkUpdated - permissions",
|
||||
SystemEvent: events.LinkUpdated{
|
||||
ShareID: linkID("shareid"),
|
||||
Sharer: userID("sharing-userid"),
|
||||
ItemID: resourceID("storage-1", "itemid-1"),
|
||||
Permissions: linkPermissions("stat"),
|
||||
CTime: timestamp(10e8),
|
||||
DisplayName: "link",
|
||||
Expiration: timestamp(10e8 + 10e5),
|
||||
PasswordProtected: true,
|
||||
Token: "token-123",
|
||||
FieldUpdated: "permissions",
|
||||
},
|
||||
CheckAuditEvent: func(t *testing.T, b []byte) {
|
||||
ev := types.AuditEventShareUpdated{}
|
||||
require.NoError(t, json.Unmarshal(b, &ev))
|
||||
|
||||
// AuditEvent fields
|
||||
checkBaseAuditEvent(t, ev.AuditEvent, "sharing-userid", "2001-09-09T01:46:40Z", "user 'sharing-userid' updated field 'permissions' of public link 'shareid'", "share_permission_updated")
|
||||
// AuditEventSharing fields
|
||||
checkSharingAuditEvent(t, ev.AuditEventSharing, "itemid-1", "sharing-userid", "shareid")
|
||||
// AuditEventShareUpdated fields
|
||||
require.Equal(t, "", ev.ItemType) // not implemented atm
|
||||
require.Equal(t, "2001-09-20T15:33:20Z", ev.ExpirationDate)
|
||||
require.Equal(t, true, ev.SharePass)
|
||||
require.Equal(t, "stat:true ", ev.Permissions)
|
||||
require.Equal(t, "link", ev.ShareType)
|
||||
require.Equal(t, "", ev.ShareWith) // not filled on links
|
||||
require.Equal(t, "sharing-userid", ev.ShareOwner)
|
||||
require.Equal(t, "token-123", ev.ShareToken)
|
||||
},
|
||||
}, {
|
||||
Alias: "ShareRemoved",
|
||||
SystemEvent: events.ShareRemoved{
|
||||
ShareID: shareID("shareid"),
|
||||
ShareKey: nil,
|
||||
},
|
||||
CheckAuditEvent: func(t *testing.T, b []byte) {
|
||||
ev := types.AuditEventShareRemoved{}
|
||||
require.NoError(t, json.Unmarshal(b, &ev))
|
||||
|
||||
// AuditEvent fields
|
||||
checkBaseAuditEvent(t, ev.AuditEvent, "", "", "share id:'shareid' uid:'' item-id:'' was removed", "file_unshared")
|
||||
// AuditEventSharing fields
|
||||
checkSharingAuditEvent(t, ev.AuditEventSharing, "", "", "shareid")
|
||||
// AuditEventShareUpdated fields
|
||||
require.Equal(t, "", ev.ItemType) // not implemented atm
|
||||
require.Equal(t, "", ev.ShareType)
|
||||
require.Equal(t, "", ev.ShareWith) // not filled on links
|
||||
},
|
||||
}, {
|
||||
Alias: "LinkRemoved - id",
|
||||
SystemEvent: events.LinkRemoved{
|
||||
Executant: userID("sharing-userid"),
|
||||
ShareID: linkID("shareid"),
|
||||
ShareToken: "",
|
||||
},
|
||||
CheckAuditEvent: func(t *testing.T, b []byte) {
|
||||
ev := types.AuditEventShareRemoved{}
|
||||
require.NoError(t, json.Unmarshal(b, &ev))
|
||||
|
||||
// AuditEvent fields
|
||||
checkBaseAuditEvent(t, ev.AuditEvent, "sharing-userid", "", "user 'sharing-userid' removed public link with id:'shareid'", "file_unshared")
|
||||
// AuditEventSharing fields
|
||||
checkSharingAuditEvent(t, ev.AuditEventSharing, "", "sharing-userid", "shareid")
|
||||
// AuditEventShareUpdated fields
|
||||
require.Equal(t, "", ev.ItemType) // not implemented atm
|
||||
require.Equal(t, "link", ev.ShareType)
|
||||
require.Equal(t, "", ev.ShareWith) // not filled on links
|
||||
},
|
||||
}, {
|
||||
Alias: "LinkRemoved - token",
|
||||
SystemEvent: events.LinkRemoved{
|
||||
Executant: userID("sharing-userid"),
|
||||
ShareID: nil,
|
||||
ShareToken: "token-123",
|
||||
},
|
||||
CheckAuditEvent: func(t *testing.T, b []byte) {
|
||||
ev := types.AuditEventShareRemoved{}
|
||||
require.NoError(t, json.Unmarshal(b, &ev))
|
||||
|
||||
// AuditEvent fields
|
||||
checkBaseAuditEvent(t, ev.AuditEvent, "sharing-userid", "", "user 'sharing-userid' removed public link with id:'token-123'", "file_unshared")
|
||||
// AuditEventSharing fields
|
||||
checkSharingAuditEvent(t, ev.AuditEventSharing, "", "sharing-userid", "token-123")
|
||||
// AuditEventShareUpdated fields
|
||||
require.Equal(t, "", ev.ItemType) // not implemented atm
|
||||
require.Equal(t, "link", ev.ShareType)
|
||||
require.Equal(t, "", ev.ShareWith) // not filled on links
|
||||
},
|
||||
}, {
|
||||
Alias: "Share accepted",
|
||||
SystemEvent: events.ReceivedShareUpdated{
|
||||
ShareID: shareID("shareid"),
|
||||
ItemID: resourceID("storageid-1", "itemid-1"),
|
||||
Permissions: sharePermissions("get_quota"),
|
||||
GranteeUserID: userID("beshared-userid"),
|
||||
GranteeGroupID: nil,
|
||||
Sharer: userID("sharing-userid"),
|
||||
MTime: timestamp(10e8),
|
||||
State: "SHARE_STATE_ACCEPTED",
|
||||
},
|
||||
CheckAuditEvent: func(t *testing.T, b []byte) {
|
||||
ev := types.AuditEventReceivedShareUpdated{}
|
||||
require.NoError(t, json.Unmarshal(b, &ev))
|
||||
|
||||
// AuditEvent fields
|
||||
checkBaseAuditEvent(t, ev.AuditEvent, "beshared-userid", "2001-09-09T01:46:40Z", "user 'beshared-userid' accepted share 'shareid' from user 'sharing-userid'", "share_accepted")
|
||||
// AuditEventSharing fields
|
||||
checkSharingAuditEvent(t, ev.AuditEventSharing, "itemid-1", "sharing-userid", "shareid")
|
||||
// AuditEventShareUpdated fields
|
||||
require.Equal(t, "", ev.ItemType)
|
||||
require.Equal(t, "user", ev.ShareType)
|
||||
require.Equal(t, "beshared-userid", ev.ShareWith)
|
||||
},
|
||||
}, {
|
||||
Alias: "Share declined",
|
||||
SystemEvent: events.ReceivedShareUpdated{
|
||||
ShareID: shareID("shareid"),
|
||||
ItemID: resourceID("storageid-1", "itemid-1"),
|
||||
Permissions: sharePermissions("get_quota"),
|
||||
GranteeUserID: userID("beshared-userid"),
|
||||
GranteeGroupID: nil,
|
||||
Sharer: userID("sharing-userid"),
|
||||
MTime: timestamp(10e8),
|
||||
State: "SHARE_STATE_DECLINED",
|
||||
},
|
||||
CheckAuditEvent: func(t *testing.T, b []byte) {
|
||||
ev := types.AuditEventReceivedShareUpdated{}
|
||||
require.NoError(t, json.Unmarshal(b, &ev))
|
||||
|
||||
// AuditEvent fields
|
||||
checkBaseAuditEvent(t, ev.AuditEvent, "beshared-userid", "2001-09-09T01:46:40Z", "user 'beshared-userid' declined share 'shareid' from user 'sharing-userid'", "share_declined")
|
||||
// AuditEventSharing fields
|
||||
checkSharingAuditEvent(t, ev.AuditEventSharing, "itemid-1", "sharing-userid", "shareid")
|
||||
// AuditEventShareUpdated fields
|
||||
require.Equal(t, "", ev.ItemType)
|
||||
require.Equal(t, "user", ev.ShareType)
|
||||
require.Equal(t, "beshared-userid", ev.ShareWith)
|
||||
},
|
||||
}, {
|
||||
Alias: "Link accessed - success",
|
||||
SystemEvent: events.LinkAccessed{
|
||||
ShareID: linkID("shareid"),
|
||||
Sharer: userID("sharing-userid"),
|
||||
ItemID: resourceID("storage-1", "itemid-1"),
|
||||
Permissions: linkPermissions("stat"),
|
||||
DisplayName: "link",
|
||||
Expiration: timestamp(10e8 + 10e5),
|
||||
PasswordProtected: true,
|
||||
CTime: timestamp(10e8),
|
||||
Token: "token-123",
|
||||
},
|
||||
CheckAuditEvent: func(t *testing.T, b []byte) {
|
||||
ev := types.AuditEventLinkAccessed{}
|
||||
require.NoError(t, json.Unmarshal(b, &ev))
|
||||
|
||||
// AuditEvent fields
|
||||
checkBaseAuditEvent(t, ev.AuditEvent, "sharing-userid", "2001-09-09T01:46:40Z", "link 'shareid' was accessed. Success: true", "public_link_accessed")
|
||||
// AuditEventSharing fields
|
||||
checkSharingAuditEvent(t, ev.AuditEventSharing, "itemid-1", "sharing-userid", "shareid")
|
||||
// AuditEventShareUpdated fields
|
||||
require.Equal(t, "", ev.ItemType) // not implemented atm
|
||||
require.Equal(t, "token-123", ev.ShareToken)
|
||||
require.Equal(t, true, ev.Success)
|
||||
},
|
||||
}, {
|
||||
Alias: "Link accessed - failure",
|
||||
SystemEvent: events.LinkAccessFailed{
|
||||
ShareID: linkID("shareid"),
|
||||
Token: "token-123",
|
||||
Status: 8,
|
||||
Message: "access denied",
|
||||
},
|
||||
CheckAuditEvent: func(t *testing.T, b []byte) {
|
||||
ev := types.AuditEventLinkAccessed{}
|
||||
require.NoError(t, json.Unmarshal(b, &ev))
|
||||
|
||||
// AuditEvent fields
|
||||
checkBaseAuditEvent(t, ev.AuditEvent, "", "", "link 'shareid' was accessed. Success: false", "public_link_accessed")
|
||||
// AuditEventSharing fields
|
||||
checkSharingAuditEvent(t, ev.AuditEventSharing, "", "", "shareid")
|
||||
// AuditEventShareUpdated fields
|
||||
require.Equal(t, "", ev.ItemType) // not implemented atm
|
||||
require.Equal(t, "token-123", ev.ShareToken)
|
||||
require.Equal(t, false, ev.Success)
|
||||
},
|
||||
}, {
|
||||
Alias: "File created",
|
||||
SystemEvent: events.FileUploaded{
|
||||
Executant: userID("uid-123"),
|
||||
Ref: reference("sto-123", "iid-123", "./item"),
|
||||
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
|
||||
},
|
||||
CheckAuditEvent: func(t *testing.T, b []byte) {
|
||||
ev := types.AuditEventFileCreated{}
|
||||
require.NoError(t, json.Unmarshal(b, &ev))
|
||||
|
||||
// AuditEvent fields
|
||||
checkBaseAuditEvent(t, ev.AuditEvent, "uid-123", "", "user 'uid-123' created file 'sto-123!iid-123/item'", "file_create")
|
||||
// AuditEventSharing fields
|
||||
checkFilesAuditEvent(t, ev.AuditEventFiles, "sto-123!iid-123/item", "uid-123", "./item")
|
||||
},
|
||||
}, {
|
||||
Alias: "File read",
|
||||
SystemEvent: events.FileDownloaded{
|
||||
Executant: userID("uid-123"),
|
||||
Ref: reference("sto-123", "iid-123", "./item"),
|
||||
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
|
||||
},
|
||||
CheckAuditEvent: func(t *testing.T, b []byte) {
|
||||
ev := types.AuditEventFileRead{}
|
||||
require.NoError(t, json.Unmarshal(b, &ev))
|
||||
|
||||
// AuditEvent fields
|
||||
checkBaseAuditEvent(t, ev.AuditEvent, "uid-123", "", "user 'uid-123' read file 'sto-123!iid-123/item'", "file_read")
|
||||
// AuditEventSharing fields
|
||||
checkFilesAuditEvent(t, ev.AuditEventFiles, "sto-123!iid-123/item", "uid-123", "./item")
|
||||
},
|
||||
}, {
|
||||
Alias: "File trashed",
|
||||
SystemEvent: events.ItemTrashed{
|
||||
Executant: userID("uid-123"),
|
||||
Ref: reference("sto-123", "iid-123", "./item"),
|
||||
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
|
||||
},
|
||||
CheckAuditEvent: func(t *testing.T, b []byte) {
|
||||
ev := types.AuditEventFileDeleted{}
|
||||
require.NoError(t, json.Unmarshal(b, &ev))
|
||||
|
||||
// AuditEvent fields
|
||||
checkBaseAuditEvent(t, ev.AuditEvent, "uid-123", "", "user 'uid-123' trashed file 'sto-123!iid-123/item'", "file_delete")
|
||||
// AuditEventSharing fields
|
||||
checkFilesAuditEvent(t, ev.AuditEventFiles, "sto-123!iid-123/item", "uid-123", "./item")
|
||||
},
|
||||
}, {
|
||||
Alias: "File renamed",
|
||||
SystemEvent: events.ItemMoved{
|
||||
Executant: userID("uid-123"),
|
||||
Ref: reference("sto-123", "iid-123", "./item"),
|
||||
OldReference: reference("sto-123", "iid-123", "./anotheritem"),
|
||||
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
|
||||
},
|
||||
CheckAuditEvent: func(t *testing.T, b []byte) {
|
||||
ev := types.AuditEventFileRenamed{}
|
||||
require.NoError(t, json.Unmarshal(b, &ev))
|
||||
|
||||
// AuditEvent fields
|
||||
checkBaseAuditEvent(t, ev.AuditEvent, "uid-123", "", "user 'uid-123' moved file 'sto-123!iid-123/item' from './anotheritem' to './item'", "file_rename")
|
||||
// AuditEventSharing fields
|
||||
checkFilesAuditEvent(t, ev.AuditEventFiles, "sto-123!iid-123/item", "uid-123", "./item")
|
||||
// AuditEventFileRenamed fields
|
||||
require.Equal(t, "./anotheritem", ev.OldPath)
|
||||
|
||||
},
|
||||
}, {
|
||||
Alias: "File purged",
|
||||
SystemEvent: events.ItemPurged{
|
||||
Executant: userID("uid-123"),
|
||||
Ref: reference("sto-123", "iid-123", "./item"),
|
||||
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
|
||||
},
|
||||
CheckAuditEvent: func(t *testing.T, b []byte) {
|
||||
ev := types.AuditEventFilePurged{}
|
||||
require.NoError(t, json.Unmarshal(b, &ev))
|
||||
|
||||
// AuditEvent fields
|
||||
checkBaseAuditEvent(t, ev.AuditEvent, "uid-123", "", "user 'uid-123' removed file 'sto-123!iid-123/item' from trashbin", "file_trash_delete")
|
||||
// AuditEventSharing fields
|
||||
checkFilesAuditEvent(t, ev.AuditEventFiles, "sto-123!iid-123/item", "uid-123", "./item")
|
||||
},
|
||||
}, {
|
||||
Alias: "File restored",
|
||||
SystemEvent: events.ItemRestored{
|
||||
Executant: userID("uid-123"),
|
||||
Ref: reference("sto-123", "iid-123", "./item"),
|
||||
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
|
||||
OldReference: reference("sto-123", "sto-123!iid-123/item", "./oldpath"),
|
||||
Key: "",
|
||||
},
|
||||
CheckAuditEvent: func(t *testing.T, b []byte) {
|
||||
ev := types.AuditEventFileRestored{}
|
||||
require.NoError(t, json.Unmarshal(b, &ev))
|
||||
|
||||
// AuditEvent fields
|
||||
checkBaseAuditEvent(t, ev.AuditEvent, "uid-123", "", "user 'uid-123' restored file 'sto-123!iid-123/item' from trashbin to './item'", "file_trash_restore")
|
||||
// AuditEventSharing fields
|
||||
checkFilesAuditEvent(t, ev.AuditEventFiles, "sto-123!iid-123/item", "uid-123", "./item")
|
||||
// AuditEventFileRestored fields
|
||||
require.Equal(t, "./oldpath", ev.OldPath)
|
||||
|
||||
},
|
||||
}, {
|
||||
Alias: "File version restored",
|
||||
SystemEvent: events.FileVersionRestored{
|
||||
Executant: userID("uid-123"),
|
||||
Ref: reference("sto-123", "iid-123", "./item"),
|
||||
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
|
||||
Key: "v1",
|
||||
},
|
||||
CheckAuditEvent: func(t *testing.T, b []byte) {
|
||||
ev := types.AuditEventFileVersionRestored{}
|
||||
require.NoError(t, json.Unmarshal(b, &ev))
|
||||
|
||||
// AuditEvent fields
|
||||
checkBaseAuditEvent(t, ev.AuditEvent, "uid-123", "", "user 'uid-123' restored file 'sto-123!iid-123/item' in version 'v1'", "file_version_restore")
|
||||
// AuditEventSharing fields
|
||||
checkFilesAuditEvent(t, ev.AuditEventFiles, "sto-123!iid-123/item", "uid-123", "./item")
|
||||
// AuditEventFileRestored fields
|
||||
require.Equal(t, "v1", ev.Key)
|
||||
|
||||
},
|
||||
}, {
|
||||
Alias: "Space created",
|
||||
SystemEvent: events.SpaceCreated{
|
||||
Executant: userID("uid-123"),
|
||||
ID: &provider.StorageSpaceId{OpaqueId: "space-123"},
|
||||
Owner: userID("uid-123"),
|
||||
Root: resourceID("sto-123", "iid-123"),
|
||||
Name: "test-space",
|
||||
Type: "project",
|
||||
Quota: nil, // Quota not interesting atm
|
||||
MTime: timestamp(10e9),
|
||||
},
|
||||
CheckAuditEvent: func(t *testing.T, b []byte) {
|
||||
ev := types.AuditEventSpaceCreated{}
|
||||
require.NoError(t, json.Unmarshal(b, &ev))
|
||||
|
||||
// AuditEvent fields
|
||||
checkBaseAuditEvent(t, ev.AuditEvent, "", "2286-11-20T17:46:40Z", "user 'uid-123' created a space 'space-123' with name 'test-space'", "space_created")
|
||||
// AuditEventSpaces fields
|
||||
checkSpacesAuditEvent(t, ev.AuditEventSpaces, "space-123")
|
||||
// AuditEventFileRestored fields
|
||||
require.Equal(t, "uid-123", ev.Owner)
|
||||
require.Equal(t, "sto-123!iid-123", ev.RootItem)
|
||||
require.Equal(t, "test-space", ev.Name)
|
||||
require.Equal(t, "project", ev.Type)
|
||||
},
|
||||
}, {
|
||||
Alias: "Space renamed",
|
||||
SystemEvent: events.SpaceRenamed{
|
||||
Executant: userID("uid-123"),
|
||||
ID: &provider.StorageSpaceId{OpaqueId: "space-123"},
|
||||
Owner: userID("uid-123"),
|
||||
Name: "new-name",
|
||||
},
|
||||
CheckAuditEvent: func(t *testing.T, b []byte) {
|
||||
ev := types.AuditEventSpaceRenamed{}
|
||||
require.NoError(t, json.Unmarshal(b, &ev))
|
||||
|
||||
// AuditEvent fields
|
||||
checkBaseAuditEvent(t, ev.AuditEvent, "", "", "user 'uid-123' renamed space 'space-123' to 'new-name'", "space_renamed")
|
||||
// AuditEventSpaces fields
|
||||
checkSpacesAuditEvent(t, ev.AuditEventSpaces, "space-123")
|
||||
// AuditEventSpaceRenamed fields
|
||||
require.Equal(t, "new-name", ev.NewName)
|
||||
},
|
||||
}, {
|
||||
Alias: "Space disabled",
|
||||
SystemEvent: events.SpaceDisabled{
|
||||
Executant: userID("uid-123"),
|
||||
ID: &provider.StorageSpaceId{OpaqueId: "space-123"},
|
||||
},
|
||||
CheckAuditEvent: func(t *testing.T, b []byte) {
|
||||
ev := types.AuditEventSpaceDisabled{}
|
||||
require.NoError(t, json.Unmarshal(b, &ev))
|
||||
|
||||
// AuditEvent fields
|
||||
checkBaseAuditEvent(t, ev.AuditEvent, "", "", "user 'uid-123' disabled the space 'space-123'", "space_disabled")
|
||||
// AuditEventSpaces fields
|
||||
checkSpacesAuditEvent(t, ev.AuditEventSpaces, "space-123")
|
||||
},
|
||||
}, {
|
||||
Alias: "Space enabled",
|
||||
SystemEvent: events.SpaceEnabled{
|
||||
Executant: userID("uid-123"),
|
||||
ID: &provider.StorageSpaceId{OpaqueId: "space-123"},
|
||||
},
|
||||
CheckAuditEvent: func(t *testing.T, b []byte) {
|
||||
ev := types.AuditEventSpaceEnabled{}
|
||||
require.NoError(t, json.Unmarshal(b, &ev))
|
||||
|
||||
// AuditEvent fields
|
||||
checkBaseAuditEvent(t, ev.AuditEvent, "", "", "user 'uid-123' (re-) enabled the space 'space-123'", "space_enabled")
|
||||
// AuditEventSpaces fields
|
||||
checkSpacesAuditEvent(t, ev.AuditEventSpaces, "space-123")
|
||||
},
|
||||
}, {
|
||||
Alias: "Space deleted",
|
||||
SystemEvent: events.SpaceDeleted{
|
||||
Executant: userID("uid-123"),
|
||||
ID: &provider.StorageSpaceId{OpaqueId: "space-123"},
|
||||
},
|
||||
CheckAuditEvent: func(t *testing.T, b []byte) {
|
||||
ev := types.AuditEventSpaceDeleted{}
|
||||
require.NoError(t, json.Unmarshal(b, &ev))
|
||||
|
||||
// AuditEvent fields
|
||||
checkBaseAuditEvent(t, ev.AuditEvent, "", "", "user 'uid-123' deleted the space 'space-123'", "space_deleted")
|
||||
// AuditEventSpaces fields
|
||||
checkSpacesAuditEvent(t, ev.AuditEventSpaces, "space-123")
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestAuditLogging(t *testing.T) {
|
||||
log := log.NewLogger()
|
||||
|
||||
inch := make(chan interface{})
|
||||
defer close(inch)
|
||||
|
||||
outch := make(chan []byte)
|
||||
defer close(outch)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.TODO())
|
||||
defer cancel()
|
||||
|
||||
go StartAuditLogger(ctx, inch, log, Marshal("json", log), func(b []byte) {
|
||||
outch <- b
|
||||
})
|
||||
|
||||
for i := range testCases {
|
||||
tc := testCases[i]
|
||||
t.Run(tc.Alias, func(t *testing.T) {
|
||||
inch <- tc.SystemEvent
|
||||
tc.CheckAuditEvent(t, <-outch)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func checkBaseAuditEvent(t *testing.T, ev types.AuditEvent, user string, time string, message string, action string) {
|
||||
require.Equal(t, "", ev.RemoteAddr) // not implemented atm
|
||||
require.Equal(t, user, ev.User)
|
||||
require.Equal(t, "", ev.URL) // not implemented atm
|
||||
require.Equal(t, "", ev.Method) // not implemented atm
|
||||
require.Equal(t, "", ev.UserAgent) // not implemented atm
|
||||
require.Equal(t, time, ev.Time)
|
||||
require.Equal(t, "admin_audit", ev.App)
|
||||
require.Equal(t, message, ev.Message)
|
||||
require.Equal(t, action, ev.Action)
|
||||
require.Equal(t, false, ev.CLI) // not implemented atm
|
||||
require.Equal(t, 1, ev.Level)
|
||||
}
|
||||
|
||||
func checkSharingAuditEvent(t *testing.T, ev types.AuditEventSharing, itemID string, owner string, shareID string) {
|
||||
require.Equal(t, itemID, ev.FileID)
|
||||
require.Equal(t, owner, ev.Owner)
|
||||
require.Equal(t, "", ev.Path) // not implemented atm
|
||||
require.Equal(t, shareID, ev.ShareID)
|
||||
}
|
||||
|
||||
func checkFilesAuditEvent(t *testing.T, ev types.AuditEventFiles, itemID string, owner string, path string) {
|
||||
require.Equal(t, itemID, ev.FileID)
|
||||
require.Equal(t, owner, ev.Owner)
|
||||
require.Equal(t, path, ev.Path)
|
||||
}
|
||||
|
||||
func checkSpacesAuditEvent(t *testing.T, ev types.AuditEventSpaces, spaceID string) {
|
||||
require.Equal(t, spaceID, ev.SpaceID)
|
||||
}
|
||||
func shareID(id string) *collaboration.ShareId {
|
||||
return &collaboration.ShareId{
|
||||
OpaqueId: id,
|
||||
}
|
||||
}
|
||||
|
||||
func linkID(id string) *link.PublicShareId {
|
||||
return &link.PublicShareId{
|
||||
OpaqueId: id,
|
||||
}
|
||||
}
|
||||
|
||||
func userID(id string) *user.UserId {
|
||||
return &user.UserId{
|
||||
OpaqueId: id,
|
||||
Idp: "idp",
|
||||
}
|
||||
}
|
||||
|
||||
func groupID(id string) *group.GroupId {
|
||||
return &group.GroupId{
|
||||
OpaqueId: id,
|
||||
Idp: "idp",
|
||||
}
|
||||
}
|
||||
|
||||
func resourceID(sid, oid string) *provider.ResourceId {
|
||||
return &provider.ResourceId{
|
||||
StorageId: sid,
|
||||
OpaqueId: oid,
|
||||
}
|
||||
}
|
||||
|
||||
func reference(sid, oid, path string) *provider.Reference {
|
||||
return &provider.Reference{
|
||||
ResourceId: resourceID(sid, oid),
|
||||
Path: path,
|
||||
}
|
||||
}
|
||||
|
||||
func timestamp(seconds uint64) *rtypes.Timestamp {
|
||||
return &rtypes.Timestamp{
|
||||
Seconds: seconds,
|
||||
Nanos: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func sharePermissions(perms ...string) *collaboration.SharePermissions {
|
||||
return &collaboration.SharePermissions{
|
||||
Permissions: permissions(perms...),
|
||||
}
|
||||
}
|
||||
|
||||
func linkPermissions(perms ...string) *link.PublicSharePermissions {
|
||||
return &link.PublicSharePermissions{
|
||||
Permissions: permissions(perms...),
|
||||
}
|
||||
}
|
||||
|
||||
func permissions(permissions ...string) *provider.ResourcePermissions {
|
||||
perms := &provider.ResourcePermissions{}
|
||||
|
||||
for _, p := range permissions {
|
||||
switch p {
|
||||
case "stat":
|
||||
perms.Stat = true
|
||||
case "get_path":
|
||||
perms.GetPath = true
|
||||
case "list_container":
|
||||
perms.ListContainer = true
|
||||
case "get_quota":
|
||||
perms.GetQuota = true
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return perms
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/cs3org/reva/v2/pkg/events"
|
||||
)
|
||||
|
||||
// short identifiers for audit actions
|
||||
const (
|
||||
// Sharing
|
||||
ActionShareCreated = "file_shared"
|
||||
ActionSharePermissionUpdated = "share_permission_updated"
|
||||
ActionShareDisplayNameUpdated = "share_name_updated"
|
||||
ActionSharePasswordUpdated = "share_password_updated"
|
||||
ActionShareExpirationUpdated = "share_expiration_updated"
|
||||
ActionShareRemoved = "file_unshared"
|
||||
ActionShareAccepted = "share_accepted"
|
||||
ActionShareDeclined = "share_declined"
|
||||
ActionLinkAccessed = "public_link_accessed"
|
||||
|
||||
// Files
|
||||
ActionContainerCreated = "container_create"
|
||||
ActionFileCreated = "file_create"
|
||||
ActionFileRead = "file_read"
|
||||
ActionFileTrashed = "file_delete"
|
||||
ActionFileRenamed = "file_rename"
|
||||
ActionFilePurged = "file_trash_delete"
|
||||
ActionFileRestored = "file_trash_restore"
|
||||
ActionFileVersionRestored = "file_version_restore"
|
||||
|
||||
// Spaces
|
||||
ActionSpaceCreated = "space_created"
|
||||
ActionSpaceRenamed = "space_renamed"
|
||||
ActionSpaceDisabled = "space_disabled"
|
||||
ActionSpaceEnabled = "space_enabled"
|
||||
ActionSpaceDeleted = "space_deleted"
|
||||
|
||||
// Users
|
||||
ActionUserCreated = "user_created"
|
||||
ActionUserDeleted = "user_deleted"
|
||||
ActionUserFeatureChanged = "user_feature_changed"
|
||||
|
||||
// Groups
|
||||
ActionGroupCreated = "group_created"
|
||||
ActionGroupDeleted = "group_deleted"
|
||||
ActionGroupMemberAdded = "group_member_added"
|
||||
ActionGroupMemberRemoved = "group_member_removed"
|
||||
)
|
||||
|
||||
// MessageShareCreated returns the human readable string that describes the action
|
||||
func MessageShareCreated(sharer, item, grantee string) string {
|
||||
return fmt.Sprintf("user '%s' shared file '%s' with '%s'", sharer, item, grantee)
|
||||
}
|
||||
|
||||
// MessageLinkCreated returns the human readable string that describes the action
|
||||
func MessageLinkCreated(sharer, item, shareid string) string {
|
||||
return fmt.Sprintf("user '%s' created a public link to file '%s' with id '%s'", sharer, item, shareid)
|
||||
}
|
||||
|
||||
// MessageShareUpdated returns the human readable string that describes the action
|
||||
func MessageShareUpdated(sharer, shareID, fieldUpdated string) string {
|
||||
return fmt.Sprintf("user '%s' updated field '%s' of share '%s'", sharer, fieldUpdated, shareID)
|
||||
}
|
||||
|
||||
// MessageLinkUpdated returns the human readable string that describes the action
|
||||
func MessageLinkUpdated(sharer, shareid, fieldUpdated string) string {
|
||||
return fmt.Sprintf("user '%s' updated field '%s' of public link '%s'", sharer, fieldUpdated, shareid)
|
||||
}
|
||||
|
||||
// MessageShareRemoved returns the human readable string that describes the action
|
||||
func MessageShareRemoved(sharer, shareid, itemid string) string {
|
||||
return fmt.Sprintf("share id:'%s' uid:'%s' item-id:'%s' was removed", shareid, sharer, itemid)
|
||||
}
|
||||
|
||||
// MessageLinkRemoved returns the human readable string that describes the action
|
||||
func MessageLinkRemoved(executant, shareid string) string {
|
||||
return fmt.Sprintf("user '%s' removed public link with id:'%s'", executant, shareid)
|
||||
}
|
||||
|
||||
// MessageShareAccepted returns the human readable string that describes the action
|
||||
func MessageShareAccepted(userid, shareid, sharerid string) string {
|
||||
return fmt.Sprintf("user '%s' accepted share '%s' from user '%s'", userid, shareid, sharerid)
|
||||
}
|
||||
|
||||
// MessageShareDeclined returns the human readable string that describes the action
|
||||
func MessageShareDeclined(userid, shareid, sharerid string) string {
|
||||
return fmt.Sprintf("user '%s' declined share '%s' from user '%s'", userid, shareid, sharerid)
|
||||
}
|
||||
|
||||
// MessageLinkAccessed returns the human readable string that describes the action
|
||||
func MessageLinkAccessed(linkid string, success bool) string {
|
||||
return fmt.Sprintf("link '%s' was accessed. Success: %v", linkid, success)
|
||||
}
|
||||
|
||||
// MessageContainerCreated returns the human readable string that describes the action
|
||||
func MessageContainerCreated(executant, item string) string {
|
||||
return fmt.Sprintf("user '%s' created folder '%s'", executant, item)
|
||||
}
|
||||
|
||||
// MessageFileCreated returns the human readable string that describes the action
|
||||
func MessageFileCreated(executant, item string) string {
|
||||
return fmt.Sprintf("user '%s' created file '%s'", executant, item)
|
||||
}
|
||||
|
||||
// MessageFileRead returns the human readable string that describes the action
|
||||
func MessageFileRead(executant, item string) string {
|
||||
return fmt.Sprintf("user '%s' read file '%s'", executant, item)
|
||||
}
|
||||
|
||||
// MessageFileTrashed returns the human readable string that describes the action
|
||||
func MessageFileTrashed(executant, item string) string {
|
||||
return fmt.Sprintf("user '%s' trashed file '%s'", executant, item)
|
||||
}
|
||||
|
||||
// MessageFileRenamed returns the human readable string that describes the action
|
||||
func MessageFileRenamed(executant, item, oldpath, newpath string) string {
|
||||
return fmt.Sprintf("user '%s' moved file '%s' from '%s' to '%s'", executant, item, oldpath, newpath)
|
||||
}
|
||||
|
||||
// MessageFilePurged returns the human readable string that describes the action
|
||||
func MessageFilePurged(executant, item string) string {
|
||||
return fmt.Sprintf("user '%s' removed file '%s' from trashbin", executant, item)
|
||||
}
|
||||
|
||||
// MessageFileRestored returns the human readable string that describes the action
|
||||
func MessageFileRestored(executant, item, path string) string {
|
||||
return fmt.Sprintf("user '%s' restored file '%s' from trashbin to '%s'", executant, item, path)
|
||||
}
|
||||
|
||||
// MessageFileVersionRestored returns the human readable string that describes the action
|
||||
func MessageFileVersionRestored(executant, item, version string) string {
|
||||
return fmt.Sprintf("user '%s' restored file '%s' in version '%s'", executant, item, version)
|
||||
}
|
||||
|
||||
// MessageSpaceCreated returns the human readable string that describes the action
|
||||
func MessageSpaceCreated(executant, spaceID, name string) string {
|
||||
return fmt.Sprintf("user '%s' created a space '%s' with name '%s'", executant, spaceID, name)
|
||||
}
|
||||
|
||||
// MessageSpaceRenamed returns the human readable string that describes the action
|
||||
func MessageSpaceRenamed(executant, spaceID, name string) string {
|
||||
return fmt.Sprintf("user '%s' renamed space '%s' to '%s'", executant, spaceID, name)
|
||||
}
|
||||
|
||||
// MessageSpaceDisabled returns the human readable string that describes the action
|
||||
func MessageSpaceDisabled(executant, spaceID string) string {
|
||||
return fmt.Sprintf("user '%s' disabled the space '%s'", executant, spaceID)
|
||||
}
|
||||
|
||||
// MessageSpaceEnabled returns the human readable string that describes the action
|
||||
func MessageSpaceEnabled(executant, spaceID string) string {
|
||||
return fmt.Sprintf("user '%s' (re-) enabled the space '%s'", executant, spaceID)
|
||||
}
|
||||
|
||||
// MessageSpaceDeleted returns the human readable string that describes the action
|
||||
func MessageSpaceDeleted(executant, spaceID string) string {
|
||||
return fmt.Sprintf("user '%s' deleted the space '%s'", executant, spaceID)
|
||||
}
|
||||
|
||||
// MessageUserCreated returns the human readable string that describes the action
|
||||
func MessageUserCreated(executant, userID string) string {
|
||||
return fmt.Sprintf("user '%s' created the user '%s'", executant, userID)
|
||||
}
|
||||
|
||||
// MessageUserDeleted returns the human readable string that describes the action
|
||||
func MessageUserDeleted(executant, userID string) string {
|
||||
return fmt.Sprintf("user '%s' deleted the user '%s'", executant, userID)
|
||||
}
|
||||
|
||||
// MessageUserFeatureChanged returns the human readable string that describes the action
|
||||
func MessageUserFeatureChanged(executant, userID string, features []events.UserFeature) string {
|
||||
// Result is: "user '%executant%' changed user %username%'s features: %featurename%=%featurevalue% %featurename%=%featurevalue%"
|
||||
var sb strings.Builder
|
||||
sb.WriteString("user '")
|
||||
sb.WriteString(executant)
|
||||
sb.WriteString("' changed user ")
|
||||
sb.WriteString(userID)
|
||||
sb.WriteString("'s features:")
|
||||
for _, f := range features {
|
||||
sb.WriteString(f.Name)
|
||||
sb.WriteRune('=')
|
||||
sb.WriteString(f.Value)
|
||||
sb.WriteRune(' ')
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
// MessageGroupCreated returns the human readable string that describes the action
|
||||
func MessageGroupCreated(executant, groupID string) string {
|
||||
return fmt.Sprintf("user '%s' created group '%s'", executant, groupID)
|
||||
}
|
||||
|
||||
// MessageGroupDeleted returns the human readable string that describes the action
|
||||
func MessageGroupDeleted(executant, groupID string) string {
|
||||
return fmt.Sprintf("user '%s' deleted group '%s'", executant, groupID)
|
||||
}
|
||||
|
||||
// MessageGroupMemberAdded returns the human readable string that describes the action
|
||||
func MessageGroupMemberAdded(executant, userID, groupID string) string {
|
||||
return fmt.Sprintf("user '%s' added user '%s' was added to group '%s'", executant, userID, groupID)
|
||||
}
|
||||
|
||||
// MessageGroupMemberRemoved returns the human readable string that describes the action
|
||||
func MessageGroupMemberRemoved(executant, userID, groupID string) string {
|
||||
return fmt.Sprintf("user '%s' added user '%s' was removed from group '%s'", executant, userID, groupID)
|
||||
}
|
||||
@@ -0,0 +1,500 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/cs3org/reva/v2/pkg/events"
|
||||
"github.com/cs3org/reva/v2/pkg/storagespace"
|
||||
|
||||
group "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
|
||||
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||
)
|
||||
|
||||
// BasicAuditEvent creates an AuditEvent from given values
|
||||
func BasicAuditEvent(uid string, ctime string, msg string, action string) AuditEvent {
|
||||
return AuditEvent{
|
||||
User: uid,
|
||||
Time: ctime,
|
||||
App: "admin_audit",
|
||||
Message: msg,
|
||||
Action: action,
|
||||
Level: 1,
|
||||
|
||||
// NOTE: those values are not in the events and can therefore not be filled at the moment
|
||||
RemoteAddr: "",
|
||||
URL: "",
|
||||
Method: "",
|
||||
UserAgent: "",
|
||||
CLI: false,
|
||||
}
|
||||
}
|
||||
|
||||
// SharingAuditEvent creates an AuditEventSharing from given values
|
||||
func SharingAuditEvent(shareid string, fileid string, uid string, base AuditEvent) AuditEventSharing {
|
||||
return AuditEventSharing{
|
||||
AuditEvent: base,
|
||||
FileID: fileid,
|
||||
Owner: uid,
|
||||
ShareID: shareid,
|
||||
|
||||
// NOTE: those values are not in the events and can therefore not be filled at the moment
|
||||
Path: "",
|
||||
}
|
||||
}
|
||||
|
||||
// ShareCreated converts a ShareCreated Event to an AuditEventShareCreated
|
||||
func ShareCreated(ev events.ShareCreated) AuditEventShareCreated {
|
||||
uid := ev.Sharer.OpaqueId
|
||||
grantee, typ := extractGrantee(ev.GranteeUserID, ev.GranteeGroupID)
|
||||
base := BasicAuditEvent(uid, formatTime(ev.CTime), MessageShareCreated(uid, ev.ItemID.OpaqueId, grantee), ActionShareCreated)
|
||||
return AuditEventShareCreated{
|
||||
AuditEventSharing: SharingAuditEvent("", ev.ItemID.OpaqueId, uid, base),
|
||||
ShareOwner: uid,
|
||||
ShareWith: grantee,
|
||||
ShareType: typ,
|
||||
|
||||
// NOTE: those values are not in the event and can therefore not be filled at the moment
|
||||
ItemType: "",
|
||||
ExpirationDate: "",
|
||||
SharePass: false,
|
||||
Permissions: "",
|
||||
ShareToken: "",
|
||||
}
|
||||
}
|
||||
|
||||
// LinkCreated converts a ShareCreated Event to an AuditEventShareCreated
|
||||
func LinkCreated(ev events.LinkCreated) AuditEventShareCreated {
|
||||
uid := ev.Sharer.OpaqueId
|
||||
with, typ := "", "link"
|
||||
base := BasicAuditEvent(uid, formatTime(ev.CTime), MessageLinkCreated(uid, ev.ItemID.OpaqueId, ev.ShareID.OpaqueId), ActionShareCreated)
|
||||
return AuditEventShareCreated{
|
||||
AuditEventSharing: SharingAuditEvent("", ev.ItemID.OpaqueId, uid, base),
|
||||
ShareOwner: uid,
|
||||
ShareWith: with,
|
||||
ShareType: typ,
|
||||
ExpirationDate: formatTime(ev.Expiration),
|
||||
SharePass: ev.PasswordProtected,
|
||||
Permissions: ev.Permissions.String(),
|
||||
ShareToken: ev.Token,
|
||||
|
||||
// NOTE: those values are not in the event and can therefore not be filled at the moment
|
||||
ItemType: "",
|
||||
}
|
||||
}
|
||||
|
||||
// ShareUpdated converts a ShareUpdated event to an AuditEventShareUpdated
|
||||
func ShareUpdated(ev events.ShareUpdated) AuditEventShareUpdated {
|
||||
uid := ev.Sharer.OpaqueId
|
||||
with, typ := extractGrantee(ev.GranteeUserID, ev.GranteeGroupID)
|
||||
base := BasicAuditEvent(uid, formatTime(ev.MTime), MessageShareUpdated(uid, ev.ShareID.OpaqueId, ev.Updated), updateType(ev.Updated))
|
||||
return AuditEventShareUpdated{
|
||||
AuditEventSharing: SharingAuditEvent(ev.ShareID.GetOpaqueId(), ev.ItemID.OpaqueId, uid, base),
|
||||
ShareOwner: uid,
|
||||
ShareWith: with,
|
||||
ShareType: typ,
|
||||
Permissions: ev.Permissions.Permissions.String(),
|
||||
|
||||
// NOTE: those values are not in the event and can therefore not be filled at the moment
|
||||
ItemType: "",
|
||||
ExpirationDate: "",
|
||||
SharePass: false,
|
||||
ShareToken: "",
|
||||
}
|
||||
}
|
||||
|
||||
// LinkUpdated converts a LinkUpdated event to an AuditEventShareUpdated
|
||||
func LinkUpdated(ev events.LinkUpdated) AuditEventShareUpdated {
|
||||
uid := ev.Sharer.OpaqueId
|
||||
with, typ := "", "link"
|
||||
base := BasicAuditEvent(uid, formatTime(ev.CTime), MessageLinkUpdated(uid, ev.ShareID.OpaqueId, ev.FieldUpdated), updateType(ev.FieldUpdated))
|
||||
return AuditEventShareUpdated{
|
||||
AuditEventSharing: SharingAuditEvent(ev.ShareID.GetOpaqueId(), ev.ItemID.OpaqueId, uid, base),
|
||||
ShareOwner: uid,
|
||||
ShareWith: with,
|
||||
ShareType: typ,
|
||||
Permissions: ev.Permissions.Permissions.String(),
|
||||
ExpirationDate: formatTime(ev.Expiration),
|
||||
SharePass: ev.PasswordProtected,
|
||||
ShareToken: ev.Token,
|
||||
|
||||
// NOTE: those values are not in the event and can therefore not be filled at the moment
|
||||
ItemType: "",
|
||||
}
|
||||
}
|
||||
|
||||
// ShareRemoved converts a ShareRemoved event to an AuditEventShareRemoved
|
||||
func ShareRemoved(ev events.ShareRemoved) AuditEventShareRemoved {
|
||||
sid, uid, iid, with, typ := "", "", "", "", ""
|
||||
if ev.ShareID != nil {
|
||||
sid = ev.ShareID.GetOpaqueId()
|
||||
}
|
||||
|
||||
if ev.ShareKey != nil {
|
||||
uid = ev.ShareKey.GetOwner().GetOpaqueId()
|
||||
iid = ev.ShareKey.GetResourceId().GetOpaqueId()
|
||||
with, typ = extractGrantee(ev.ShareKey.GetGrantee().GetUserId(), ev.ShareKey.GetGrantee().GetGroupId())
|
||||
}
|
||||
base := BasicAuditEvent(uid, "", MessageShareRemoved(uid, sid, iid), ActionShareRemoved)
|
||||
return AuditEventShareRemoved{
|
||||
AuditEventSharing: SharingAuditEvent(sid, iid, uid, base),
|
||||
ShareWith: with,
|
||||
ShareType: typ,
|
||||
|
||||
// NOTE: those values are not in the event and can therefore not be filled at the moment
|
||||
ItemType: "",
|
||||
}
|
||||
}
|
||||
|
||||
// LinkRemoved converts a LinkRemoved event to an AuditEventShareRemoved
|
||||
func LinkRemoved(ev events.LinkRemoved) AuditEventShareRemoved {
|
||||
uid, sid, typ := ev.Executant.GetOpaqueId(), "", "link"
|
||||
if ev.ShareID != nil {
|
||||
sid = ev.ShareID.GetOpaqueId()
|
||||
} else {
|
||||
sid = ev.ShareToken
|
||||
}
|
||||
|
||||
base := BasicAuditEvent(uid, "", MessageLinkRemoved(uid, sid), ActionShareRemoved)
|
||||
return AuditEventShareRemoved{
|
||||
AuditEventSharing: SharingAuditEvent(sid, "", uid, base),
|
||||
ShareWith: "",
|
||||
ShareType: typ,
|
||||
|
||||
// NOTE: those values are not in the event and can therefore not be filled at the moment
|
||||
ItemType: "",
|
||||
}
|
||||
}
|
||||
|
||||
// ReceivedShareUpdated converts a ReceivedShareUpdated event to an AuditEventReceivedShareUpdated
|
||||
func ReceivedShareUpdated(ev events.ReceivedShareUpdated) AuditEventReceivedShareUpdated {
|
||||
uid := ev.Sharer.GetOpaqueId()
|
||||
sid := ev.ShareID.GetOpaqueId()
|
||||
with, typ := extractGrantee(ev.GranteeUserID, ev.GranteeGroupID)
|
||||
itemID := ev.ItemID.GetOpaqueId()
|
||||
|
||||
msg, utype := "", ""
|
||||
switch ev.State {
|
||||
case "SHARE_STATE_ACCEPTED":
|
||||
msg = MessageShareAccepted(with, sid, uid)
|
||||
utype = ActionShareAccepted
|
||||
case "SHARE_STATE_DECLINED":
|
||||
msg = MessageShareDeclined(with, sid, uid)
|
||||
utype = ActionShareDeclined
|
||||
}
|
||||
base := BasicAuditEvent(with, formatTime(ev.MTime), msg, utype)
|
||||
return AuditEventReceivedShareUpdated{
|
||||
AuditEventSharing: SharingAuditEvent(sid, itemID, uid, base),
|
||||
ShareType: typ,
|
||||
ShareWith: with,
|
||||
|
||||
// NOTE: those values are not in the event and can therefore not be filled at the moment
|
||||
ItemType: "",
|
||||
}
|
||||
}
|
||||
|
||||
// LinkAccessed converts a LinkAccessed event to an AuditEventLinkAccessed
|
||||
func LinkAccessed(ev events.LinkAccessed) AuditEventLinkAccessed {
|
||||
uid := ev.Sharer.OpaqueId
|
||||
base := BasicAuditEvent(uid, formatTime(ev.CTime), MessageLinkAccessed(ev.ShareID.GetOpaqueId(), true), ActionLinkAccessed)
|
||||
return AuditEventLinkAccessed{
|
||||
AuditEventSharing: SharingAuditEvent(ev.ShareID.GetOpaqueId(), ev.ItemID.OpaqueId, uid, base),
|
||||
ShareToken: ev.Token,
|
||||
Success: true,
|
||||
|
||||
// NOTE: those values are not in the event and can therefore not be filled at the moment
|
||||
ItemType: "",
|
||||
}
|
||||
}
|
||||
|
||||
// LinkAccessFailed converts a LinkAccessFailed event to an AuditEventLinkAccessed
|
||||
func LinkAccessFailed(ev events.LinkAccessFailed) AuditEventLinkAccessed {
|
||||
base := BasicAuditEvent("", "", MessageLinkAccessed(ev.ShareID.GetOpaqueId(), false), ActionLinkAccessed)
|
||||
return AuditEventLinkAccessed{
|
||||
AuditEventSharing: SharingAuditEvent(ev.ShareID.GetOpaqueId(), "", "", base),
|
||||
ShareToken: ev.Token,
|
||||
Success: false,
|
||||
|
||||
// NOTE: those values are not in the event and can therefore not be filled at the moment
|
||||
ItemType: "",
|
||||
}
|
||||
}
|
||||
|
||||
// FilesAuditEvent creates an AuditEventFiles from the given values
|
||||
func FilesAuditEvent(base AuditEvent, itemid, owner, path string) AuditEventFiles {
|
||||
return AuditEventFiles{
|
||||
AuditEvent: base,
|
||||
FileID: itemid,
|
||||
Owner: owner,
|
||||
Path: path,
|
||||
}
|
||||
}
|
||||
|
||||
// ContainerCreated converts a ContainerCreated event to an AuditEventContainerCreated
|
||||
func ContainerCreated(ev events.ContainerCreated) AuditEventContainerCreated {
|
||||
iid, path, uid := extractFileDetails(ev.Ref, ev.Owner)
|
||||
base := BasicAuditEvent(uid, "", MessageContainerCreated(ev.Executant.GetOpaqueId(), iid), ActionContainerCreated)
|
||||
return AuditEventContainerCreated{
|
||||
AuditEventFiles: FilesAuditEvent(base, iid, uid, path),
|
||||
}
|
||||
}
|
||||
|
||||
// FileUploaded converts a FileUploaded event to an AuditEventFileCreated
|
||||
func FileUploaded(ev events.FileUploaded) AuditEventFileCreated {
|
||||
iid, path, uid := extractFileDetails(ev.Ref, ev.Owner)
|
||||
base := BasicAuditEvent(uid, "", MessageFileCreated(ev.Executant.GetOpaqueId(), iid), ActionFileCreated)
|
||||
return AuditEventFileCreated{
|
||||
AuditEventFiles: FilesAuditEvent(base, iid, uid, path),
|
||||
}
|
||||
}
|
||||
|
||||
// FileDownloaded converts a FileDownloaded event to an AuditEventFileRead
|
||||
func FileDownloaded(ev events.FileDownloaded) AuditEventFileRead {
|
||||
iid, path, uid := extractFileDetails(ev.Ref, ev.Owner)
|
||||
base := BasicAuditEvent(uid, "", MessageFileRead(ev.Executant.GetOpaqueId(), iid), ActionFileRead)
|
||||
return AuditEventFileRead{
|
||||
AuditEventFiles: FilesAuditEvent(base, iid, uid, path),
|
||||
}
|
||||
}
|
||||
|
||||
// ItemMoved converts a ItemMoved event to an AuditEventFileRenamed
|
||||
func ItemMoved(ev events.ItemMoved) AuditEventFileRenamed {
|
||||
iid, path, uid := extractFileDetails(ev.Ref, ev.Owner)
|
||||
|
||||
oldpath := ""
|
||||
if ev.OldReference != nil {
|
||||
oldpath = ev.OldReference.GetPath()
|
||||
}
|
||||
|
||||
base := BasicAuditEvent(uid, "", MessageFileRenamed(ev.Executant.GetOpaqueId(), iid, oldpath, path), ActionFileRenamed)
|
||||
return AuditEventFileRenamed{
|
||||
AuditEventFiles: FilesAuditEvent(base, iid, uid, path),
|
||||
OldPath: oldpath,
|
||||
}
|
||||
}
|
||||
|
||||
// ItemTrashed converts a ItemTrashed event to an AuditEventFileDeleted
|
||||
func ItemTrashed(ev events.ItemTrashed) AuditEventFileDeleted {
|
||||
iid, path, uid := extractFileDetails(ev.Ref, ev.Owner)
|
||||
base := BasicAuditEvent(uid, "", MessageFileTrashed(ev.Executant.GetOpaqueId(), iid), ActionFileTrashed)
|
||||
return AuditEventFileDeleted{
|
||||
AuditEventFiles: FilesAuditEvent(base, iid, uid, path),
|
||||
}
|
||||
}
|
||||
|
||||
// ItemPurged converts a ItemPurged event to an AuditEventFilePurged
|
||||
func ItemPurged(ev events.ItemPurged) AuditEventFilePurged {
|
||||
iid, path, uid := extractFileDetails(ev.Ref, ev.Owner)
|
||||
base := BasicAuditEvent(uid, "", MessageFilePurged(ev.Executant.GetOpaqueId(), iid), ActionFilePurged)
|
||||
return AuditEventFilePurged{
|
||||
AuditEventFiles: FilesAuditEvent(base, iid, uid, path),
|
||||
}
|
||||
}
|
||||
|
||||
// ItemRestored converts a ItemRestored event to an AuditEventFileRestored
|
||||
func ItemRestored(ev events.ItemRestored) AuditEventFileRestored {
|
||||
iid, path, uid := extractFileDetails(ev.Ref, ev.Owner)
|
||||
|
||||
oldpath := ""
|
||||
if ev.OldReference != nil {
|
||||
oldpath = ev.OldReference.GetPath()
|
||||
}
|
||||
|
||||
base := BasicAuditEvent(uid, "", MessageFileRestored(ev.Executant.GetOpaqueId(), iid, path), ActionFileRestored)
|
||||
return AuditEventFileRestored{
|
||||
AuditEventFiles: FilesAuditEvent(base, iid, uid, path),
|
||||
OldPath: oldpath,
|
||||
}
|
||||
}
|
||||
|
||||
// FileVersionRestored converts a FileVersionRestored event to an AuditEventFileVersionRestored
|
||||
func FileVersionRestored(ev events.FileVersionRestored) AuditEventFileVersionRestored {
|
||||
iid, path, uid := extractFileDetails(ev.Ref, ev.Owner)
|
||||
base := BasicAuditEvent(uid, "", MessageFileVersionRestored(ev.Executant.GetOpaqueId(), iid, ev.Key), ActionFileVersionRestored)
|
||||
return AuditEventFileVersionRestored{
|
||||
AuditEventFiles: FilesAuditEvent(base, iid, uid, path),
|
||||
Key: ev.Key,
|
||||
}
|
||||
}
|
||||
|
||||
// SpacesAuditEvent creates an AuditEventSpaces from the given values
|
||||
func SpacesAuditEvent(base AuditEvent, spaceID string) AuditEventSpaces {
|
||||
return AuditEventSpaces{
|
||||
AuditEvent: base,
|
||||
SpaceID: spaceID,
|
||||
}
|
||||
}
|
||||
|
||||
// SpaceCreated converts a SpaceCreated event to an AuditEventSpaceCreated
|
||||
func SpaceCreated(ev events.SpaceCreated) AuditEventSpaceCreated {
|
||||
sid := ev.ID.GetOpaqueId()
|
||||
iid, _, owner := extractFileDetails(&provider.Reference{ResourceId: ev.Root}, ev.Owner)
|
||||
base := BasicAuditEvent("", formatTime(ev.MTime), MessageSpaceCreated(ev.Executant.GetOpaqueId(), sid, ev.Name), ActionSpaceCreated)
|
||||
return AuditEventSpaceCreated{
|
||||
AuditEventSpaces: SpacesAuditEvent(base, sid),
|
||||
Owner: owner,
|
||||
RootItem: iid,
|
||||
Name: ev.Name,
|
||||
Type: ev.Type,
|
||||
}
|
||||
}
|
||||
|
||||
// SpaceRenamed converts a SpaceRenamed event to an AuditEventSpaceRenamed
|
||||
func SpaceRenamed(ev events.SpaceRenamed) AuditEventSpaceRenamed {
|
||||
sid := ev.ID.GetOpaqueId()
|
||||
base := BasicAuditEvent("", "", MessageSpaceRenamed(ev.Executant.GetOpaqueId(), sid, ev.Name), ActionSpaceRenamed)
|
||||
return AuditEventSpaceRenamed{
|
||||
AuditEventSpaces: SpacesAuditEvent(base, sid),
|
||||
NewName: ev.Name,
|
||||
}
|
||||
}
|
||||
|
||||
// SpaceDisabled converts a SpaceDisabled event to an AuditEventSpaceDisabled
|
||||
func SpaceDisabled(ev events.SpaceDisabled) AuditEventSpaceDisabled {
|
||||
sid := ev.ID.GetOpaqueId()
|
||||
base := BasicAuditEvent("", "", MessageSpaceDisabled(ev.Executant.GetOpaqueId(), sid), ActionSpaceDisabled)
|
||||
return AuditEventSpaceDisabled{
|
||||
AuditEventSpaces: SpacesAuditEvent(base, sid),
|
||||
}
|
||||
}
|
||||
|
||||
// SpaceEnabled converts a SpaceEnabled event to an AuditEventSpaceEnabled
|
||||
func SpaceEnabled(ev events.SpaceEnabled) AuditEventSpaceEnabled {
|
||||
sid := ev.ID.GetOpaqueId()
|
||||
base := BasicAuditEvent("", "", MessageSpaceEnabled(ev.Executant.GetOpaqueId(), sid), ActionSpaceEnabled)
|
||||
return AuditEventSpaceEnabled{
|
||||
AuditEventSpaces: SpacesAuditEvent(base, sid),
|
||||
}
|
||||
}
|
||||
|
||||
// SpaceDeleted converts a SpaceDeleted event to an AuditEventSpaceDeleted
|
||||
func SpaceDeleted(ev events.SpaceDeleted) AuditEventSpaceDeleted {
|
||||
sid := ev.ID.GetOpaqueId()
|
||||
base := BasicAuditEvent("", "", MessageSpaceDeleted(ev.Executant.GetOpaqueId(), sid), ActionSpaceDeleted)
|
||||
return AuditEventSpaceDeleted{
|
||||
AuditEventSpaces: SpacesAuditEvent(base, sid),
|
||||
}
|
||||
}
|
||||
|
||||
// UserCreated converts a UserCreated event to an AuditEventUserCreated
|
||||
func UserCreated(ev events.UserCreated) AuditEventUserCreated {
|
||||
base := BasicAuditEvent("", "", MessageUserCreated(ev.Executant.GetOpaqueId(), ev.UserID), ActionUserCreated)
|
||||
return AuditEventUserCreated{
|
||||
AuditEvent: base,
|
||||
UserID: ev.UserID,
|
||||
}
|
||||
}
|
||||
|
||||
// UserDeleted converts a UserDeleted event to an AuditEventUserDeleted
|
||||
func UserDeleted(ev events.UserDeleted) AuditEventUserDeleted {
|
||||
base := BasicAuditEvent("", "", MessageUserDeleted(ev.Executant.GetOpaqueId(), ev.UserID), ActionUserDeleted)
|
||||
return AuditEventUserDeleted{
|
||||
AuditEvent: base,
|
||||
UserID: ev.UserID,
|
||||
}
|
||||
}
|
||||
|
||||
// UserFeatureChanged converts a UserFeatureChanged event to an AuditEventUserFeatureChanged
|
||||
func UserFeatureChanged(ev events.UserFeatureChanged) AuditEventUserFeatureChanged {
|
||||
msg := MessageUserFeatureChanged(ev.Executant.GetOpaqueId(), ev.UserID, ev.Features)
|
||||
base := BasicAuditEvent("", "", msg, ActionUserFeatureChanged)
|
||||
return AuditEventUserFeatureChanged{
|
||||
AuditEvent: base,
|
||||
UserID: ev.UserID,
|
||||
Features: ev.Features,
|
||||
}
|
||||
}
|
||||
|
||||
// GroupCreated converts a GroupCreated event to an AuditEventGroupCreated
|
||||
func GroupCreated(ev events.GroupCreated) AuditEventGroupCreated {
|
||||
base := BasicAuditEvent("", "", MessageGroupCreated(ev.Executant.GetOpaqueId(), ev.GroupID), ActionGroupCreated)
|
||||
return AuditEventGroupCreated{
|
||||
AuditEvent: base,
|
||||
GroupID: ev.GroupID,
|
||||
}
|
||||
}
|
||||
|
||||
// GroupDeleted converts a GroupDeleted event to an AuditEventGroupDeleted
|
||||
func GroupDeleted(ev events.GroupDeleted) AuditEventGroupDeleted {
|
||||
base := BasicAuditEvent("", "", MessageGroupDeleted(ev.Executant.GetOpaqueId(), ev.GroupID), ActionGroupDeleted)
|
||||
return AuditEventGroupDeleted{
|
||||
AuditEvent: base,
|
||||
GroupID: ev.GroupID,
|
||||
}
|
||||
}
|
||||
|
||||
// GroupMemberAdded converts a GroupMemberAdded event to an AuditEventGroupMemberAdded
|
||||
func GroupMemberAdded(ev events.GroupMemberAdded) AuditEventGroupMemberAdded {
|
||||
msg := MessageGroupMemberAdded(ev.Executant.GetOpaqueId(), ev.GroupID, ev.UserID)
|
||||
base := BasicAuditEvent("", "", msg, ActionGroupMemberAdded)
|
||||
return AuditEventGroupMemberAdded{
|
||||
AuditEvent: base,
|
||||
GroupID: ev.GroupID,
|
||||
UserID: ev.UserID,
|
||||
}
|
||||
}
|
||||
|
||||
// GroupMemberRemoved converts a GroupMemberRemoved event to an AuditEventGroupMemberRemove
|
||||
func GroupMemberRemoved(ev events.GroupMemberRemoved) AuditEventGroupMemberRemoved {
|
||||
msg := MessageGroupMemberRemoved(ev.Executant.GetOpaqueId(), ev.GroupID, ev.UserID)
|
||||
base := BasicAuditEvent("", "", msg, ActionGroupMemberRemoved)
|
||||
return AuditEventGroupMemberRemoved{
|
||||
AuditEvent: base,
|
||||
GroupID: ev.GroupID,
|
||||
UserID: ev.UserID,
|
||||
}
|
||||
}
|
||||
|
||||
func extractGrantee(uid *user.UserId, gid *group.GroupId) (string, string) {
|
||||
switch {
|
||||
case uid != nil && uid.OpaqueId != "":
|
||||
return uid.OpaqueId, "user"
|
||||
case gid != nil && gid.OpaqueId != "":
|
||||
return gid.OpaqueId, "group"
|
||||
}
|
||||
|
||||
return "", ""
|
||||
}
|
||||
|
||||
func extractFileDetails(ref *provider.Reference, owner *user.UserId) (string, string, string) {
|
||||
id, path := "", ""
|
||||
if ref != nil {
|
||||
path = ref.GetPath()
|
||||
id, _ = storagespace.FormatReference(ref)
|
||||
}
|
||||
|
||||
uid := ""
|
||||
if owner != nil {
|
||||
uid = owner.GetOpaqueId()
|
||||
}
|
||||
return id, path, uid
|
||||
}
|
||||
|
||||
func formatTime(t *types.Timestamp) string {
|
||||
if t == nil {
|
||||
return ""
|
||||
}
|
||||
return time.Unix(int64(t.Seconds), int64(t.Nanos)).UTC().Format(time.RFC3339)
|
||||
}
|
||||
|
||||
func updateType(u string) string {
|
||||
switch u {
|
||||
case "permissions":
|
||||
return ActionSharePermissionUpdated
|
||||
case "displayname":
|
||||
return ActionShareDisplayNameUpdated
|
||||
case "TYPE_PERMISSIONS":
|
||||
return ActionSharePermissionUpdated
|
||||
case "TYPE_DISPLAYNAME":
|
||||
return ActionShareDisplayNameUpdated
|
||||
case "TYPE_PASSWORD":
|
||||
return ActionSharePasswordUpdated
|
||||
case "TYPE_EXPIRATION":
|
||||
return ActionShareExpirationUpdated
|
||||
default:
|
||||
fmt.Println("Unknown update type", u)
|
||||
return ""
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/cs3org/reva/v2/pkg/events"
|
||||
)
|
||||
|
||||
// RegisteredEvents returns the events the service is registered for
|
||||
func RegisteredEvents() []events.Unmarshaller {
|
||||
return []events.Unmarshaller{
|
||||
events.ShareCreated{},
|
||||
events.ShareUpdated{},
|
||||
events.LinkCreated{},
|
||||
events.LinkUpdated{},
|
||||
events.ShareRemoved{},
|
||||
events.LinkRemoved{},
|
||||
events.ReceivedShareUpdated{},
|
||||
events.LinkAccessed{},
|
||||
events.LinkAccessFailed{},
|
||||
events.ContainerCreated{},
|
||||
events.FileUploaded{},
|
||||
events.FileDownloaded{},
|
||||
events.ItemTrashed{},
|
||||
events.ItemMoved{},
|
||||
events.ItemPurged{},
|
||||
events.ItemRestored{},
|
||||
events.FileVersionRestored{},
|
||||
events.SpaceCreated{},
|
||||
events.SpaceRenamed{},
|
||||
events.SpaceEnabled{},
|
||||
events.SpaceDisabled{},
|
||||
events.SpaceDeleted{},
|
||||
events.UserCreated{},
|
||||
events.UserDeleted{},
|
||||
events.UserFeatureChanged{},
|
||||
events.GroupCreated{},
|
||||
events.GroupDeleted{},
|
||||
events.GroupMemberAdded{},
|
||||
events.GroupMemberRemoved{},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
package types
|
||||
|
||||
import "github.com/cs3org/reva/v2/pkg/events"
|
||||
|
||||
// AuditEvent is the basic audit event
|
||||
type AuditEvent struct {
|
||||
RemoteAddr string // the remote client IP
|
||||
User string // the UID of the user performing the action. Or "IP x.x.x.x.", "cron", "CLI", "unknown"
|
||||
URL string // the process request URI
|
||||
Method string // the HTTP request method
|
||||
UserAgent string // the HTTP request user agent
|
||||
Time string // the time of the event eg: 2018-05-08T08:26:00+00:00
|
||||
App string // always 'admin_audit'
|
||||
Message string // sentence explaining the action
|
||||
Action string // unique action identifier eg: file_delete or public_link_created
|
||||
CLI bool // if the action was performed from the CLI
|
||||
Level int // the log level of the entry (usually 1 for audit events)
|
||||
}
|
||||
|
||||
/*
|
||||
Sharing
|
||||
*/
|
||||
|
||||
// AuditEventSharing is the basic audit event for shares
|
||||
type AuditEventSharing struct {
|
||||
AuditEvent
|
||||
|
||||
FileID string // The file identifier for the item shared.
|
||||
Owner string // The UID of the owner of the shared item.
|
||||
Path string // The path to the shared item.
|
||||
ShareID string // The sharing identifier. (not available for public_link_accessed or when recipient unshares)
|
||||
}
|
||||
|
||||
// AuditEventShareCreated is the event logged when a share is created
|
||||
type AuditEventShareCreated struct {
|
||||
AuditEventSharing
|
||||
|
||||
ItemType string // file or folder
|
||||
ExpirationDate string // The text expiration date in format 'yyyy-mm-dd'
|
||||
SharePass bool // If the share is password protected.
|
||||
Permissions string // The permissions string eg: "READ"
|
||||
ShareType string // group user or link
|
||||
ShareWith string // The UID or GID of the share recipient. (not available for public link)
|
||||
ShareOwner string // The UID of the share owner.
|
||||
ShareToken string // For link shares the unique token, else null
|
||||
}
|
||||
|
||||
// AuditEventShareUpdated is the event logged when a share is updated
|
||||
type AuditEventShareUpdated struct {
|
||||
AuditEventSharing
|
||||
|
||||
ItemType string // file or folder
|
||||
ExpirationDate string // The text expiration date in format 'yyyy-mm-dd'
|
||||
SharePass bool // If the share is password protected.
|
||||
Permissions string // The permissions string eg: "READ"
|
||||
ShareType string // group user or link
|
||||
ShareWith string // The UID or GID of the share recipient. (not available for public link)
|
||||
ShareOwner string // The UID of the share owner.
|
||||
ShareToken string // For link shares the unique token, else null
|
||||
}
|
||||
|
||||
// AuditEventShareRemoved is the event logged when a share is removed
|
||||
type AuditEventShareRemoved struct {
|
||||
AuditEventSharing
|
||||
ItemType string // file or folder
|
||||
ShareType string // group user or link
|
||||
ShareWith string // The UID or GID of the share recipient.
|
||||
}
|
||||
|
||||
// AuditEventReceivedShareUpdated is the event logged when a share is accepted or declined
|
||||
type AuditEventReceivedShareUpdated struct {
|
||||
AuditEventSharing
|
||||
ItemType string // file or folder
|
||||
ShareType string // group user or link
|
||||
ShareWith string // The UID or GID of the share recipient.
|
||||
}
|
||||
|
||||
// AuditEventLinkAccessed is the event logged when a link is accessed
|
||||
type AuditEventLinkAccessed struct {
|
||||
AuditEventSharing
|
||||
ShareToken string // The share token.
|
||||
Success bool // If the request was successful.
|
||||
ItemType string // file or folder
|
||||
}
|
||||
|
||||
/*
|
||||
Files
|
||||
*/
|
||||
|
||||
// AuditEventFiles is the basic audit event for files
|
||||
type AuditEventFiles struct {
|
||||
AuditEvent
|
||||
|
||||
Path string // The full path to the create file.
|
||||
Owner string // The UID of the owner of the file.
|
||||
FileID string // The newly created files identifier.
|
||||
}
|
||||
|
||||
// AuditEventContainerCreated is the event logged when a container is created
|
||||
type AuditEventContainerCreated struct {
|
||||
AuditEventFiles
|
||||
}
|
||||
|
||||
// AuditEventFileCreated is the event logged when a file is created
|
||||
type AuditEventFileCreated struct {
|
||||
AuditEventFiles
|
||||
}
|
||||
|
||||
// AuditEventFileRead is the event logged when a file is read (aka downloaded)
|
||||
type AuditEventFileRead struct {
|
||||
AuditEventFiles
|
||||
}
|
||||
|
||||
// AuditEventFileUpdated is the event logged when a file is updated
|
||||
// TODO: How to differentiate between new uploads and new version uploads?
|
||||
// FIXME: implement
|
||||
type AuditEventFileUpdated struct {
|
||||
AuditEventFiles
|
||||
}
|
||||
|
||||
// AuditEventFileDeleted is the event logged when a file is deleted (aka trashed)
|
||||
type AuditEventFileDeleted struct {
|
||||
AuditEventFiles
|
||||
}
|
||||
|
||||
// AuditEventFileCopied is the event logged when a file is copied
|
||||
// TODO: copy is a download&upload for now. How to know it was a copy?
|
||||
// FIXME: implement
|
||||
type AuditEventFileCopied struct {
|
||||
AuditEventFiles
|
||||
}
|
||||
|
||||
// AuditEventFileRenamed is the event logged when a file is renamed (moved)
|
||||
type AuditEventFileRenamed struct {
|
||||
AuditEventFiles
|
||||
|
||||
OldPath string
|
||||
}
|
||||
|
||||
// AuditEventFilePurged is the event logged when a file is purged (deleted from trashbin)
|
||||
type AuditEventFilePurged struct {
|
||||
AuditEventFiles
|
||||
}
|
||||
|
||||
// AuditEventFileRestored is the event logged when a file is restored (from trashbin)
|
||||
type AuditEventFileRestored struct {
|
||||
AuditEventFiles
|
||||
|
||||
OldPath string
|
||||
}
|
||||
|
||||
// AuditEventFileVersionRestored is the event logged when a file version is restored
|
||||
type AuditEventFileVersionRestored struct {
|
||||
AuditEventFiles
|
||||
|
||||
Key string
|
||||
}
|
||||
|
||||
// AuditEventFileVersionDeleted is the event logged when a file version is deleted
|
||||
// TODO: is this even possible?
|
||||
type AuditEventFileVersionDeleted struct {
|
||||
AuditEventFiles
|
||||
}
|
||||
|
||||
/*
|
||||
Spaces
|
||||
*/
|
||||
|
||||
// AuditEventSpaces is the basic audit event for spaces
|
||||
type AuditEventSpaces struct {
|
||||
AuditEvent
|
||||
|
||||
SpaceID string
|
||||
}
|
||||
|
||||
// AuditEventSpaceCreated is the event logged when a space is created
|
||||
type AuditEventSpaceCreated struct {
|
||||
AuditEventSpaces
|
||||
|
||||
Owner string
|
||||
RootItem string
|
||||
Name string
|
||||
Type string
|
||||
}
|
||||
|
||||
// AuditEventSpaceRenamed is the event logged when a space is renamed
|
||||
type AuditEventSpaceRenamed struct {
|
||||
AuditEventSpaces
|
||||
|
||||
NewName string
|
||||
}
|
||||
|
||||
// AuditEventSpaceDisabled is the event logged when a space is disabled
|
||||
type AuditEventSpaceDisabled struct {
|
||||
AuditEventSpaces
|
||||
}
|
||||
|
||||
// AuditEventSpaceEnabled is the event logged when a space is (re-)enabled
|
||||
type AuditEventSpaceEnabled struct {
|
||||
AuditEventSpaces
|
||||
}
|
||||
|
||||
// AuditEventSpaceDeleted is the event logged when a space is deleted
|
||||
type AuditEventSpaceDeleted struct {
|
||||
AuditEventSpaces
|
||||
}
|
||||
|
||||
// AuditEventUserCreated is the event logged when a user is created
|
||||
type AuditEventUserCreated struct {
|
||||
AuditEvent
|
||||
UserID string
|
||||
}
|
||||
|
||||
// AuditEventUserDeleted is the event logged when a user is deleted
|
||||
type AuditEventUserDeleted struct {
|
||||
AuditEvent
|
||||
UserID string
|
||||
}
|
||||
|
||||
// AuditEventUserFeatureChanged is the event logged when a user feature is changed
|
||||
type AuditEventUserFeatureChanged struct {
|
||||
AuditEvent
|
||||
UserID string
|
||||
Features []events.UserFeature
|
||||
}
|
||||
|
||||
// AuditEventGroupCreated is the event logged when a group is created
|
||||
type AuditEventGroupCreated struct {
|
||||
AuditEvent
|
||||
GroupID string
|
||||
}
|
||||
|
||||
// AuditEventGroupDeleted is the event logged when a group is deleted
|
||||
type AuditEventGroupDeleted struct {
|
||||
AuditEvent
|
||||
GroupID string
|
||||
}
|
||||
|
||||
// AuditEventGroupMemberAdded is the event logged when a group member is added
|
||||
type AuditEventGroupMemberAdded struct {
|
||||
AuditEvent
|
||||
GroupID string
|
||||
UserID string
|
||||
}
|
||||
|
||||
// AuditEventGroupMemberRemoved is the event logged when a group member is removed
|
||||
type AuditEventGroupMemberRemoved struct {
|
||||
AuditEvent
|
||||
GroupID string
|
||||
UserID string
|
||||
}
|
||||
Reference in New Issue
Block a user