working on the permissions system and groups structure

This commit is contained in:
2025-05-21 22:38:10 -04:00
parent a5ee53a151
commit 8938709a1e
2 changed files with 97 additions and 50 deletions

View File

@ -1,6 +1,7 @@
import wrap, { type WrapResult, ConstEnum, Option } from "./wrap" import wrap, { type WrapResult, ConstEnum, Option } from "./wrap"
import directory_search from "./index" import directory_search from "./index"
import User from "./users"
const enum EntryType { const enum EntryType {
Root, Root,
@ -8,16 +9,10 @@ const enum EntryType {
Directory, Directory,
Binary, Binary,
} }
const enum Permissions {
r = 1<<0,
w = 1<<1,
x = 1<<2,
}
const enum ROOT_ID { const enum ROOT_ID {
TRUNK = "/", TRUNK = "/",
NAME = "root" NAME = "root"
} }
const enum PushStatus { const enum PushStatus {
Ok, Ok,
Duplicate, Duplicate,
@ -28,15 +23,15 @@ const enum ReadStatus {
NotFound, NotFound,
Denied, Denied,
} }
const enum Permissions {
interface UserPermissions { r = 1<<0,
readonly root: Permissions.r | Permissions.w | Permissions.x, //Flip OR w = 1<<1,
[index: string]: Permissions x = 1<<2,
} }
interface Entry<T extends EntryType = EntryType, N = EntryValue<string>> { interface Entry<T extends EntryType = EntryType, N = EntryValue<string>> {
readonly type: T, readonly type: T,
permissions: UserPermissions, owner: User,
timestamp: number, timestamp: number,
name: N name: N
} }

View File

@ -19,39 +19,77 @@ const enum UserMoveStatus {
AlreadyInWheel, AlreadyInWheel,
AlreadyInUsers, AlreadyInUsers,
} }
const enum SettingUser { const enum UserSet {
Ok, Ok,
AlreadyLoggedIn, AlreadyLoggedIn,
UserDoesNotExist UserDoesNotExist
} }
const enum GroupRemoveStatus {
Ok,
RootBlocked,
RemovingNonExistentUser,
}
type Group = User[]
type User_Index = [User, number] type User_Index = [User, number]
type WrapUserSearch = WrapResult<User_Index | undefined, GroupSearch> type WrapUserSearch = WrapResult<User_Index | undefined, GroupSearch>
type WheelAndUsers = Group
interface Groups { interface Groups {
wheel: Group, wheel: Group,
users: Group, users: Group,
together: () => WheelAndUsers together: () => User[]
}
class Group {
protected inner: User[];
private type: SysGroups;
constructor(type: SysGroups) {
this.type = type
this.inner = []
}
public get_type(): SysGroups {
return this.type
}
public get_users(): User[] {
return [...this.inner]
}
public add_user(user: User): void {
this.inner.push(user)
}
public remove_user(user: User): User | undefined {
for (let i = 0; i<this.inner.length; i++) {
if (this.inner[i].get_uname() === user.get_uname()) {
this.inner.splice(i, 1)
return this.inner[i]
}
}
return undefined
}
} }
const groups: Groups = { const groups: Groups = {
wheel: [], wheel: new Group(SysGroups.Wheel),
users: [], users: new Group(SysGroups.Users),
together: function() { together: function() {
return [...this.wheel, ...this.users] return [...this.wheel.get_users(), ...this.users.get_users()]
} }
} }
let uid_count = 0
function wrap_user_search(status: GroupSearch, result?: User_Index): WrapUserSearch { function wrap_user_search(status: GroupSearch, result?: User_Index): WrapUserSearch {
return wrap(result, status) return wrap(result, status)
} }
function group_iter_for_user(uname: string, group_t: Group): User_Index | undefined { function group_iter_for_user(uname: string, group_t: Group): User_Index | undefined {
for (let i = 0; i<group_t.length; i++) { const group_t_users = group_t.get_users()
if (group_t[i].get_uname() === uname) { for (let i = 0; i<group_t_users.length; i++) {
return [group_t[i], i] if (group_t_users[i].get_uname() === uname) {
return [group_t_users[i], i]
} }
} }
return undefined return undefined
@ -72,20 +110,21 @@ function groups_find_user(uname: string): WrapUserSearch {
function group_add(new_user: User, group_t: Group): GroupSearch { function group_add(new_user: User, group_t: Group): GroupSearch {
const dups = groups_find_user(new_user.get_uname()) const dups = groups_find_user(new_user.get_uname())
if (dups.status === GroupSearch.NotFound) { if (dups.status === GroupSearch.NotFound) {
group_t.push(new_user) group_t.add_user(new_user)
} }
return dups.status return dups.status
} }
function group_remove(uname: string, group_t: Group): boolean { function group_remove(uname: string, group_t: Group): GroupRemoveStatus {
if (uname !== ROOT_ID.NAME) { if (uname !== ROOT_ID.NAME) {
const find_user = group_iter_for_user(uname, group_t) const found_user = group_t.get_users().find(user => user.get_uname() === uname)
if (find_user) { if (found_user) {
group_t.splice(find_user[1], 1) group_t.remove_user(found_user)
return true return GroupRemoveStatus.Ok
} }
return GroupRemoveStatus.RemovingNonExistentUser
} }
return false return GroupRemoveStatus.RootBlocked
} }
function group_user_move(uname: string, new_group: SysGroups): UserMoveStatus { function group_user_move(uname: string, new_group: SysGroups): UserMoveStatus {
@ -96,12 +135,12 @@ function group_user_move(uname: string, new_group: SysGroups): UserMoveStatus {
if (new_group === SysGroups.Wheel) { if (new_group === SysGroups.Wheel) {
if (find_in_group.status === GroupSearch.WheelResult) { return UserMoveStatus.AlreadyInWheel } if (find_in_group.status === GroupSearch.WheelResult) { return UserMoveStatus.AlreadyInWheel }
const removed_users_user = groups.users.remove_user((find_in_group.result as User_Index)[0])
groups.wheel.push(groups.users.splice((find_in_group.result as User_Index)[1], 1)[0]) groups.wheel.add_user(removed_users_user as User)
} else if (new_group === SysGroups.Users) { } else if (new_group === SysGroups.Users) {
if (find_in_group.status === GroupSearch.UsersResult) { return UserMoveStatus.AlreadyInUsers } if (find_in_group.status === GroupSearch.UsersResult) { return UserMoveStatus.AlreadyInUsers }
const removed_wheel_user = groups.wheel.remove_user((find_in_group.result as User_Index)[0])
groups.users.push(groups.wheel.splice((find_in_group.result as User_Index)[1], 1)[0]) groups.users.add_user(removed_wheel_user as User)
} }
return UserMoveStatus.Ok return UserMoveStatus.Ok
} }
@ -110,7 +149,7 @@ function group_wheel_add(new_user: User): GroupSearch {
return group_add(new_user, groups.wheel) return group_add(new_user, groups.wheel)
} }
function group_wheel_remove(uname: string): boolean { function group_wheel_remove(uname: string): GroupRemoveStatus {
return group_remove(uname, groups.wheel) return group_remove(uname, groups.wheel)
} }
@ -118,7 +157,7 @@ function group_users_add(new_user: User): GroupSearch {
return group_add(new_user, groups.users) return group_add(new_user, groups.users)
} }
function group_users_remove(uname: string): boolean { function group_users_remove(uname: string): GroupRemoveStatus {
return group_remove(uname, groups.users) return group_remove(uname, groups.users)
} }
@ -129,14 +168,14 @@ class user_lib {
return groups.together().find(user => user.is_logged_in()) as User return groups.together().find(user => user.is_logged_in()) as User
} }
public static set_sys_user(uname: string): SettingUser { public static set_sys_user(uname: string): UserSet {
const found_user = groups_find_user(uname) const found_user = groups_find_user(uname)
const result_user_i = found_user.result const result_user_i = found_user.result
if (!result_user_i) { return SettingUser.UserDoesNotExist } if (!result_user_i) { return UserSet.UserDoesNotExist }
if (result_user_i[0].is_logged_in()) { return SettingUser.AlreadyLoggedIn } if (result_user_i[0].is_logged_in()) { return UserSet.AlreadyLoggedIn }
user_lib.current_sys_user = result_user_i[0] user_lib.current_sys_user = result_user_i[0]
return SettingUser.Ok return UserSet.Ok
} }
} }
@ -144,30 +183,41 @@ class User extends user_lib {
private current: boolean; private current: boolean;
private name: string; private name: string;
private password?: SHA256_String; private password?: SHA256_String;
private uid: number;
constructor(name: string, password?: SHA256_String) { constructor(name: string, password?: SHA256_String) {
super() super()
const root_creation = name === ROOT_ID.NAME
if (root_creation) {
this.uid = 0
} else {
uid_count += 1
this.uid = uid_count
}
this.name = name this.name = name
this.current = name === ROOT_ID.NAME this.current = root_creation
this.password = password this.password = password
} }
public get_uid() {
return this.uid
}
public is_logged_in(): boolean { public is_logged_in(): boolean {
return this.current return this.current
} }
public login(password?: SHA256_String): boolean { public login(password?: SHA256_String): boolean {
if (password !== this.password) { return false } if (password === this.password) {
const other_user = User.get_sys_user()
for (const other_user of groups.together()) {
if (other_user.is_logged_in()) {
other_user.current = false other_user.current = false
this.current = true this.current = true
break User.current_sys_user = this
}
}
return this.current return this.current
} }
return false
}
public get_uname() { public get_uname() {
return this.name return this.name
@ -195,8 +245,10 @@ class User extends user_lib {
} }
groups.wheel.push( groups.wheel.push(
new User(ROOT_ID.NAME), new User(ROOT_ID.NAME, "9025f0dd51ed4f2b2dc2791b6a15eff804555c283bac50d1d8923c18a51f977b")
new User("rhpidfyre", "9025f0dd51ed4f2b2dc2791b6a15eff804555c283bac50d1d8923c18a51f977b") )
groups.users.push(
new User("user")
) )
export default User export default User