feat: enhance LDAP integration with new configuration options and browsing capabilities
This commit is contained in:
@@ -51,8 +51,36 @@ func (d *DB) init() error {
|
||||
username TEXT NOT NULL UNIQUE,
|
||||
pass_hash TEXT NOT NULL,
|
||||
role TEXT NOT NULL DEFAULT 'user',
|
||||
is_ldap BOOLEAN NOT NULL DEFAULT 0,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS groups (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL UNIQUE,
|
||||
is_ldap BOOLEAN NOT NULL DEFAULT 0,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS user_groups (
|
||||
user_id INTEGER NOT NULL,
|
||||
group_id INTEGER NOT NULL,
|
||||
PRIMARY KEY(user_id, group_id),
|
||||
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY(group_id) REFERENCES groups(id) ON DELETE CASCADE
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS acl (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
path TEXT NOT NULL,
|
||||
subject_type TEXT NOT NULL CHECK(subject_type IN ('user', 'group')),
|
||||
subject_id INTEGER NOT NULL,
|
||||
can_search BOOLEAN NOT NULL DEFAULT 0,
|
||||
can_view BOOLEAN NOT NULL DEFAULT 0,
|
||||
can_read BOOLEAN NOT NULL DEFAULT 0,
|
||||
can_edit BOOLEAN NOT NULL DEFAULT 0,
|
||||
can_create BOOLEAN NOT NULL DEFAULT 0,
|
||||
can_delete BOOLEAN NOT NULL DEFAULT 0,
|
||||
can_move BOOLEAN NOT NULL DEFAULT 0,
|
||||
UNIQUE(path, subject_type, subject_id)
|
||||
);
|
||||
`)
|
||||
return err
|
||||
}
|
||||
@@ -153,3 +181,96 @@ func (d *DB) UserCount() (int, error) {
|
||||
err := d.sql.QueryRow(`SELECT COUNT(*) FROM users`).Scan(&n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
// --- LDAP & Roles ---
|
||||
|
||||
// CreateOrUpdateLDAPUser inserts or updates an LDAP user (without password, role='user').
|
||||
func (d *DB) CreateOrUpdateLDAPUser(username string) error {
|
||||
_, err := d.sql.Exec(`
|
||||
INSERT INTO users (username, pass_hash, role, is_ldap)
|
||||
VALUES (?, '', 'user', 1)
|
||||
ON CONFLICT(username) DO UPDATE SET is_ldap=1;
|
||||
`, username)
|
||||
return err
|
||||
}
|
||||
|
||||
// CreateOrUpdateGroup inserts or updates a group (local or LDAP).
|
||||
func (d *DB) CreateOrUpdateGroup(name string, isLdap bool) error {
|
||||
ldVal := 0
|
||||
if isLdap {
|
||||
ldVal = 1
|
||||
}
|
||||
_, err := d.sql.Exec(`
|
||||
INSERT INTO groups (name, is_ldap)
|
||||
VALUES (?, ?)
|
||||
ON CONFLICT(name) DO UPDATE SET is_ldap=excluded.is_ldap;
|
||||
`, name, ldVal)
|
||||
return err
|
||||
}
|
||||
|
||||
// --- ACL Methods ---
|
||||
|
||||
type ACLEntry struct {
|
||||
ID int64
|
||||
Path string
|
||||
SubjectType string
|
||||
SubjectID int64
|
||||
CanSearch bool
|
||||
CanView bool
|
||||
CanRead bool
|
||||
CanEdit bool
|
||||
CanCreate bool
|
||||
CanDelete bool
|
||||
CanMove bool
|
||||
}
|
||||
|
||||
// SetACL inserts or replaces an ACL entry.
|
||||
func (d *DB) SetACL(entry ACLEntry) error {
|
||||
_, err := d.sql.Exec(`
|
||||
INSERT INTO acl (path, subject_type, subject_id, can_search, can_view, can_read, can_edit, can_create, can_delete, can_move)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT(path, subject_type, subject_id) DO UPDATE SET
|
||||
can_search = excluded.can_search,
|
||||
can_view = excluded.can_view,
|
||||
can_read = excluded.can_read,
|
||||
can_edit = excluded.can_edit,
|
||||
can_create = excluded.can_create,
|
||||
can_delete = excluded.can_delete,
|
||||
can_move = excluded.can_move;
|
||||
`, entry.Path, entry.SubjectType, entry.SubjectID,
|
||||
entry.CanSearch, entry.CanView, entry.CanRead, entry.CanEdit,
|
||||
entry.CanCreate, entry.CanDelete, entry.CanMove)
|
||||
return err
|
||||
}
|
||||
|
||||
// RemoveACL deletes an ACL entry by ID.
|
||||
func (d *DB) RemoveACL(id int64) error {
|
||||
_, err := d.sql.Exec(`DELETE FROM acl WHERE id = ?`, id)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetACLsForPath retrieves all ACL definitions for a specific document or folder.
|
||||
func (d *DB) GetACLsForPath(path string) ([]ACLEntry, error) {
|
||||
rows, err := d.sql.Query(`
|
||||
SELECT id, path, subject_type, subject_id, can_search, can_view, can_read, can_edit, can_create, can_delete, can_move
|
||||
FROM acl WHERE path = ?
|
||||
`, path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var entries []ACLEntry
|
||||
for rows.Next() {
|
||||
var e ACLEntry
|
||||
if err := rows.Scan(
|
||||
&e.ID, &e.Path, &e.SubjectType, &e.SubjectID,
|
||||
&e.CanSearch, &e.CanView, &e.CanRead, &e.CanEdit,
|
||||
&e.CanCreate, &e.CanDelete, &e.CanMove,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
entries = append(entries, e)
|
||||
}
|
||||
return entries, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user