test
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2024-01-09 09:51:32 +11:00
parent 20dc745a64
commit dbc2276d68
10 changed files with 223 additions and 186 deletions

View File

@@ -168,44 +168,45 @@ func RegisterUser(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "user registration success"}) c.JSON(http.StatusOK, gin.H{"message": "user registration success"})
} }
func AddRole(c *gin.Context) { /*
var input AddRoleInput func AddRole(c *gin.Context) {
var input AddRoleInput
if err := c.ShouldBindJSON(&input); err != nil { if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return return
}
// define the new role properties
r := models.Role{}
r.RoleName = input.RoleName
r.ReadOnly = input.ReadOnly
r.Admin = input.Admin
r.LdapGroup = input.LdapGroup
// Check if role already exists
testRole, _ := models.GetRoleByName(r.RoleName)
log.Printf("AddRole checking if role '%s' already exists\n", r.RoleName)
if (models.Role{} == testRole) {
log.Printf("AddRole confirmed no existing rolename\n")
} else {
errorString := fmt.Sprintf("attempt to register conflicting rolename '%s'", r.RoleName)
log.Printf("Register error : '%s'\n", errorString)
c.JSON(http.StatusBadRequest, gin.H{"error": errorString})
return
}
_, err := r.AddRole()
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"Error creating role": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "role creation success"})
} }
*/
// define the new role properties
r := models.Role{}
r.RoleName = input.RoleName
r.ReadOnly = input.ReadOnly
r.Admin = input.Admin
r.LdapGroup = input.LdapGroup
// Check if role already exists
testRole, _ := models.GetRoleByName(r.RoleName)
log.Printf("AddRole checking if role '%s' already exists\n", r.RoleName)
if (models.Role{} == testRole) {
log.Printf("AddRole confirmed no existing rolename\n")
} else {
errorString := fmt.Sprintf("attempt to register conflicting rolename '%s'", r.RoleName)
log.Printf("Register error : '%s'\n", errorString)
c.JSON(http.StatusBadRequest, gin.H{"error": errorString})
return
}
_, err := r.AddRole()
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"Error creating role": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "role creation success"})
}
func Login(c *gin.Context) { func Login(c *gin.Context) {
var input LoginInput var input LoginInput
@@ -254,17 +255,18 @@ func CurrentUser(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "success", "data": u}) c.JSON(http.StatusOK, gin.H{"message": "success", "data": u})
} }
func GetRoles(c *gin.Context) { /*
roles, err := models.QueryRoles() func GetRoles(c *gin.Context) {
roles, err := models.QueryRoles()
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return return
}
c.JSON(http.StatusOK, gin.H{"message": "success", "data": roles})
} }
*/
c.JSON(http.StatusOK, gin.H{"message": "success", "data": roles})
}
func GetUsers(c *gin.Context) { func GetUsers(c *gin.Context) {
users, err := models.UserList() users, err := models.UserList()

View File

@@ -4,7 +4,6 @@ import (
"log" "log"
"net/http" "net/http"
"smt/models" "smt/models"
"smt/utils/token"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
@@ -165,12 +164,14 @@ func retrieveSpecifiedSecret(s *models.Secret, c *gin.Context) {
*/ */
var results []models.Secret var results []models.Secret
var userIsAdmin = false /*
user_id, err := token.ExtractTokenID(c) user_id, err := token.ExtractTokenID(c)
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "error determining user"}) c.JSON(http.StatusBadRequest, gin.H{"error": "error determining user"})
return return
} }
*/
user_id := c.GetInt("user-id")
// Work out which safe to query for this user if the safe was not specified // Work out which safe to query for this user if the safe was not specified
safeList, err := models.UserGetSafesAllowed(int(user_id)) safeList, err := models.UserGetSafesAllowed(int(user_id))
@@ -182,21 +183,13 @@ func retrieveSpecifiedSecret(s *models.Secret, c *gin.Context) {
// If there was only one result then just use that // If there was only one result then just use that
if len(safeList) == 0 { if len(safeList) == 0 {
// check if the user is an admin, if not then they seem to have access to zero safes errString := "no matching secret or user has no access to specified secret"
if !models.UserCheckIfAdmin(int(user_id)) { log.Printf("retrieveSpecifiedSecret %s\n", errString)
c.JSON(http.StatusBadRequest, gin.H{"error": "user has no access to any secrets"}) c.JSON(http.StatusBadRequest, gin.H{"error": errString})
return return
} else {
// Don't apply a role filter if user has admin role
results, err = models.SecretsGetMultipleSafes(s, true, []int{})
}
} else if len(safeList) == 1 { } else if len(safeList) == 1 {
s.SafeId = safeList[0].SafeId s.SafeId = safeList[0].SafeId
userIsAdmin = safeList[0].AdminUser || safeList[0].AdminGroup results, err = models.SecretsGetMultipleSafes(s, []int{s.SafeId})
// Don't apply a role filter if user has admin role
//results, err = models.GetSecrets(&s, userIsAdmin)
results, err = models.SecretsGetMultipleSafes(s, userIsAdmin, []int{s.SafeId})
} else { } else {
// Create a list of all the safes this user can access // Create a list of all the safes this user can access
var safeIds []int var safeIds []int
@@ -204,7 +197,7 @@ func retrieveSpecifiedSecret(s *models.Secret, c *gin.Context) {
safeIds = append(safeIds, safe.SafeId) safeIds = append(safeIds, safe.SafeId)
} }
results, err = models.SecretsGetMultipleSafes(s, false, safeIds) results, err = models.SecretsGetMultipleSafes(s, safeIds)
} }
if err != nil { if err != nil {
@@ -250,12 +243,8 @@ func ListSecrets(c *gin.Context) {
*/ */
var results []models.Secret var results []models.Secret
var userIsAdmin = false s := models.Secret{}
user_id, err := token.ExtractTokenID(c) user_id := c.GetInt("user-id")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "error determining user"})
return
}
// Work out which safe to query for this user if the safe was not specified // Work out which safe to query for this user if the safe was not specified
safeList, err := models.UserGetSafesAllowed(int(user_id)) safeList, err := models.UserGetSafesAllowed(int(user_id))
@@ -267,18 +256,13 @@ func ListSecrets(c *gin.Context) {
// If there was only one result then just use that // If there was only one result then just use that
if len(safeList) == 0 { if len(safeList) == 0 {
// check if the user is an admin, if not then they seem to have access to zero safes errString := "no matching secret or user has no access to specified secret"
if !models.UserCheckIfAdmin(int(user_id)) { log.Printf("ListSecrets %s\n", errString)
c.JSON(http.StatusBadRequest, gin.H{"error": "user has no access to any secrets"}) c.JSON(http.StatusBadRequest, gin.H{"error": errString})
return return
} else {
// Don't apply a role filter if user has admin role
results, err = models.SecretsGetMultipleSafes(&models.Secret{}, true, []int{})
}
} else if len(safeList) == 1 { } else if len(safeList) == 1 {
userIsAdmin = safeList[0].AdminUser || safeList[0].AdminGroup s.SafeId = safeList[0].SafeId
results, err = models.SecretsGetMultipleSafes(&models.Secret{}, userIsAdmin, []int{safeList[0].SafeId}) results, err = models.SecretsGetMultipleSafes(&s, []int{s.SafeId})
} else { } else {
// Create a list of all the safes this user can access // Create a list of all the safes this user can access
var safeIds []int var safeIds []int
@@ -286,7 +270,7 @@ func ListSecrets(c *gin.Context) {
safeIds = append(safeIds, safe.SafeId) safeIds = append(safeIds, safe.SafeId)
} }
results, err = models.SecretsGetMultipleSafes(&models.Secret{}, false, safeIds) results, err = models.SecretsGetMultipleSafes(&s, safeIds)
} }
if err != nil { if err != nil {

View File

@@ -111,6 +111,23 @@ func StoreSecret(c *gin.Context) {
// CheckUpdateSecretAllowed checks to see if a user has access to the specified secret. If so, the corresponding SafeId is returned // CheckUpdateSecretAllowed checks to see if a user has access to the specified secret. If so, the corresponding SafeId is returned
func CheckUpdateSecretAllowed(s *models.Secret, user_id int) (int, error) { func CheckUpdateSecretAllowed(s *models.Secret, user_id int) (int, error) {
// If user has Admin access then perform update
// If user has normal access to the safe the secret is stored in then perform update
// If matching secret is found in multiple safes then generate error
// If user doesn't have access to the safe the matching secret is in then generate error
// NO. That is too complicated!
// Lets try to make this more simple
// A user can only be in one group
// A group can have permissions on multiple safes
// If a user is an admin they can do user related functions like create users, groups, assign permissions
// But a user has to have a permission that maps the group to the safe in order to perform CRUD operations
// What does a group being an admin give them? All users in that group can do user related function
// Query all safes for secrets matching parameters specified // Query all safes for secrets matching parameters specified
matchingSecrets, err := models.SecretsSearchAllSafes(s) matchingSecrets, err := models.SecretsSearchAllSafes(s)
if err != nil { if err != nil {
@@ -133,14 +150,7 @@ func CheckUpdateSecretAllowed(s *models.Secret, user_id int) (int, error) {
return 0, errors.New(errString) return 0, errors.New(errString)
} else if len(matchingSecrets) == 1 { } else if len(matchingSecrets) == 1 {
log.Printf("CheckUpdateSecretAllowed found a single matching secret :\n'%+v'\n", matchingSecrets[0]) log.Printf("CheckUpdateSecretAllowed found a single matching secret :\n'%+v'\n", matchingSecrets[0])
// Check if user is admin
for _, val := range userSafes {
if val.User.Admin || val.AdminGroup {
return matchingSecrets[0].SafeId, nil
}
}
// If we reach here then user is not admin
// Check to see user is allowed to access the safe holding the secret // Check to see user is allowed to access the safe holding the secret
for _, secret := range matchingSecrets { for _, secret := range matchingSecrets {
for _, user := range userSafes { for _, user := range userSafes {
@@ -167,19 +177,6 @@ func CheckUpdateSecretAllowed(s *models.Secret, user_id int) (int, error) {
return 0, errors.New(errString) return 0, errors.New(errString)
} }
} }
if user.User.Admin || user.AdminGroup {
log.Printf("CheckUpdateSecretAllowed found user to be admin, assuming SafeId '%d'\n", user.SafeId)
if !matchFound {
matchFound = true
matchingSafeId = user.SafeId
} else {
// Found more than one applicable secret, how do we know which one to update?
errString := "CheckUpdateSecretAllowed found multiple secrets matching supplied parameters, supply more specific parameters"
log.Println(errString)
return 0, errors.New(errString)
}
}
} }
} }
@@ -213,11 +210,14 @@ func UpdateSecret(c *gin.Context) {
} }
*/ */
user_id, err := token.ExtractTokenID(c) /*
if err != nil { user_id, err := token.ExtractTokenID(c)
c.JSON(http.StatusBadRequest, gin.H{"error": "error determining user"}) if err != nil {
return c.JSON(http.StatusBadRequest, gin.H{"error": "error determining user"})
} return
}
*/
user_id := c.GetInt("user-id")
// Populate fields // Populate fields
s := models.Secret{} s := models.Secret{}
@@ -226,6 +226,15 @@ func UpdateSecret(c *gin.Context) {
s.DeviceName = input.DeviceName s.DeviceName = input.DeviceName
s.DeviceCategory = input.DeviceCategory s.DeviceCategory = input.DeviceCategory
// TODO:
// Get a list of matching secrets - SecretsSearchAllSafes
//secretList, err := models.SecretsSearchAllSafes(&s)
// Check if user has access to the safes containing those secrets - something like UserGetSafesAllowed but not quite
//allowedSafes, err := models.UserGetSafesAllowed(user_id)
// Make sure that the access is not readonly
// If user has access to more than one safe containing the secret, generate an error
// Otherwise, update the secret
allowedUpdate, err := CheckUpdateSecretAllowed(&s, int(user_id)) allowedUpdate, err := CheckUpdateSecretAllowed(&s, int(user_id))
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("error determining secret : '%s'", err)}) c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("error determining secret : '%s'", err)})
@@ -236,11 +245,6 @@ func UpdateSecret(c *gin.Context) {
s.SafeId = allowedUpdate s.SafeId = allowedUpdate
} }
// If user has Admin access then perform update
// If user has normal access to the safe the secret is stored in then perform update
// If matching secret is found in multiple safes then generate error
// If user doesn't have access to the safe the matching secret is in then generate error
// Query which safes the current user is allowed to access // Query which safes the current user is allowed to access
/* /*
@@ -319,10 +323,8 @@ func SecretCheckSafeAllowed(user_id int, input StoreInput) int {
return safe.SafeId return safe.SafeId
} else if input.SafeId > 0 && safe.SafeId == input.SafeId { // Safe specified by id } else if input.SafeId > 0 && safe.SafeId == input.SafeId { // Safe specified by id
return safe.SafeId return safe.SafeId
} else if safe.User.Admin || safe.AdminGroup { // User has admin role so they're allowed this safe anyway
return safe.SafeId
} else { } else {
log.Printf("SecretCheckSafeAllowed ") log.Printf("SecretCheckSafeAllowed unexpected\n")
} }
} }

View File

@@ -246,11 +246,13 @@ func main() {
adminOnly.POST("/user/add", controllers.RegisterUser) adminOnly.POST("/user/add", controllers.RegisterUser)
// TODO // TODO
//adminOnly.POST("/user/update", controllers.UpdateUser) //adminOnly.POST("/user/update", controllers.UpdateUser)
adminOnly.GET("/roles", controllers.GetRoles)
adminOnly.POST("/role/add", controllers.AddRole)
adminOnly.GET("/users", controllers.GetUsers) adminOnly.GET("/users", controllers.GetUsers)
adminOnly.POST("/unlock", controllers.Unlock) adminOnly.POST("/unlock", controllers.Unlock)
// Deprecated
//adminOnly.GET("/roles", controllers.GetRoles)
//adminOnly.POST("/role/add", controllers.AddRole)
// Get secrets // Get secrets
protected := router.Group("/api/secret") protected := router.Group("/api/secret")
protected.Use(middlewares.JwtAuthMiddleware()) protected.Use(middlewares.JwtAuthMiddleware())

View File

@@ -19,6 +19,19 @@ func JwtAuthMiddleware() gin.HandlerFunc {
c.Abort() c.Abort()
return return
} }
// Token is valid, extract user_id
user_id, err := token.ExtractTokenID(c)
if err != nil {
log.Printf("JwtAuthMiddleware user_id could not be parsed : '%s'\n", err)
c.String(http.StatusUnauthorized, "Unauthorized")
c.Abort()
return
}
// Store user id in context for accessing later
log.Printf("JwtAuthMiddleware storing user-id '%d'\n", user_id)
c.Set("user-id", user_id)
c.Next() c.Next()
} }
} }

View File

@@ -111,7 +111,7 @@ func SecretsSearchAllSafes(s *Secret) ([]Secret, error) {
} }
// SecretsGetMultipleSafes queries the specified safes for matching secrets // SecretsGetMultipleSafes queries the specified safes for matching secrets
func SecretsGetMultipleSafes(s *Secret, adminRole bool, safeIds []int) ([]Secret, error) { func SecretsGetMultipleSafes(s *Secret, safeIds []int) ([]Secret, error) {
var err error var err error
var secretResults []Secret var secretResults []Secret
@@ -130,25 +130,19 @@ func SecretsGetMultipleSafes(s *Secret, adminRole bool, safeIds []int) ([]Secret
args := []interface{}{} args := []interface{}{}
var query string var query string
if adminRole { // Generate placeholders for the IN clause to match multiple SafeId values
log.Printf("SecretsGetMultipleSafes using admin role so not limiting to specific safes\n") placeholders := make([]string, len(safeIds))
// No need to limit query to any safe for i := range safeIds {
query = "SELECT * FROM secrets WHERE 1=1 " placeholders[i] = "?"
} else { }
// Generate placeholders for the IN clause to match multiple SafeId values placeholderStr := strings.Join(placeholders, ",")
placeholders := make([]string, len(safeIds))
for i := range safeIds {
placeholders[i] = "?"
}
placeholderStr := strings.Join(placeholders, ",")
// Create query with the necessary placeholders // Create query with the necessary placeholders
query = fmt.Sprintf("SELECT * FROM secrets WHERE SafeId IN (%s) ", placeholderStr) query = fmt.Sprintf("SELECT * FROM secrets WHERE SafeId IN (%s) ", placeholderStr)
// Add the Safe Ids to the arguments list // Add the Safe Ids to the arguments list
for _, g := range safeIds { for _, g := range safeIds {
args = append(args, g) args = append(args, g)
}
} }
// Add any other arguments to the query if they were specified // Add any other arguments to the query if they were specified

View File

@@ -20,8 +20,7 @@ const (
sqlFile = "smt.db" sqlFile = "smt.db"
) )
// TODO drop LdapGroup column /*
const createRoles string = ` const createRoles string = `
CREATE TABLE IF NOT EXISTS roles ( CREATE TABLE IF NOT EXISTS roles (
RoleId INTEGER PRIMARY KEY ASC, RoleId INTEGER PRIMARY KEY ASC,
@@ -29,6 +28,7 @@ const createRoles string = `
ReadOnly BOOLEAN ReadOnly BOOLEAN
); );
` `
*/
const createUsers string = ` const createUsers string = `
CREATE TABLE IF NOT EXISTS users ( CREATE TABLE IF NOT EXISTS users (
@@ -62,11 +62,11 @@ const createGroups string = `
const createPermissions = ` const createPermissions = `
CREATE TABLE IF NOT EXISTS permissions ( CREATE TABLE IF NOT EXISTS permissions (
PermissionId INTEGER PRIMARY KEY ASC, PermissionId INTEGER PRIMARY KEY ASC,
RoleId INTEGER, Description VARCHAR DEFAULT '',
ReadOnly BOOLEAN DEFAULT 0,
SafeId INTEGER, SafeId INTEGER,
UserId INTEGER, UserId INTEGER,
GroupId INTEGER, GroupId INTEGER,
FOREIGN KEY (RoleId) REFERENCES roles(RoleId),
FOREIGN KEY (SafeId) REFERENCES safes(SafeId), FOREIGN KEY (SafeId) REFERENCES safes(SafeId),
FOREIGN KEY (UserId) REFERENCES users(UserId), FOREIGN KEY (UserId) REFERENCES users(UserId),
FOREIGN KEY (GroupId) REFERENCES groups(GroupId) FOREIGN KEY (GroupId) REFERENCES groups(GroupId)
@@ -131,23 +131,44 @@ func CreateTables() {
var err error var err error
var rowCount int var rowCount int
// Create database tables if it doesn't exist // Create database tables if it doesn't exist
// Roles table should go first since other tables refer to it /*
if _, err = db.Exec(createRoles); err != nil { // Roles table should go first since other tables refer to it
log.Printf("Error checking roles table : '%s'", err) if _, err = db.Exec(createRoles); err != nil {
log.Printf("Error checking roles table : '%s'", err)
os.Exit(1)
}
rowCount, _ = CheckCount("roles")
if rowCount == 0 {
if _, err = db.Exec("INSERT INTO roles VALUES(1, 'Admin', false);"); err != nil {
log.Printf("Error adding initial admin role : '%s'", err)
os.Exit(1)
}
if _, err = db.Exec("INSERT INTO roles VALUES(2, 'UserRole', false);"); err != nil {
log.Printf("Error adding initial user role : '%s'", err)
os.Exit(1)
}
if _, err = db.Exec("INSERT INTO roles VALUES(3, 'GuestRole', true);"); err != nil {
log.Printf("Error adding initial guest role : '%s'", err)
os.Exit(1)
}
}
*/
// groups table
if _, err = db.Exec(createGroups); err != nil {
log.Printf("Error checking groups table : '%s'", err)
os.Exit(1) os.Exit(1)
} }
rowCount, _ = CheckCount("roles")
// Add initial groups
rowCount, _ = CheckCount("groups")
if rowCount == 0 { if rowCount == 0 {
if _, err = db.Exec("INSERT INTO roles VALUES(1, 'Admin', false);"); err != nil { if _, err = db.Exec("INSERT INTO groups (GroupId, GroupName, Admin) VALUES(1, 'Administrators', 1);"); err != nil {
log.Printf("Error adding initial admin role : '%s'", err) log.Printf("Error adding initial group entry id 1 : '%s'", err)
os.Exit(1) os.Exit(1)
} }
if _, err = db.Exec("INSERT INTO roles VALUES(2, 'UserRole', false);"); err != nil { if _, err = db.Exec("INSERT INTO groups (GroupId, GroupName, Admin) VALUES(2, 'Users', 0);"); err != nil {
log.Printf("Error adding initial user role : '%s'", err) log.Printf("Error adding initial group entry id 2 : '%s'", err)
os.Exit(1)
}
if _, err = db.Exec("INSERT INTO roles VALUES(3, 'GuestRole', true);"); err != nil {
log.Printf("Error adding initial guest role : '%s'", err)
os.Exit(1) os.Exit(1)
} }
} }
@@ -169,7 +190,11 @@ func CreateTables() {
cryptText, _ := bcrypt.GenerateFromPassword([]byte(initialPassword), bcrypt.DefaultCost) cryptText, _ := bcrypt.GenerateFromPassword([]byte(initialPassword), bcrypt.DefaultCost)
initialPassword = string(cryptText) initialPassword = string(cryptText)
} }
if _, err = db.Exec("INSERT INTO users (RoleId, UserName, Password, LdapUser) VALUES(1, 1, 'Administrator', ?, 0);", initialPassword); err != nil { if _, err = db.Exec("INSERT INTO users (UserId, GroupId, UserName, Password, LdapUser, Admin) VALUES(1, 1, 'Administrator', ?, false, true);", initialPassword); err != nil {
log.Printf("Error adding initial admin role : '%s'", err)
os.Exit(1)
}
if _, err = db.Exec("INSERT INTO users (UserId, GroupId, UserName, Password, LdapUser, Admin) VALUES(2, 2, 'User', ?, false, false);", initialPassword); err != nil {
log.Printf("Error adding initial admin role : '%s'", err) log.Printf("Error adding initial admin role : '%s'", err)
os.Exit(1) os.Exit(1)
} }
@@ -201,46 +226,23 @@ func CreateTables() {
os.Exit(1) os.Exit(1)
} }
// groups table
if _, err = db.Exec(createGroups); err != nil {
log.Printf("Error checking groups table : '%s'", err)
os.Exit(1)
}
// permissions table // permissions table
if _, err = db.Exec(createPermissions); err != nil { if _, err = db.Exec(createPermissions); err != nil {
log.Printf("Error checking permissions table : '%s'", err) log.Printf("Error checking permissions table : '%s'", err)
os.Exit(1) os.Exit(1)
} }
// Add initial groups
rowCount, _ = CheckCount("groups")
if rowCount == 0 {
if _, err = db.Exec("INSERT INTO groups (GroupId, GroupName, Admin) VALUES(1, 'Administrators', 1);"); err != nil {
log.Printf("Error adding initial group entry id 1 : '%s'", err)
os.Exit(1)
}
if _, err = db.Exec("INSERT INTO groups (GroupId, GroupName, Admin) VALUES(2, 'Users', 0);"); err != nil {
log.Printf("Error adding initial group entry id 2 : '%s'", err)
os.Exit(1)
}
}
// Add initial permissions // Add initial permissions
rowCount, _ = CheckCount("permissions") rowCount, _ = CheckCount("permissions")
if rowCount == 0 { if rowCount == 0 {
if _, err = db.Exec("INSERT INTO permissions (RoleId, SafeId, UserId) VALUES(1, 1, 1);"); err != nil { if _, err = db.Exec("INSERT INTO permissions (Description, ReadOnly, GroupId, SafeId) VALUES('Default Admin Group Permission', false, 1, 1);"); err != nil {
log.Printf("Error adding initial permissions entry userid 1 : '%s'", err) log.Printf("Error adding initial permissions entry userid 1 : '%s'", err)
os.Exit(1) os.Exit(1)
} }
if _, err = db.Exec("INSERT INTO permissions (RoleId, SafeId, UserId) VALUES(1, 1, 2);"); err != nil { if _, err = db.Exec("INSERT INTO permissions (Description, ReadOnly, SafeId, GroupId) VALUES('Default User Group Permission', false, 1, 2);"); err != nil {
log.Printf("Error adding initial permissions entry userid 2 : '%s'", err) log.Printf("Error adding initial permissions entry userid 2 : '%s'", err)
os.Exit(1) os.Exit(1)
} }
if _, err = db.Exec("INSERT INTO permissions (RoleId, SafeId, UserId) VALUES(1, 1, 3);"); err != nil {
log.Printf("Error adding initial permissions entry userid 3 : '%s'", err)
os.Exit(1)
}
} }
// Schema table should go last so we know if the database has a value in the schema table then everything was created properly // Schema table should go last so we know if the database has a value in the schema table then everything was created properly
@@ -326,7 +328,7 @@ func CreateTables() {
DROP TABLE _secrets_old; DROP TABLE _secrets_old;
`) `)
if err != nil { if err != nil {
log.Printf("Error altering secrets table to renmove RoleId column : '%s'\n", err) log.Printf("Error altering secrets table to remove RoleId column : '%s'\n", err)
os.Exit(1) os.Exit(1)
} }
} }
@@ -342,6 +344,47 @@ func CreateTables() {
} }
} }
// Remove the Admin column from roles table
rolesAdminCheck, _ := CheckColumnExists("roles", "Admin")
if rolesAdminCheck {
_, err := db.Exec("ALTER TABLE roles DROP COLUMN Admin;")
if err != nil {
log.Printf("Error altering roles table to remove Admin column : '%s'\n", err)
os.Exit(1)
}
}
// Remove the RoleId from permissiosn table
permissionsRoleIdCheck, _ := CheckColumnExists("permissions", "RoleId")
if permissionsRoleIdCheck {
_, err := db.Exec(`
PRAGMA foreign_keys=off;
BEGIN TRANSACTION;
ALTER TABLE permissions RENAME TO _permissions_old;
CREATE TABLE permissions
(
PermissionId INTEGER PRIMARY KEY ASC,
Description VARCHAR DEFAULT '',
ReadOnly BOOLEAN DEFAULT 0,
SafeId INTEGER,
UserId INTEGER,
GroupId INTEGER,
FOREIGN KEY (SafeId) REFERENCES safes(SafeId),
FOREIGN KEY (UserId) REFERENCES users(UserId),
FOREIGN KEY (GroupId) REFERENCES groups(GroupId)
);
INSERT INTO permissions SELECT * FROM _permissions_old;
ALTER TABLE permissions DROP COLUMN RoleId;
COMMIT;
PRAGMA foreign_keys=on;
DROP TABLE _permissions_old;
`)
if err != nil {
log.Printf("Error altering permissions table to remove RoleId column : '%s'\n", err)
os.Exit(1)
}
}
/* /*
// Database updates added after initial version released // Database updates added after initial version released
ldapCheck, _ := CheckColumnExists("roles", "LdapGroup") ldapCheck, _ := CheckColumnExists("roles", "LdapGroup")

View File

@@ -37,11 +37,9 @@ type UserGroup struct {
type UserSafe struct { type UserSafe struct {
User User
AdminUser bool `db:"AdminUser"` SafeId int `db:"SafeId"`
AdminGroup bool `db:"AdminGroup"` SafeName string `db:"SafeName"`
SafeId int `db:"SafeId"` GroupId int `db:"GroupId"`
SafeName string `db:"SafeName"`
GroupId int `db:"GroupId"`
} }
func (u *User) SaveUser() (*User, error) { func (u *User) SaveUser() (*User, error) {
@@ -360,7 +358,6 @@ func UserGetSafesAllowed(userId int) ([]UserSafe, error) {
// join users, groups and permissions // join users, groups and permissions
rows, err := db.Queryx(` rows, err := db.Queryx(`
SELECT users.UserId, users.GroupId, SELECT users.UserId, users.GroupId,
groups.Admin as AdminGroup,
permissions.SafeId, safes.SafeName FROM users permissions.SafeId, safes.SafeName FROM users
INNER JOIN groups ON users.GroupId = groups.GroupId INNER JOIN groups ON users.GroupId = groups.GroupId
INNER JOIN permissions ON groups.GroupId = permissions.GroupId INNER JOIN permissions ON groups.GroupId = permissions.GroupId

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 78 KiB