n0nag0n/fatfree-permissions

为您的Fat-Free应用程序提供权限模块,以帮助自定义权限。

v0.1.2 2024-06-17 02:43 UTC

This package is auto-updated.

Last update: 2024-09-17 03:16:36 UTC


README

这是一个权限模块,您可以在您的项目中使用,如果您在应用程序中有多个角色,并且每个角色都有一些不同的功能。此模块允许您为每个角色定义权限,然后检查当前用户是否有权访问某个页面或执行某个操作。此模块旨在与Fat-Free 框架一起使用。它不是一个独立的模块。此模块与xfra35/f3-access配合使用非常好。

安装

运行composer require n0nag0n/fatfree-permissions即可开始使用!

配置

为了启动此功能,您需要做的配置非常少。实际上,它已经连接好了以接受配置,但目前并没有实际使用。

用法

首先,您需要设置您的权限,然后告诉您的应用程序权限的含义。最终,您将使用$Permissions->has()->can()->is()来检查权限。它们都具有相同的功能,但名称不同,可以使您的代码更易于阅读。

简单用法

<?php

// bootstrap code
$f3 = Base::instance();

// some code 

// then you probably have something that tells you who the current role is of the person
// likely you have something like $f3->get('SESSION.user.role'); which defines this
// after someone logs in, otherwise they will have a 'guest' or 'public' role.
$current_role = 'admin';

// setup permissions
$Permissions = \n0nag0n\Permissions::instance($current_role);
$Permissions->defineRule('logged_in', function(Base $f3, $current_role) {
	return $current_role !== 'guest';
});

// You'll likely want to attach to this the hive
$f3->set('Permissions', $Permissions);
// or you can just call it on it's own cause it extends itself
// \n0nag0n\Permissions::instance()->can('somePermission');

$f3->run();

然后在您的模板或控制器中,您可以这样做

<?php

public function getOrder(Base $f3, array $args = []) {
	// check if the user is logged in
	if (!$f3->get('Permissions')->is('logged_in')) {
		// if not, redirect them to the login page
		$f3->reroute('/login');
	}
	// otherwise, show them the order page
	// ...
}

高级用法

您可能有一些更高级的功能,其中一个角色可以访问某些功能,而另一个角色则不能。我将向您展示这意味着什么。

在此上下文中定义的权限完全可以自定义。如果您需要viewupdatearchivesoft-deletelike权限,您可以完全按照这种方式自定义。您可以将任何字符串附加到数组中,以检查用户是否有该权限。

<?php

// bootstrap code
$f3 = Base::instance();

$current_role = 'manager';

// setup permissions in a CRUD like context
$Permissions = \n0nag0n\Permissions::instance($current_role);

// additionally you can inject additional dependencies into the closure/class->method
$Permissions->defineRule('order', function(Base $f3, $current_role, My_Dependency $My_Dependency = null) {
	$allowed_permissions = [ 'read' ]; // everyone can view an order
	if($current_role === 'manager' && $My_Dependency->something === 'something') {
		$allowed_permissions[] = 'create'; // managers can create orders
	}
	$some_special_toggle_from_db = $f3->get('DB')->exec('SELECT some_special_toggle FROM settings WHERE id = ?', [ $f3->get('SESSION.user_id') ])[0]['some_special_toggle'];
	if($some_special_toggle_from_db) {
		$allowed_permissions[] = 'update'; // if the user has a special toggle, they can update orders
	}
	if($current_role === 'admin') {
		$allowed_permissions[] = 'delete'; // admins can delete orders
	}
	return $allowed_permissions;
});

// You'll likely want to attach to this the hive
$f3->set('Permissions', $Permissions);

$f3->run();

现在,当您想检查用户是否有关于订单的特定权限时,乐趣就开始了。

<?php

public function deleteOrder(Base $f3, array $args = []) {

	$My_Dependency = new My_Dependency('something');

	// check if the user can delete an order
	// notice where you inject the dependency
	if (!$f3->get('Permissions')->can('order.delete', $My_Dependency)) {
		// if not, redirect them to the orders page gracefully
		$f3->reroute('/orders');
	}
	// otherwise, delete the order page
	// ...
}

注入依赖项

如上例所示,您可以将依赖项注入到定义权限的闭包中。如果您想检查某种类型的切换,这将非常有用。对于Class->Method类型的调用也适用,但您需要将方法定义为这种方式。

namespace MyApp;

class Permissions {

	public function order(Base $f3, string $current_role, My_Dependency $My_Dependency = null) {
		// ... code
	}
}

使用类来定义快捷方式

您还可以使用类来定义权限。如果您有很多权限并且想保持代码的整洁,这非常有用。您可以这样做

<?php

// bootstrap code
$Permissions = \n0nag0n\Permissions::instance($current_role);
$Permissions->defineRule('order', 'MyApp\Permissions->order');

// myapp/Permissions.php
namespace MyApp;

class Permissions {

	public function order(Base $f3, string $current_role) {
		$allowed_permissions = [ 'read' ]; // everyone can view an order
		if($current_role === 'manager') {
			$allowed_permissions[] = 'create'; // managers can create orders
		}
		$some_special_toggle_from_db = $f3->get('DB')->exec('SELECT some_special_toggle FROM settings WHERE id = ?', [ $f3->get('SESSION.user_id') ])[0]['some_special_toggle'];
		if($some_special_toggle_from_db) {
			$allowed_permissions[] = 'update'; // if the user has a special toggle, they can update orders
		}
		if($current_role === 'admin') {
			$allowed_permissions[] = 'delete'; // admins can delete orders
		}
		return $allowed_permissions;
	}
}

酷的地方在于,还有一个您可以使用(也是缓存过的!)快捷方式,您只需告诉权限类将一个类中的所有方法映射到权限。所以如果您有一个名为order()的方法和一个名为company()的方法,它们将自动映射,您可以简单地运行$Permissions->has('order.read')$Permissions->has('company.read'),它就会起作用。定义这一点非常困难,所以请跟我来。您只需这样做

$Permissions = \n0nag0n\Permissions::instance($current_role);
$Permissions->defineRulesFromClassMethods(MyApp\Permissions::class, 3600); // 3600 is how many seconds to cache this for. Leave this off to not use caching

然后就可以开始了!