Schema: add roles tables

This commit is contained in:
Alexander A. Klimov 2024-04-10 14:59:22 +02:00
parent acf8795d70
commit d14a2f6958
9 changed files with 481 additions and 4 deletions

View File

@ -0,0 +1,79 @@
<?php
/* Icinga Web 2 | (c) 2024 Icinga GmbH | GPLv2+ */
namespace Icinga\Model;
use DateTime;
use ipl\Orm\Behavior\BoolCast;
use ipl\Orm\Behavior\MillisecondTimestamp;
use ipl\Orm\Behaviors;
use ipl\Orm\Model;
use ipl\Orm\Relations;
/**
* A database model for Icinga Web role table
*
* @property int $id Unique identifier
* @property ?int $parent_id Inherited role identifier (optional)
* @property string $name Unique name
* @property bool $unrestricted Whether restrictions don't apply
* @property DateTime $ctime The insert time
* @property ?DateTime $mtime The modification time (optional)
* @property ?Role $parent Inherited role (optional)
* @property Role[] $children Inheriting roles
* @property RoleUser[] $users Users this role applies to
* @property RoleGroup[] $groups Groups this role applies to
* @property RolePermission[] $permissions Permissions this role allows/denies
* @property RoleRestriction[] $restrictions Restrictions this role imposes
*/
class Role extends Model
{
public function getTableName(): string
{
return 'icingaweb_role';
}
public function getKeyName(): string
{
return 'id';
}
public function getColumns(): array
{
return ['parent_id', 'name', 'unrestricted', 'ctime', 'mtime'];
}
public function createBehaviors(Behaviors $behaviors): void
{
$behaviors->add(new BoolCast(['unrestricted']));
$behaviors->add(new MillisecondTimestamp(['ctime', 'mtime']));
}
public function createRelations(Relations $relations): void
{
$relations->belongsTo('parent', self::class)
->setCandidateKey('parent_id')
->setJoinType('LEFT');
$relations->hasMany('children', self::class)
->setForeignKey('parent_id')
->setJoinType('LEFT');
$relations->hasMany('users', RoleUser::class)
->setForeignKey('role_id')
->setJoinType('LEFT');
$relations->hasMany('groups', RoleGroup::class)
->setForeignKey('role_id')
->setJoinType('LEFT');
$relations->hasMany('permissions', RolePermission::class)
->setForeignKey('role_id')
->setJoinType('LEFT');
$relations->hasMany('restrictions', RoleRestriction::class)
->setForeignKey('role_id')
->setJoinType('LEFT');
}
}

View File

@ -0,0 +1,40 @@
<?php
/* Icinga Web 2 | (c) 2024 Icinga GmbH | GPLv2+ */
namespace Icinga\Model;
use ipl\Orm\Model;
use ipl\Orm\Relations;
/**
* A database model for Icinga Web role-group table
*
* @property int $role_id Role identifier
* @property string $group_name Group name
* @property Role $role Role object
*/
class RoleGroup extends Model
{
public function getTableName(): string
{
return 'icingaweb_role_group';
}
public function getKeyName(): array
{
return ['group_name', 'role_id'];
}
public function getColumns(): array
{
return [];
}
public function createRelations(Relations $relations): void
{
$relations->belongsTo('icingaweb_role', Role::class) // TODO(ak): make 'role' working
->setCandidateKey('role_id')
->setJoinType('INNER');
}
}

View File

@ -0,0 +1,49 @@
<?php
/* Icinga Web 2 | (c) 2024 Icinga GmbH | GPLv2+ */
namespace Icinga\Model;
use ipl\Orm\Behavior\BoolCast;
use ipl\Orm\Behaviors;
use ipl\Orm\Model;
use ipl\Orm\Relations;
/**
* A database model for Icinga Web role-permission table
*
* @property int $role_id Role identifier
* @property string $permission Permission name
* @property bool $allowed Whether the permission is allowed
* @property bool $denied Whether the permission is denied
* @property Role $role Role object
*/
class RolePermission extends Model
{
public function getTableName(): string
{
return 'icingaweb_role_permission';
}
public function getKeyName(): array
{
return ['role_id', 'permission'];
}
public function getColumns(): array
{
return ['allowed', 'denied'];
}
public function createBehaviors(Behaviors $behaviors): void
{
$behaviors->add(new BoolCast(['allowed', 'denied']));
}
public function createRelations(Relations $relations): void
{
$relations->belongsTo('icingaweb_role', Role::class) // TODO(ak): make 'role' working
->setCandidateKey('role_id')
->setJoinType('INNER');
}
}

