feature: #135 Permissions for logs (#273)

This commit is contained in:
James Read 2024-04-18 21:52:04 +01:00 committed by GitHub
parent f60ab6ce85
commit db5de9be97
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 54 additions and 24 deletions

View File

@ -17,24 +17,51 @@ type AuthenticatedUser struct {
acls []string
}
// IsAllowedExec checks if a AuthenticatedUser is allowed to execute an Action
func IsAllowedExec(cfg *config.Config, user *AuthenticatedUser, action *config.Action) bool {
func logAclNotMatched(cfg *config.Config, aclFunction string, user *AuthenticatedUser, action *config.Action) {
if cfg.LogDebugOptions.AclNotMatched {
log.WithFields(log.Fields{
"User": user.Username,
"Action": action.Title,
}).Debugf("%v - No ACLs Matched", aclFunction)
}
}
func logAclMatched(cfg *config.Config, aclFunction string, user *AuthenticatedUser, action *config.Action, acl *config.AccessControlList) {
if cfg.LogDebugOptions.AclMatched {
log.WithFields(log.Fields{
"User": user.Username,
"Action": action.Title,
"ACL": acl.Name,
}).Debugf("%v - Matched ACL", aclFunction)
}
}
// IsAllowedLogs checks if a AuthenticatedUser is allowed to view an action's logs
func IsAllowedLogs(cfg *config.Config, user *AuthenticatedUser, action *config.Action) bool {
for _, acl := range getRelevantAcls(cfg, action.Acls, user) {
if acl.Permissions.Exec {
log.WithFields(log.Fields{
"User": user.Username,
"Action": action.Title,
"ACL": acl.Name,
}).Trace("isAllowedExec - Matched ACL")
if acl.Permissions.Logs {
logAclMatched(cfg, "isAllowedLogs", user, action, acl)
return true
}
}
log.WithFields(log.Fields{
"User": user.Username,
"Action": action.Title,
}).Trace("isAllowedExec - No ACLs matched")
logAclNotMatched(cfg, "isAllowedLogs", user, action)
return cfg.DefaultPermissions.Logs
}
// IsAllowedExec checks if a AuthenticatedUser is allowed to execute an Action
func IsAllowedExec(cfg *config.Config, user *AuthenticatedUser, action *config.Action) bool {
for _, acl := range getRelevantAcls(cfg, action.Acls, user) {
if acl.Permissions.Exec {
logAclMatched(cfg, "isAllowedExec", user, action, acl)
return true
}
}
logAclNotMatched(cfg, "isAllowedExec", user, action)
return cfg.DefaultPermissions.Exec
}
@ -47,20 +74,13 @@ func IsAllowedView(cfg *config.Config, user *AuthenticatedUser, action *config.A
for _, acl := range getRelevantAcls(cfg, action.Acls, user) {
if acl.Permissions.View {
log.WithFields(log.Fields{
"User": user.Username,
"Action": action.Title,
"ACL": acl.Name,
}).Trace("isAllowedView - Matched ACL")
logAclMatched(cfg, "isAllowedView", user, action, acl)
return true
}
}
log.WithFields(log.Fields{
"User": user.Username,
"Action": action.Title,
}).Trace("isAllowedView - No ACLs matched")
logAclNotMatched(cfg, "isAllowedView", user, action)
return cfg.DefaultPermissions.View
}

View File

@ -53,6 +53,7 @@ type EntityFile struct {
type PermissionsList struct {
View bool
Exec bool
Logs bool
}
// AccessControlList defines what permissions apply to a user or user group.
@ -117,6 +118,8 @@ type Config struct {
type LogDebugOptions struct {
SingleFrontendRequests bool
SingleFrontendRequestHeaders bool
AclMatched bool
AclNotMatched bool
}
type DashboardComponent struct {
@ -144,6 +147,7 @@ func DefaultConfig() *Config {
config.CheckForUpdates = true
config.DefaultPermissions.Exec = true
config.DefaultPermissions.View = true
config.DefaultPermissions.Logs = true
config.AuthJwtClaimUsername = "name"
config.AuthJwtClaimUserGroup = "group"
config.WebUIDir = "./webui"

View File

@ -227,15 +227,21 @@ func (api *oliveTinAPI) GetDashboardComponents(ctx ctx.Context, req *pb.GetDashb
}
func (api *oliveTinAPI) GetLogs(ctx ctx.Context, req *pb.GetLogsRequest) (*pb.GetLogsResponse, error) {
user := acl.UserFromContext(ctx, cfg)
ret := &pb.GetLogsResponse{}
// TODO Limit to 10 entries or something to prevent browser lag.
for trackingId, logEntry := range api.executor.Logs {
pbLogEntry := internalLogEntryToPb(logEntry)
pbLogEntry.ExecutionTrackingId = trackingId
action := cfg.FindAction(logEntry.ActionTitle)
ret.Logs = append(ret.Logs, pbLogEntry)
if action == nil || acl.IsAllowedLogs(cfg, user, action) {
pbLogEntry := internalLogEntryToPb(logEntry)
pbLogEntry.ExecutionTrackingId = trackingId
ret.Logs = append(ret.Logs, pbLogEntry)
}
}
sorter := func(i, j int) bool {