working on the permissions system and groups structure
This commit is contained in:
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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,29 +183,40 @@ 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()) {
|
other_user.current = false
|
||||||
if (other_user.is_logged_in()) {
|
this.current = true
|
||||||
other_user.current = false
|
User.current_sys_user = this
|
||||||
this.current = true
|
return this.current
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return this.current
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
public get_uname() {
|
public get_uname() {
|
||||||
@ -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
|
||||||
|
Reference in New Issue
Block a user