View File

@ -0,0 +1,41 @@
<?php
/* Icinga Web 2 | (c) 2024 Icinga GmbH | GPLv2+ */
namespace Icinga\Model;
use ipl\Orm\Model;
use ipl\Orm\Relations;
/**
* A database model for Icinga Web role-restriction table
*
* @property int $role_id Role identifier
* @property string $restriction Restriction name
* @property string $filter Filter of things the role is restricted to
* @property Role $role Role object
*/
class RoleRestriction extends Model
{
public function getTableName(): string
{
return 'icingaweb_role_restriction';
}
public function getKeyName(): array
{
return ['role_id', 'restriction'];
}
public function getColumns(): array
{
return ['filter'];
}
public function createRelations(Relations $relations): void
{
$relations->belongsTo('icingaweb_role', Role::class) // TODO(ak): make 'role' working
->setCandidateKey('role_id')
->setJoinType('INNER');
}
}

View File

@ -0,0 +1,40 @@
<?php
/* Icinga Web 2 | (c) 2024 Icinga GmbH | GPLv2+ */
namespace Icinga\Model;
use ipl\Orm\Model;
use ipl\Orm\Relations;
/**
* A database model for Icinga Web role-user table
*
* @property int $role_id Role identifier
* @property string $user_name User name
* @property Role $role Role object
*/
class RoleUser extends Model
{
public function getTableName(): string
{
return 'icingaweb_role_user';
}
public function getKeyName(): array
{
return ['user_name', 'role_id'];
}
public function getColumns(): array
{
return [];
}
public function createRelations(Relations $relations): void
{
$relations->belongsTo('icingaweb_role', Role::class) // TODO(ak): make 'role' working
->setCandidateKey('role_id')
->setJoinType('INNER');
}
}

View File

