Skip to content

Commit

Permalink
Rough-draft for permission management examples (#3)
Browse files Browse the repository at this point in the history
* Rough-draft for permission management examples

* Use InformationException
  • Loading branch information
BelleNottelling authored Dec 11, 2023
1 parent 14cd34e commit baab923
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 24 deletions.
48 changes: 48 additions & 0 deletions src/Api/Admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,52 @@ public function get_something($data): array

return $result;
}

/**
* An example that checks if the staff member has permission to the `do_something` permission key.
*
* @return bool
*/
public function can_do_something($data)
{
// First, get an instance of the staff module
$staff_service = $this->di['mod_service']('Staff');

/* Next, we use the staff module to check if the current staff member has permission.
* We pass `null` to the first parameter to tell it to check against current staff member
* The second parameter `example` is the name of the module
* The third parameter is the name of the permission key we are checking (`do_something`)
*/
if (!$staff_service->hasPermission(null, 'example', 'do_something')) {
throw new \FOSSBilling\InformationException('You do not have permission to perform this action', [], 403);
}

return true;
}


/**
* An example that checks if the staff member has permission to the `a_select` permission key depending on the specific constraint set.
*
* @return bool
*/
public function check_select($data)
{
$data['constraint'] ??= 'value_1';

// First, get an instance of the staff module
$staff_service = $this->di['mod_service']('Staff');

/* Next, we use the staff module to check if the current staff member has permission.
* We pass `null` to the first parameter to tell it to check against current staff member
* The second parameter `example` is the name of the module
* The third parameter is the name of the permission key we are checking (`a_select`)
* The final parameter is the contraint we want to apply for the staff member's permission. When using the select type pemission, this is how you check if they have a specific one. (`value_1` for example)
*/
if (!$staff_service->hasPermission(null, 'example', 'a_select', $data['constraint'])) {
throw new \FOSSBilling\InformationException('You do not have permission to perform this action', [], 403);
}

return true;
}
}
31 changes: 31 additions & 0 deletions src/Service.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,37 @@ public function setDi(\Pimple\Container|null $di): void
$this->di = $di;
}

/**
* Any module may define this function to return an array of permission keys that are related to it.
* You may define either a `bool` or a `select` permission type.
* Modules do not need to define this function.
*
* We've included an example of how to check the permissions under the `/api/Admin.php` file and some front-end usage under `/html_admin/mod_example_index.html.twig`
*
* @return array
*/
public function getModulePermissions(): array
{
return [
'do_something' => [
'type' => 'bool',
'display_name' => 'Do something',
'description' => 'Allows the staff member to do something',
],
'a_select' => [
'type' => 'select',
'display_name' => 'A select',
'description' => 'This is an example of the select permission type',
'options' => [
'value_1' => 'Value 1',
'value_2' => 'Value 2',
'value_3' => 'Value 3',
]
],
'manage_settings' => [], // Tells FOSSBilling that there should be a permission key to manage the module's settings (admin/extension/settings/example)
];
}

/**
* Method to install the module. In most cases you will use this
* to create database tables for your module.
Expand Down
85 changes: 62 additions & 23 deletions src/html_admin/mod_example_index.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

{% block content %}
<div class="card">
<div class="card-header">
<h3 class="card-title">Example module for developers</h3>
<div class="card-header">
<h3 class="card-title">Example module for developers</h3>
</div>
<!-- First card -->
<div class="card-body">
Expand All @@ -24,7 +24,23 @@
</ul>
</div>

{# Check if example parameters passed to template file #}
<div class="card-header">
<h3>Permission tests</h3>
</div>
<div class="card-body">
<p>Check if you have permission to do "something"</p>
<button class="btn btn-primary" onclick="checkCanDoSomething();">Check</button>

<p>Check if you are assigned a specific option from a "select" permission type.</p>
<select id="check-against">
<option value="value_1">Value 1</option>
<option value="value_2">Value 2</option>
<option value="value_3">Value 3</option>
</select>
<button class="btn btn-primary" onclick="checkConstraintPermission();">Check</button>
</div>

{# Check if example parameters passed to the template file #}
{% if youparamname %}
<div class="card-header">
<h5>{{ 'Parameters from Controller'|trans }}</h5>
Expand All @@ -34,37 +50,60 @@
</div>
{% endif %}

{# Check if example parameters passed to template file #}
{# Check if example parameters passed to the template file #}
{% if userid %}
<div class="card-header">
<h5>{{ 'Parameters from URL'|trans }}</h5>
</div>
<div class="card-body">
<p>You have passed parameter userid: <strong>{{ userid }}</strong></p>
</div>
<div class="card-header">
<h5>{{ 'Parameters from URL'|trans }}</h5>
</div>
<div class="card-body">
<p>You have passed parameter userid: <strong>{{ userid }}</strong></p>
</div>
{% endif %}

{% if api_example %}
{# API example #}
<div class="card-header">
<h5>{{ 'API example'|trans }}</h5>
</div>
<div class="card-body">
<h5 class="pt12">Data from API and passed to template from controller</h5>
<pre>{{ dump(list_from_controller) }}</pre>
{# API example #}
<div class="card-header">
<h5>{{ 'API example'|trans }}</h5>
</div>
<div class="card-body">
<h5 class="pt-2">Data from API and passed to the template from the controller</h5>
<pre>{{ dump(list_from_controller) }}</pre>

<h5 class="pt12">Data from API accessed directly from template file</h5>
{% set list = admin.example_get_something({"microsoft":1}) %}
<pre>{{ dump(list) }}</pre>
</div>
<h5 class="pt-2">Data from API accessed directly from the template file</h5>
{% set list = admin.example_get_something({"microsoft":1}) %}
<pre>{{ dump(list) }}</pre>
</div>
{% endif %}

<!-- Second card -->
<div class="card-header">
<h5>{{ 'README'|trans }}</h5>
<div class="card-header">
<h5>{{ 'README'|trans }}</h5>
</div>
<div class="card-body markdown">
{{ guest.example_readme | markdown }}
</div>
</div>

<script>
// Send a request to the backend and ask if the staff member has the `do_something` permission key.
function checkCanDoSomething() {
API.admin.post('example/can_do_something', {}, function(result) {
FOSSBilling.message('Great, you did something!');
},
function(result){
FOSSBilling.message(result.message, 'error');
});
};
// Use the API to check and see if the staff member has a specifc permission constraint under the `a_select` key.
function checkConstraintPermission() {
var e = document.getElementById('check-against');
API.admin.post('example/check_select', { constraint: e.value }, function(result) {
FOSSBilling.message('You do have that permission');
},
function(result){
FOSSBilling.message('You do not have that permission', 'error');
});
};
</script>
{% endblock %}
2 changes: 1 addition & 1 deletion src/manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"id": "Example",
"id": "example",
"type": "mod",
"name": "Example",
"description": "An example module for developers to get started",
Expand Down

0 comments on commit baab923

Please sign in to comment.