Skip to content

Commit

Permalink
Critter access policy and small fixes (#55)
Browse files Browse the repository at this point in the history
### Before deploy

Do not forget to run `bin/migrate` and to check the config file `config.default.php`.
New policy variables inside:
```php
    // Policy features
    'policy'                => [
        // Adds the prefix to the visual text but do not affect the link
        'telegram_visual_prefix' => '', //keep it empty - users without telegram, may be buggy
        // Non-staff others profile link generation - False = empty link / True = message
        'non_staff_message_shortcut' => true,
        // Non-Staff - Use Telegram for message. False > uses internal message system
        'non_staff_message_via_telegram' => true,
    ],
```

### [Add]
- New awesome theme add/created by @Balenty
- New policy flag `telegram_visual_prefix`
  - Only the text displayed gets the prefix while not touching the link. For example, we can add '@'
- Force remove @ from the telegram handler when rendering link - from the database (old data)
- New policy flag `non_staff_message_shortcut`
   - Responsible for profile link generation for all critters - affects viewing others profiles
   - True (Default) = Create a link to send internal message to the target user
   - False = Disable the link creation - Just shows the name... no link
- Privilege Group: Staff - Internal
- Privilege: `user.type.internal_staff` for internal staff
- Migration script for the new Privilege `Internal Staff`
  - Add group and privilege
  - Add the new privilege to groups: Bureaucrat, Developer, Shift Coordinator
- New config policy: `non_staff_message_via_telegram` False = Use internal message system / True = Use telegram (if exist)
- Proper description for the function `render_profile_link`

### [Change]
- Fix: Wrong profile link when departure date is missing
- Fix: config variable `telegram_visual_prefix` set to empty
- Guest - can't see contacts
- Non staff - profile (others) access is restricted
- Other small stuff not relevant to be documented
- New parameter for function `render_profile_link` -> yes, not ideal but later to be improved
- If telegram handler is available, it will be used, if not, default to internal message system
- Add explicit variables declaration for the function `render_user_departure_date_hint` and `User_Nick_render`
  • Loading branch information
RustyBraze authored Sep 14, 2024
1 parent ce65ccf commit 8a8fe45
Show file tree
Hide file tree
Showing 31 changed files with 1,308 additions and 28 deletions.
25 changes: 25 additions & 0 deletions config/config.default.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,21 @@
// Supported themes
// To disable a theme in config.php, you can set its value to null
'themes' => [
20 => [
'name' => 'Eurofurence 2024 - Cyberpunk ',
'type' => 'dark',
'navbar_classes' => 'navbar-dark',
],
19 => [
'name' => 'Eurofurence Light',
'type' => 'light',
'navbar_classes' => 'navbar-light bg-light',
],
18=> [
'name' => 'Eurofurence Dark',
'type' => 'dark',
'navbar_classes' => 'navbar-primary navbar-dark bg-black border-dark',
],
17 => [
'name' => 'Engelsystem 37c3 (2023)',
'type' => 'dark',
Expand Down Expand Up @@ -469,6 +484,16 @@
. 'or need help.',
],

// Policy features
'policy' => [
// Adds the prefix to the visual text but do not affect the link
'telegram_visual_prefix' => '',
// Non-Staff - profile link redirects to Message system. False > Only shows the name (no link)
'non_staff_message_shortcut' => true,
// Non-Staff - Use Telegram for message. False > uses internal message system
'non_staff_message_via_telegram' => true,
],

// var dump server
'var_dump_server' => [
'host' => '127.0.0.1',
Expand Down
226 changes: 226 additions & 0 deletions db/migrations/2024_09_12_000000_internal_staff_permission.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
<?php

declare(strict_types=1);

namespace Engelsystem\Migrations;

use Engelsystem\Database\Migration\Migration;
use Illuminate\Database\Connection;
use Illuminate\Database\Schema\Builder as SchemaBuilder;

class InternalStaffPermission extends Migration
{
// ------------------------------------------------------------
// Groups
// ------------------------------------------------------------
protected int $staffInternalID = 21;
protected string $staffInternalText = 'Staff - Internal';

protected int $shiftCoordinatorID = 60;
protected int $bureaucratID = 80;
protected int $developerID = 90;

// ------------------------------------------------------------
// Privileges
// ------------------------------------------------------------
protected int $userTypeInternalStaffID;
protected string $userTypeInternalStaffText = 'user.type.internal_staff';
protected string $userTypeInternalStaffDesc = 'Flag the user as Internal Staff';

protected Connection $db;

public function __construct(SchemaBuilder $schema)
{
parent::__construct($schema);
$this->db = $this->schema->getConnection();
}

/**
* Run the migration
*/
public function up(): void
{
// I know... look shit but it is late, I am sleepy and want to finish this...

// add the staff group
$this->db->table('groups')
->insert([
'id' => $this->staffInternalID,
'name' => $this->staffInternalText,
]);

// add the privileges
$this->db->table('privileges')
->insert([
'name' => $this->userTypeInternalStaffText,
'description' => $this->userTypeInternalStaffDesc,
]);

// we want the ID of the privilege we add
$this->userTypeInternalStaffID = $this->getPrivilegeId($this->userTypeInternalStaffText);

// Time to add shit to the groups
$this->insertGroupPermission($this->userTypeInternalStaffID, $this->staffInternalID);
$this->insertGroupPermission($this->userTypeInternalStaffID, $this->shiftCoordinatorID);
$this->insertGroupPermission($this->userTypeInternalStaffID, $this->bureaucratID);
$this->insertGroupPermission($this->userTypeInternalStaffID, $this->developerID);
}

/**
* Reverse the migration
*/
public function down(): void
{
// we want the ID of the privilege we add
$this->userTypeInternalStaffID = $this->getPrivilegeId($this->userTypeInternalStaffText);

// Time to delete the crap out of the system...
$this->deleteGroupPermission($this->userTypeInternalStaffID, $this->staffInternalID);
$this->deleteGroupPermission($this->userTypeInternalStaffID, $this->shiftCoordinatorID);
$this->deleteGroupPermission($this->userTypeInternalStaffID, $this->bureaucratID);
$this->deleteGroupPermission($this->userTypeInternalStaffID, $this->developerID);

$this->deletePermission($this->userTypeInternalStaffText);

$this->deleteGroup($this->staffInternalID);
}


/**
* Retrieves the ID of a given privilege.
*
* @param string $privilege The name of the privilege whose ID is to be retrieved.
* @return int The ID of the privilege.
*/
protected function getPrivilegeId(string $privilege): int
{
return $this->db->table('privileges')
->where('name', $privilege)
->get(['id'])
->first()->id;
}

/**
* Deletes a group identified by the provided ID.
*
* @param int $group The ID of the group to be deleted.
* @return void
*/
protected function deleteGroup(int $group): void
{
$this->db->table('groups')
->where(['id' => $group])
->delete();
}

/**
* Inserts a group into the database and assigns the given privileges to it.
*
* @param int $id The ID of the group.
* @param string $name The name of the group.
* @param array $privileges A list of privileges to be assigned to the group.
*
* @return void
*/
protected function insertGroup(int $id, string $name, array $privileges): void
{
$this->db->table('groups')
->insertOrIgnore([
'name' => $name,
'id' => $id,
]);
foreach ($privileges as $privilege) {
$this->insertGroupPermission($privilege, $id);
}
}

/**
* Removes a specified privilege from a group.
*
* @param int $privilege The ID of the privilege to remove.
* @param int $group The ID of the group from which the privilege should be removed.
* @return void
*/
protected function deleteGroupPermission(int $privilege, int $group): void
{
$this->db->table('group_privileges')
->where(['group_id' => $group, 'privilege_id' => $privilege])
->delete();
}

/**
* Inserts a privilege into the group's privilege list.
*
* @param int $privilege The ID of the privilege to be added.
* @param int $group The ID of the group to which the privilege is to be added.
* @return void
*/
protected function insertGroupPermission(int $privilege, int $group): void
{
$this->db->table('group_privileges')
->insertOrIgnore([
['group_id' => $group, 'privilege_id' => $privilege],
]);
}

/**
* Moves a permission from one group to another.
*
* @param int $privilege The identifier of the privilege to be moved.
* @param int $oldGroup The identifier of the group from which the privilege will be removed.
* @param int $newGroup The identifier of the group to which the privilege will be added.
* @return void
*/
protected function movePermission(int $privilege, int $oldGroup, int $newGroup): void
{
$this->insertGroupPermission($privilege, $newGroup);
$this->deleteGroupPermission($privilege, $oldGroup);
}

/**
* Inserts a new permission into the privileges table and assigns it to a group.
*
* @param string $name The name of the permission.
* @param string $description A description of the permission.
* @param int $group The ID of the group to associate with the permission.
* @return void
*/
protected function insertPermission(string $name, string $description, int $group): void
{
$this->db->table('privileges')
->insertOrIgnore([
'name' => $name, 'description' => $description,
]);
$permission = $this->getPrivilegeId($name);
$this->insertGroupPermission($permission, $group);
}

/**
* Deletes a permission from the privileges table based on its name.
*
* @param string $privilege The name of the permission to delete.
* @return void
*/
protected function deletePermission(string $privilege): void
{
$this->db->table('privileges')
->where(['name' => $privilege])
->delete();
}

/**
* Updates an existing permission in the privileges table.
*
* @param string $oldName The current name of the permission to be updated.
* @param string $newName The new name of the permission.
* @param string $description The new description of the permission.
* @return void
*/
protected function updatePermission(string $oldName, string $newName, string $description): void
{
$this->db->table('privileges')->where('name', $oldName)->update([
'name' => $newName,
'description' => $description,
]);
}
}
8 changes: 8 additions & 0 deletions includes/controller/users_controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,14 @@ function user_controller()
}
}

if ($user->id != $user_source->id and
!(auth()->can('user.type.internal_staff') or
auth()->can('admin_user'))
) {
// error(__('Not possible...'));
throw_redirect(url('/'));
}

$shifts = Shifts_by_user($user_source->id, true);
foreach ($shifts as $shift) {
// TODO: Move queries to model
Expand Down
2 changes: 1 addition & 1 deletion includes/pages/admin_free.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ function admin_free()
. user_info_icon($usr),
'shift_state' => User_shift_state_render($usr),
'last_shift' => User_last_shift_render($usr),
'dect' => sprintf('<a href="https://t.me/%s">%1$s</a>', htmlspecialchars((string) $usr->contact->dect)),
'dect' => sprintf('<a href="https://t.me/%s">%s%1$s</a>', str_replace('@','', htmlspecialchars((string) $usr->contact->dect)), config('policy')['telegram_visual_prefix']),
'email' => $usr->settings->email_human
? sprintf('<a href="mailto:%s">%1$s</a>', htmlspecialchars((string) $email))
: icon('eye-slash'),
Expand Down
4 changes: 2 additions & 2 deletions includes/view/AngelTypes_view.php
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ function AngelType_view_members(AngelType $angeltype, $members, $admin_user_ange
$member->name = User_Nick_render($member) . User_Pronoun_render($member);
if (config('enable_dect')) {
$member['dect'] =
sprintf('<a href="https://t.me/%s">%1$s</a>', htmlspecialchars((string) $member->contact->dect));
sprintf('<a href="https://t.me/%s">%s%1$s</a>', str_replace('@', '', htmlspecialchars((string) $member->contact->dect)), config('policy')['telegram_visual_prefix']);
}
if (config('driving_license_enabled') && $angeltype->requires_driver_license) {
$drive_confirmed = $member->license->drive_confirmed;
Expand Down Expand Up @@ -683,7 +683,7 @@ function AngelTypes_render_contact_info(AngelType $angeltype)
],
__('general.dect') => config('enable_dect')
? [
sprintf('<a href="http://t.me/%s">%1$s</a>', htmlspecialchars($angeltype->contact_dect)),
sprintf('<a href="https://t.me/%s">%s%1$s</a>', str_replace('@','',htmlspecialchars($angeltype->contact_dect)),config('policy')['telegram_visual_prefix']),
htmlspecialchars($angeltype->contact_dect),
]
: null,
Expand Down
5 changes: 3 additions & 2 deletions includes/view/Locations_view.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ function location_view(Location $location, ShiftsFilterRenderer $shiftsFilterRen
if (config('enable_dect') && $location->dect) {
$dect = heading(__('Contact'), 3)
. description([__('general.dect') => sprintf(
'<a href="https://t.me/%s">%1$s</a>',
htmlspecialchars($location->dect)
'<a href="https://t.me/%s">%s%1$s</a>',
str_replace('@','',htmlspecialchars($location->dect)),
config('policy')['telegram_visual_prefix']
)]);
}

Expand Down
Loading

0 comments on commit 8a8fe45

Please sign in to comment.