Explorar o código

feature: Log username with each request #422 (#424)

James Read hai 1 ano
pai
achega
5d82ae7680

+ 16 - 8
internal/acl/acl.go

@@ -2,6 +2,7 @@ package acl
 
 import (
 	"context"
+
 	config "github.com/OliveTin/OliveTin/internal/config"
 	log "github.com/sirupsen/logrus"
 
@@ -135,25 +136,22 @@ func getMetadataKeyOrEmpty(md metadata.MD, key string) string {
 
 // UserFromContext tries to find a user from a grpc context
 func UserFromContext(ctx context.Context, cfg *config.Config) *AuthenticatedUser {
-	ret := &AuthenticatedUser{}
+	var ret *AuthenticatedUser
 
 	md, ok := metadata.FromIncomingContext(ctx)
 
 	if ok {
+		ret = &AuthenticatedUser{}
 		ret.Username = getMetadataKeyOrEmpty(md, "username")
 		ret.Usergroup = getMetadataKeyOrEmpty(md, "usergroup")
-	}
 
-	if ret.Username == "" {
-		ret.Username = "guest"
+		buildUserAcls(cfg, ret)
 	}
 
-	if ret.Usergroup == "" {
-		ret.Usergroup = "guest"
+	if !ok || ret.Username == "" {
+		ret = UserGuest(cfg)
 	}
 
-	buildUserAcls(cfg, ret)
-
 	log.WithFields(log.Fields{
 		"username":  ret.Username,
 		"usergroup": ret.Usergroup,
@@ -162,6 +160,16 @@ func UserFromContext(ctx context.Context, cfg *config.Config) *AuthenticatedUser
 	return ret
 }
 
+func UserGuest(cfg *config.Config) *AuthenticatedUser {
+	ret := &AuthenticatedUser{}
+	ret.Username = "guest"
+	ret.Usergroup = "guest"
+
+	buildUserAcls(cfg, ret)
+
+	return ret
+}
+
 func UserFromSystem(cfg *config.Config, username string) *AuthenticatedUser {
 	ret := &AuthenticatedUser{
 		Username:  username,

+ 6 - 0
internal/executor/executor.go

@@ -84,6 +84,7 @@ type InternalLogEntry struct {
 	ExecutionFinished   bool
 	ExecutionTrackingID string
 	Process             *os.Process
+	Username            string
 
 	/*
 		The following 3 properties are obviously on Action normally, but it's useful
@@ -182,6 +183,10 @@ func (e *Executor) SetLog(trackingID string, entry *InternalLogEntry) {
 
 // ExecRequest processes an ExecutionRequest
 func (e *Executor) ExecRequest(req *ExecutionRequest) (*sync.WaitGroup, string) {
+	if req.AuthenticatedUser == nil {
+		req.AuthenticatedUser = acl.UserGuest(req.Cfg)
+	}
+
 	req.executor = e
 	req.logEntry = &InternalLogEntry{
 		DatetimeStarted:     time.Now(),
@@ -193,6 +198,7 @@ func (e *Executor) ExecRequest(req *ExecutionRequest) (*sync.WaitGroup, string)
 		ActionId:            "",
 		ActionTitle:         "notfound",
 		ActionIcon:          "💩",
+		Username:            req.AuthenticatedUser.Username,
 	}
 
 	_, isDuplicate := e.GetLog(req.TrackingID)

+ 5 - 1
internal/grpcapi/grpcApi.go

@@ -2,6 +2,7 @@ package grpcapi
 
 import (
 	ctx "context"
+
 	pb "github.com/OliveTin/OliveTin/gen/grpc"
 	"github.com/google/uuid"
 	log "github.com/sirupsen/logrus"
@@ -75,12 +76,14 @@ func (api *oliveTinAPI) StartAction(ctx ctx.Context, req *pb.StartActionRequest)
 		return nil, status.Errorf(codes.NotFound, "Action not found.")
 	}
 
+	authenticatedUser := acl.UserFromContext(ctx, cfg)
+
 	execReq := executor.ExecutionRequest{
 		Action:            pair.Action,
 		EntityPrefix:      pair.EntityPrefix,
 		TrackingID:        req.UniqueTrackingId,
 		Arguments:         args,
-		AuthenticatedUser: acl.UserFromContext(ctx, cfg),
+		AuthenticatedUser: authenticatedUser,
 		Cfg:               cfg,
 	}
 
@@ -174,6 +177,7 @@ func internalLogEntryToPb(logEntry *executor.InternalLogEntry) *pb.LogEntry {
 		ExecutionTrackingId: logEntry.ExecutionTrackingID,
 		ExecutionStarted:    logEntry.ExecutionStarted,
 		ExecutionFinished:   logEntry.ExecutionFinished,
+		User:                logEntry.Username,
 	}
 }
 

+ 1 - 1
internal/oncalendarfile/calendar.go

@@ -109,7 +109,7 @@ func exec(instant time.Time, action *config.Action, cfg *config.Config, ex *exec
 	req := &executor.ExecutionRequest{
 		Action:            action,
 		Cfg:               cfg,
-		Tags:              []string{"calendar"},
+		Tags:              []string{},
 		AuthenticatedUser: acl.UserFromSystem(cfg, "calendar"),
 	}
 

+ 1 - 1
internal/oncron/cron.go

@@ -36,7 +36,7 @@ func scheduleAction(cfg *config.Config, scheduler *cron.Cron, cronline string, e
 		req := &executor.ExecutionRequest{
 			ActionTitle:       action.Title,
 			Cfg:               cfg,
-			Tags:              []string{"cron"},
+			Tags:              []string{},
 			AuthenticatedUser: acl.UserFromSystem(cfg, "cron"),
 		}
 

+ 1 - 1
internal/onfileindir/fileindir.go

@@ -46,7 +46,7 @@ func scheduleExec(action *config.Action, cfg *config.Config, ex *executor.Execut
 	req := &executor.ExecutionRequest{
 		ActionTitle:       action.Title,
 		Cfg:               cfg,
-		Tags:              []string{"fileindir"},
+		Tags:              []string{},
 		Arguments:         args,
 		AuthenticatedUser: acl.UserFromSystem(cfg, "fileindir"),
 	}

+ 2 - 2
internal/onstartup/startup.go

@@ -8,7 +8,7 @@ import (
 )
 
 func Execute(cfg *config.Config, ex *executor.Executor) {
-	user := acl.UserFromSystem(cfg, "startup-user")
+	user := acl.UserFromSystem(cfg, "startup")
 
 	for _, action := range cfg.Actions {
 		if action.ExecOnStartup {
@@ -20,7 +20,7 @@ func Execute(cfg *config.Config, ex *executor.Executor) {
 				ActionTitle:       action.Title,
 				Arguments:         nil,
 				Cfg:               cfg,
-				Tags:              []string{"startup"},
+				Tags:              []string{},
 				AuthenticatedUser: user,
 			}
 

+ 6 - 2
internal/websocket/websocket.go

@@ -1,14 +1,15 @@
 package websocket
 
 import (
+	"net/http"
+	"sync"
+
 	pb "github.com/OliveTin/OliveTin/gen/grpc"
 	"github.com/OliveTin/OliveTin/internal/executor"
 	ws "github.com/gorilla/websocket"
 	log "github.com/sirupsen/logrus"
 	"google.golang.org/protobuf/encoding/protojson"
 	"google.golang.org/protobuf/reflect/protoreflect"
-	"net/http"
-	"sync"
 )
 
 var upgrader = ws.Upgrader{
@@ -95,9 +96,12 @@ func (WebsocketExecutionListener) OnExecutionFinished(logEntry *executor.Interna
 			ExecutionTrackingId: logEntry.ExecutionTrackingID,
 			ExecutionStarted:    logEntry.ExecutionStarted,
 			ExecutionFinished:   logEntry.ExecutionFinished,
+			User:                logEntry.Username,
 		},
 	}
 
+	log.Infof("Execution finished: %v+v", evt.LogEntry)
+
 	broadcast(evt)
 }
 

+ 1 - 1
webui.dev/index.html

@@ -58,7 +58,7 @@
 						<tr title = "untitled">
 							<th>Timestamp</th>
 							<th>Action</th>
-							<th>Tags</th>
+							<th>Metadata</th>
 							<th>Status</th>
 						</tr>
 					</thead>

+ 47 - 5
webui.dev/js/marshaller.js

@@ -2,6 +2,49 @@ import './ActionButton.js' // To define action-button
 import { ExecutionDialog } from './ExecutionDialog.js'
 import { ActionStatusDisplay } from './ActionStatusDisplay.js'
 
+function createElement (tag, attributes) {
+  const el = document.createElement(tag)
+
+  if (attributes !== null) {
+    if (attributes.classNames !== undefined) {
+      el.classList.add(...attributes.classNames)
+    }
+
+    if (attributes.innerText !== undefined) {
+      el.innerText = attributes.innerText
+    }
+  }
+
+  return el
+}
+
+function createTag (val) {
+  const domTag = createElement('span', {
+    innerText: val,
+    classNames: ['tag']
+  })
+
+  return domTag
+}
+
+function createAnnotation (key, val) {
+  const domAnnotation = createElement('span', {
+    classNames: ['annotation']
+  })
+
+  domAnnotation.appendChild(createElement('span', {
+    innerText: key,
+    classNames: ['annotationKey']
+  }))
+
+  domAnnotation.appendChild(createElement('span', {
+    innerText: val,
+    classNames: ['annotationValue']
+  }))
+
+  return domAnnotation
+}
+
 /**
  * This is a weird function that just sets some globals.
  */
@@ -577,13 +620,12 @@ export function marshalLogsJsonToHtml (json) {
     }
 
     for (const tag of logEntry.tags) {
-      const domTag = document.createElement('span')
-      domTag.classList.add('tag')
-      domTag.innerText = tag
-
-      row.querySelector('.tags').append(domTag)
+      row.querySelector('.tags').append(createTag(tag))
     }
 
+    console.log(logEntry)
+    row.querySelector('.tags').append(createAnnotation('user', logEntry.user))
+
     document.querySelector('#logTableBody').prepend(row)
   }
 }

+ 24 - 2
webui.dev/style.css

@@ -457,12 +457,34 @@ input.invalid {
 }
 
 span.tag {
-  background-color: lightgray;
   border-radius: 0.4em;
-  padding: 0.4em;
   margin-top: .2em;
   margin-right: .2em;
   display: inline-block;
+  background-color: lightgray;
+  padding: .4em;
+  color: black;
+}
+
+span.annotation {
+  display: inline-block;
+  margin-top: .2em;
+  margin-right: .2em;
+}
+
+span.annotationKey {
+  padding: 0.4em;
+  border-radius: 0.4em 0 0 .4em;
+  display: inline-block;
+  background-color: lightgray;
+  color: #666;
+}
+
+span.annotationValue {
+  padding: 0.4em;
+  border-radius: 0 .4em .4em 0;
+  display: inline-block;
+  background-color: lightgray;
   color: black;
 }