add event log retrieval
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2024-01-17 12:20:01 +11:00
parent 5f63ee235b
commit f68bd9637d
8 changed files with 75 additions and 12 deletions

View File

@@ -92,7 +92,9 @@ Body
```
This API call will return a JWT token that must be present for any other API calls to succeed. The validity duration of this token is based on the configured TOKEN_HOUR_LIFESPAN value. JWT token is returned as value of `access_token`, and must be supplied via a HTTP header in the form `"Authorization: Bearer <JWT_TOKEN>"` for all subsequent API calls.
### Unlock
#### Admin Only operations
#### Unlock
**POST** `/api/admin/unlock`
Body
@@ -106,6 +108,11 @@ If the SECRETS_KEY environment variable is not defined, this API call to unlock
This API call can only be made once after the service has started. Subsequent calls will receive an error until the service is restarted.
#### Event Logs
**GET** `/api/admin/logs`
This operation can only be performed by a user with that is admin enabled. Lists all event logs.
### User Operations
#### Register User

View File

@@ -82,7 +82,7 @@ func DeleteUser(c *gin.Context) {
UserId: RequestingUserId,
EventText: fmt.Sprintf("Deleted User Id %d", testUser.UserId),
}
a.AuditAdd()
a.AutidLogAdd()
c.JSON(http.StatusOK, gin.H{"message": "user deletion success"})
}
@@ -183,7 +183,7 @@ func AddUser(c *gin.Context) {
UserId: RequestingUserId,
EventText: fmt.Sprintf("Created User Id %d", u.UserId),
}
a.AuditAdd()
a.AutidLogAdd()
c.JSON(http.StatusOK, gin.H{"message": "user registration success", "data": u})
}

View File

@@ -0,0 +1,23 @@
package controllers
import (
"fmt"
"log"
"net/http"
"smt/models"
"github.com/gin-gonic/gin"
)
func GetAuditLogsHandler(c *gin.Context) {
logs, err := models.AuditLogList()
if err != nil {
errString := fmt.Sprintf("error retrieving audit logs : '%s'", err)
log.Printf("GetAuditLogsHandler %s\n", errString)
c.JSON(http.StatusBadRequest, gin.H{"error": errString})
return
}
c.JSON(http.StatusOK, gin.H{"message": "success", "data": logs})
}

View File

@@ -164,7 +164,7 @@ func retrieveSpecifiedSecret(s *models.Secret, c *gin.Context) {
UserId: UserId,
EventText: fmt.Sprintf("Retrieved Secret Id %d", results[0].SecretId),
}
a.AuditAdd()
a.AutidLogAdd()
// output results as json
c.JSON(http.StatusOK, gin.H{"message": "success", "data": results})
@@ -210,7 +210,7 @@ func ListSecrets(c *gin.Context) {
UserId: UserId,
EventText: fmt.Sprintf("Listed %d secrets, %+v", len(output), s),
}
a.AuditAdd()
a.AutidLogAdd()
// output results as json
c.JSON(http.StatusOK, gin.H{"message": "success", "data": output})

View File

@@ -149,7 +149,7 @@ func StoreSecret(c *gin.Context) {
UserId: UserId,
EventText: fmt.Sprintf("Created Secret Id %d", s.SecretId),
}
a.AuditAdd()
a.AutidLogAdd()
c.JSON(http.StatusOK, gin.H{"message": "secret stored successfully", "data": models.SecretRestricted(s)})
}
@@ -370,7 +370,7 @@ func UpdateSecret(c *gin.Context) {
UserId: UserId,
EventText: fmt.Sprintf("Updated Secret Id %d", s.SecretId),
}
a.AuditAdd()
a.AutidLogAdd()
c.JSON(http.StatusOK, gin.H{"message": "secret updated successfully", "data": models.SecretRestricted(s)})
} else {
@@ -460,7 +460,7 @@ func DeleteSecret(c *gin.Context) {
UserId: UserId,
EventText: fmt.Sprintf("Deleted Secret Id %d", s.SecretId),
}
a.AuditAdd()
a.AutidLogAdd()
c.JSON(http.StatusOK, gin.H{"message": "secret deleted successfully"})
} else {

View File

@@ -269,6 +269,7 @@ func main() {
// Other functions for admin
adminOnly.POST("/unlock", controllers.Unlock)
adminOnly.GET("/logs", controllers.GetAuditLogsHandler)
// Get secrets
secretRoutes := router.Group("/api/secret")

View File

@@ -14,8 +14,8 @@ type Audit struct {
EventTime time.Time `db:"EventTime" json:"eventTime"`
}
// AuditAdd adds a new audit record to the database
func (a *Audit) AuditAdd() (*Audit, error) {
// AutidLogAdd adds a new audit record to the database
func (a *Audit) AutidLogAdd() (*Audit, error) {
var err error
// Populate timestamp field if not already set
@@ -26,14 +26,42 @@ func (a *Audit) AuditAdd() (*Audit, error) {
result, err := db.NamedExec(("INSERT INTO audit (UserId, SecretId, EventText, EventTime) VALUES (:UserId, :SecretId, :EventText, :EventTime);"), a)
if err != nil {
log.Printf("AuditAdd error executing sql record : '%s'\n", err)
log.Printf("AutidLogAdd error executing sql record : '%s'\n", err)
return &Audit{}, err
} else {
affected, _ := result.RowsAffected()
id, _ := result.LastInsertId()
a.AuditId = int(id)
log.Printf("AuditAdd insert returned result id '%d' affecting %d row(s).\n", id, affected)
log.Printf("AutidLogAdd insert returned result id '%d' affecting %d row(s).\n", id, affected)
}
return a, nil
}
// AuditList returns a list of all audit logs in database
func AuditLogList() ([]Audit, error) {
var results []Audit
// Query database for groups
rows, err := db.Queryx("SELECT * FROM audit")
if err != nil {
log.Printf("AuditLogList error executing sql record : '%s'\n", err)
return results, err
} else {
// parse all the results into a slice
for rows.Next() {
var a Audit
err = rows.StructScan(&a)
if err != nil {
log.Printf("AuditLogList error parsing sql record : '%s'\n", err)
return results, err
}
results = append(results, a)
}
log.Printf("AuditLogList retrieved '%d' results\n", len(results))
}
return results, nil
}

View File

@@ -261,6 +261,10 @@ func UserLdapNewLoginCheck(username string, password string) (User, error) {
matchFound := false
for _, group := range groupList {
// Skip any groups that aren't LDAP groups
if len(group.LdapDn) == 0 {
continue
}
for _, lg := range ldapGroups {
if group.LdapDn == lg {
log.Printf("Found match with groupname '%s' and LDAP group DN '%s', user is a member of group ID '%d'\n", group.GroupName, group.LdapDn, group.GroupId)