@ -0,0 +1,57 @@
CREATE TABLE icingaweb_role (
id int unsigned NOT NULL AUTO_INCREMENT,
parent_id int unsigned DEFAULT NULL,
name varchar(254) NOT NULL,
unrestricted enum('n', 'y') NOT NULL DEFAULT 'n',
ctime bigint unsigned NOT NULL,
mtime bigint unsigned DEFAULT NULL,
PRIMARY KEY (id),
CONSTRAINT fk_icingaweb_role_parent_id FOREIGN KEY (parent_id)
REFERENCES icingaweb_role (id) ON DELETE SET NULL,
CONSTRAINT idx_icingaweb_role_name UNIQUE (name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
CREATE TABLE icingaweb_role_user (
role_id int unsigned NOT NULL,
user_name varchar(254) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (role_id, user_name),
INDEX idx_icingaweb_role_user_user_name (user_name),
CONSTRAINT fk_icingaweb_role_user_role_id FOREIGN KEY (role_id)
REFERENCES icingaweb_role (id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
CREATE TABLE icingaweb_role_group (
role_id int unsigned NOT NULL,
group_name varchar(254) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (role_id, group_name),
INDEX idx_icingaweb_role_group_group_name (group_name),
CONSTRAINT fk_icingaweb_role_group_role_id FOREIGN KEY (role_id)
REFERENCES icingaweb_role (id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
CREATE TABLE icingaweb_role_permission (
role_id int unsigned NOT NULL,
permission varchar(254) NOT NULL,
allowed enum('n', 'y') NOT NULL DEFAULT 'n',
denied enum('n', 'y') NOT NULL DEFAULT 'n',
PRIMARY KEY (role_id, permission),
CONSTRAINT fk_icingaweb_role_permission_role_id FOREIGN KEY (role_id)
REFERENCES icingaweb_role (id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
CREATE TABLE icingaweb_role_restriction (
role_id int unsigned NOT NULL,
restriction varchar(254) NOT NULL,
filter text NOT NULL,
PRIMARY KEY (role_id, restriction),
CONSTRAINT fk_icingaweb_role_restriction_role_id FOREIGN KEY (role_id)
REFERENCES icingaweb_role (id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
INSERT INTO icingaweb_schema (version, timestamp, success, reason)
VALUES('2.13.0', UNIX_TIMESTAMP() * 1000, 'y', NULL);

View File

@ -31,6 +31,61 @@ CREATE TABLE `icingaweb_user`(
PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
CREATE TABLE icingaweb_role (
id int unsigned NOT NULL AUTO_INCREMENT,
parent_id int unsigned DEFAULT NULL,
name varchar(254) NOT NULL,
unrestricted enum('n', 'y') NOT NULL DEFAULT 'n',
ctime bigint unsigned NOT NULL,
mtime bigint unsigned DEFAULT NULL,
PRIMARY KEY (id),
CONSTRAINT fk_icingaweb_role_parent_id FOREIGN KEY (parent_id)
REFERENCES icingaweb_role (id) ON DELETE SET NULL,
CONSTRAINT idx_icingaweb_role_name UNIQUE (name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
CREATE TABLE icingaweb_role_user (
role_id int unsigned NOT NULL,
user_name varchar(254) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (role_id, user_name),
INDEX idx_icingaweb_role_user_user_name (user_name),
CONSTRAINT fk_icingaweb_role_user_role_id FOREIGN KEY (role_id)
REFERENCES icingaweb_role (id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
CREATE TABLE icingaweb_role_group (
role_id int unsigned NOT NULL,
group_name varchar(254) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (role_id, group_name),
INDEX idx_icingaweb_role_group_group_name (group_name),
CONSTRAINT fk_icingaweb_role_group_role_id FOREIGN KEY (role_id)
REFERENCES icingaweb_role (id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
CREATE TABLE icingaweb_role_permission (
role_id int unsigned NOT NULL,
permission varchar(254) NOT NULL,
allowed enum('n', 'y') NOT NULL DEFAULT 'n',
denied enum('n', 'y') NOT NULL DEFAULT 'n',
PRIMARY KEY (role_id, permission),
CONSTRAINT fk_icingaweb_role_permission_role_id FOREIGN KEY (role_id)
REFERENCES icingaweb_role (id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
CREATE TABLE icingaweb_role_restriction (
role_id int unsigned NOT NULL,
restriction varchar(254) NOT NULL,
filter text NOT NULL,
PRIMARY KEY (role_id, restriction),
CONSTRAINT fk_icingaweb_role_restriction_role_id FOREIGN KEY (role_id)
REFERENCES icingaweb_role (id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
CREATE TABLE `icingaweb_user_preference`(
`username` varchar(254) COLLATE utf8mb4_unicode_ci NOT NULL,
`section` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL,
@ -65,4 +120,4 @@ CREATE TABLE icingaweb_schema (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin ROW_FORMAT=DYNAMIC;
INSERT INTO icingaweb_schema (version, timestamp, success)
VALUES ('2.12.0', UNIX_TIMESTAMP() * 1000, 'y');
VALUES ('2.13.0', UNIX_TIMESTAMP() * 1000, 'y');

View File

@ -0,0 +1,59 @@
CREATE TABLE icingaweb_role (
id serial,
parent_id int DEFAULT NULL,
name varchar(254) NOT NULL,
unrestricted boolenum NOT NULL DEFAULT 'n',
ctime bigint NOT NULL,
mtime bigint DEFAULT NULL,
CONSTRAINT pk_icingaweb_role PRIMARY KEY (id),
CONSTRAINT fk_icingaweb_role_parent_id FOREIGN KEY (parent_id)
REFERENCES icingaweb_role (id) ON DELETE SET NULL,
CONSTRAINT idx_icingaweb_role_name UNIQUE (name)
);
CREATE TABLE icingaweb_role_user (
role_id int NOT NULL,
user_name citext NOT NULL,
CONSTRAINT pk_icingaweb_role_user PRIMARY KEY (role_id, user_name),
CONSTRAINT fk_icingaweb_role_user_role_id FOREIGN KEY (role_id)
REFERENCES icingaweb_role (id) ON DELETE CASCADE
);
CREATE INDEX idx_icingaweb_role_user_user_name ON icingaweb_role_user(user_name);
CREATE TABLE icingaweb_role_group (
role_id int NOT NULL,
group_name citext NOT NULL,
CONSTRAINT pk_icingaweb_role_group PRIMARY KEY (role_id, group_name),
CONSTRAINT fk_icingaweb_role_group_role_id FOREIGN KEY (role_id)
REFERENCES icingaweb_role (id) ON DELETE CASCADE
);
CREATE INDEX idx_icingaweb_role_group_group_name ON icingaweb_role_group(group_name);
CREATE TABLE icingaweb_role_permission (
role_id int NOT NULL,
permission varchar(254) NOT NULL,
allowed boolenum NOT NULL DEFAULT 'n',
denied boolenum NOT NULL DEFAULT 'n',
CONSTRAINT pk_icingaweb_role_permission PRIMARY KEY (role_id, permission),
CONSTRAINT fk_icingaweb_role_permission_role_id FOREIGN KEY (role_id)
REFERENCES icingaweb_role (id) ON DELETE CASCADE
);
CREATE TABLE icingaweb_role_restriction (
role_id int NOT NULL,
restriction varchar(254) NOT NULL,
filter text NOT NULL,
CONSTRAINT pk_icingaweb_role_restriction PRIMARY KEY (role_id, restriction),
CONSTRAINT fk_icingaweb_role_restriction_role_id FOREIGN KEY (role_id)
REFERENCES icingaweb_role (id) ON DELETE CASCADE
);
INSERT INTO icingaweb_schema (version, timestamp, success, reason)
VALUES('2.13.0', EXTRACT(EPOCH FROM now()) * 1000, 'y', NULL);

View File

@ -1,5 +1,7 @@
/* Icinga Web 2 | (c) 2014 Icinga GmbH | GPLv2+ */
CREATE TYPE boolenum AS ENUM ('n', 'y');
CREATE OR REPLACE FUNCTION unix_timestamp(timestamp with time zone) RETURNS bigint AS '
SELECT EXTRACT(EPOCH FROM $1)::bigint AS result
' LANGUAGE sql;
@ -76,6 +78,63 @@ CREATE UNIQUE INDEX idx_icingaweb_user
lower((name)::text)
);
CREATE TABLE icingaweb_role (
id serial,
parent_id int DEFAULT NULL,
name varchar(254) NOT NULL,
unrestricted boolenum NOT NULL DEFAULT 'n',
ctime bigint NOT NULL,
mtime bigint DEFAULT NULL,
CONSTRAINT pk_icingaweb_role PRIMARY KEY (id),
CONSTRAINT fk_icingaweb_role_parent_id FOREIGN KEY (parent_id)
REFERENCES icingaweb_role (id) ON DELETE SET NULL,
CONSTRAINT idx_icingaweb_role_name UNIQUE (name)
);
CREATE TABLE icingaweb_role_user (
role_id int NOT NULL,
user_name citext NOT NULL,
CONSTRAINT pk_icingaweb_role_user PRIMARY KEY (role_id, user_name),
CONSTRAINT fk_icingaweb_role_user_role_id FOREIGN KEY (role_id)
REFERENCES icingaweb_role (id) ON DELETE CASCADE
);
CREATE INDEX idx_icingaweb_role_user_user_name ON icingaweb_role_user(user_name);
CREATE TABLE icingaweb_role_group (
role_id int NOT NULL,
group_name citext NOT NULL,
CONSTRAINT pk_icingaweb_role_group PRIMARY KEY (role_id, group_name),
CONSTRAINT fk_icingaweb_role_group_role_id FOREIGN KEY (role_id)
REFERENCES icingaweb_role (id) ON DELETE CASCADE
);
CREATE INDEX idx_icingaweb_role_group_group_name ON icingaweb_role_group(group_name);
CREATE TABLE icingaweb_role_permission (
role_id int NOT NULL,
permission varchar(254) NOT NULL,
allowed boolenum NOT NULL DEFAULT 'n',
denied boolenum NOT NULL DEFAULT 'n',
CONSTRAINT pk_icingaweb_role_permission PRIMARY KEY (role_id, permission),
CONSTRAINT fk_icingaweb_role_permission_role_id FOREIGN KEY (role_id)
REFERENCES icingaweb_role (id) ON DELETE CASCADE
);
CREATE TABLE icingaweb_role_restriction (
role_id int NOT NULL,
restriction varchar(254) NOT NULL,
filter text NOT NULL,
CONSTRAINT pk_icingaweb_role_restriction PRIMARY KEY (role_id, restriction),
CONSTRAINT fk_icingaweb_role_restriction_role_id FOREIGN KEY (role_id)
REFERENCES icingaweb_role (id) ON DELETE CASCADE
);
CREATE TABLE "icingaweb_user_preference" (
"username" character varying(254) NOT NULL,
"name" character varying(64) NOT NULL,
@ -118,8 +177,6 @@ ALTER TABLE ONLY "icingaweb_rememberme"
"id"
);
CREATE TYPE boolenum AS ENUM ('n', 'y');
CREATE TABLE "icingaweb_schema" (
"id" serial,
"version" varchar(64) NOT NULL,
@ -132,4 +189,4 @@ CREATE TABLE "icingaweb_schema" (
);
INSERT INTO icingaweb_schema (version, timestamp, success)
VALUES ('2.12.0', extract(epoch from now()) * 1000, 'y');
VALUES ('2.13.0', extract(epoch from now()) * 1000, 'y');