mirror of
https://github.com/espocrm/espocrm.git
synced 2026-06-28 06:56:05 +00:00
dev
This commit is contained in:
@@ -4,6 +4,5 @@ namespace Espo\Controllers;
|
||||
|
||||
class User extends \Espo\Core\Controllers\Record
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ class Acl
|
||||
public function __construct(\Espo\Entities\User $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->user->loadLinkMultipleField('teams');
|
||||
|
||||
$this->cacheFile = 'data/cache/application/acl/' . $user->id;
|
||||
|
||||
@@ -22,21 +23,22 @@ class Acl
|
||||
$cached = include $this->cacheFile;
|
||||
} else {
|
||||
$this->load();
|
||||
$this->initSolid();
|
||||
$this->buildCache();
|
||||
}
|
||||
}
|
||||
|
||||
public function checkScope($subject, $action = null, $isOwner = null, $inTeam = null)
|
||||
public function checkScope($scope, $action = null, $isOwner = null, $inTeam = null)
|
||||
{
|
||||
if (isset($this->data[$scope])) {
|
||||
if (array_key_exists($scope, $this->data)) {
|
||||
if ($this->data[$scope] === false) {
|
||||
return false;
|
||||
}
|
||||
if ($this->data[$scope] === true) {
|
||||
return true;
|
||||
}
|
||||
if ($action) {
|
||||
if (isset($this->data[$scope][$action])) {
|
||||
if (!is_null($action)) {
|
||||
if (array_key_exists($action, $this->data[$scope])) {
|
||||
$value = $this->data[$scope][$action];
|
||||
|
||||
if ($value === 'all' || $value === true) {
|
||||
@@ -45,9 +47,9 @@ class Acl
|
||||
|
||||
if (!$value || $value === 'no') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($isOwner === null) {
|
||||
if (is_null($isOwner)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -82,17 +84,38 @@ class Acl
|
||||
return true;
|
||||
}
|
||||
if (is_string($subject)) {
|
||||
return $this->checkScope($subject, $action = null, $isOwner = null, $inTeam = null);
|
||||
return $this->checkScope($subject, $action, $isOwner, $inTeam);
|
||||
} else {
|
||||
$entity = $subject;
|
||||
$entityName = ltrim(get_class($entity), '\\');
|
||||
|
||||
$entityName = $entity->getEntityName();
|
||||
return $this->checkScope($entityName, $action, $this->checkIsOwner($entity), $this->checkInTeam($entity));
|
||||
}
|
||||
}
|
||||
|
||||
public function checkReadOnlyTeam($scope)
|
||||
{
|
||||
if (isset($this->data[$scope]) && isset($this->data[$scope]['read'])) {
|
||||
return $this->data[$scope]['read'] === 'team';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkReadOnlyOwn($scope)
|
||||
{
|
||||
if ($this->user->isAdmin()) {
|
||||
return false;
|
||||
}
|
||||
if (isset($this->data[$scope]) && isset($this->data[$scope]['read'])) {
|
||||
return $this->data[$scope]['read'] === 'own';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkIsOwner($entity)
|
||||
{
|
||||
if ($this->user->isAdmin()) {
|
||||
return false;
|
||||
}
|
||||
$userId = $this->user->id;
|
||||
if ($userId === $entity->get('assignedUserId') || $userId === $entity->get('createdById')) {
|
||||
return true;
|
||||
@@ -133,6 +156,21 @@ class Acl
|
||||
|
||||
$this->data = $this->merge($aclTables);
|
||||
}
|
||||
|
||||
private function initSolid()
|
||||
{
|
||||
$this->data['User'] = array(
|
||||
'read' => 'all',
|
||||
'edit' => 'no',
|
||||
'delete' => 'no',
|
||||
);
|
||||
$this->data['Team'] = array(
|
||||
'read' => 'all',
|
||||
'edit' => 'no',
|
||||
'delete' => 'no',
|
||||
);
|
||||
$this->data['Role'] = false;
|
||||
}
|
||||
|
||||
private function merge($tables)
|
||||
{
|
||||
|
||||
@@ -33,17 +33,12 @@ abstract class Record extends Base
|
||||
public function actionRead($params)
|
||||
{
|
||||
$id = $params['id'];
|
||||
$service = $this->getRecordService();
|
||||
$entity = $service->getEntity($id);
|
||||
$entity = $this->getRecordService()->getEntity($id);
|
||||
|
||||
if (empty($entity)) {
|
||||
throw new NotFound();
|
||||
}
|
||||
|
||||
if (!$this->getAcl()->check($entity, 'read')) {
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
return $entity->toArray();
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,20 @@ namespace Espo\Core\ORM;
|
||||
|
||||
class Entity extends \Espo\ORM\Entity
|
||||
{
|
||||
|
||||
public function loadLinkMultipleField($field)
|
||||
{
|
||||
if ($this->hasRelation($field) && $this->hasField($field . 'Ids')) {
|
||||
$collection = $this->get($field);
|
||||
$ids = array();
|
||||
$names = new \stdClass();
|
||||
foreach ($collection as $e) {
|
||||
$id = $e->id;
|
||||
$ids[] = $id;
|
||||
$names->$id = $e->get('name');
|
||||
}
|
||||
$this->set($field . 'Ids', $ids);
|
||||
$this->set($field . 'Names', $names);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ class EntityManager extends \Espo\ORM\EntityManager
|
||||
public function normalizeEntityName($name)
|
||||
{
|
||||
return $this->espoMetadata->getEntityPath($name);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -27,11 +27,19 @@ class SelectManager
|
||||
{
|
||||
$this->entityName = $entityName;
|
||||
}
|
||||
|
||||
public function getSelectParams(array $params, $withAcl = false)
|
||||
{
|
||||
$result = array();
|
||||
|
||||
|
||||
protected function limit($params, &$result)
|
||||
{
|
||||
if (isset($params['offset']) && !is_null($params['offset'])) {
|
||||
$result['offset'] = $params['offset'];
|
||||
}
|
||||
if (isset($params['maxSize']) && !is_null($params['maxSize'])) {
|
||||
$result['limit'] = $params['maxSize'];
|
||||
}
|
||||
}
|
||||
|
||||
protected function order($params, &$result)
|
||||
{
|
||||
if (!empty($params['sortBy'])) {
|
||||
$result['orderBy'] = $params['sortBy'];
|
||||
}
|
||||
@@ -42,14 +50,10 @@ class SelectManager
|
||||
$result['order'] = 'DESC';
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($params['offset']) && !is_null($params['offset'])) {
|
||||
$result['offset'] = $params['offset'];
|
||||
}
|
||||
if (isset($params['maxSize']) && !is_null($params['maxSize'])) {
|
||||
$result['limit'] = $params['maxSize'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected function where($params, &$result)
|
||||
{
|
||||
if (!empty($params['where']) && is_array($params['where'])) {
|
||||
$where = array();
|
||||
|
||||
@@ -101,12 +105,42 @@ class SelectManager
|
||||
|
||||
}
|
||||
|
||||
//print_r($where);
|
||||
//die;
|
||||
|
||||
$result['whereClause'] = $where;
|
||||
}
|
||||
}
|
||||
|
||||
protected function access(&$result)
|
||||
{
|
||||
if ($this->acl->checkReadOnlyOwn($this->entityName)) {
|
||||
if (!array_key_exists('whereClause', $result)) {
|
||||
$result['whereClause'] = array();
|
||||
}
|
||||
$result['whereClause']['assignedUserId'] = $this->user->id;
|
||||
}
|
||||
if ($this->acl->checkReadOnlyTeam($this->entityName)) {
|
||||
if (!array_key_exists('whereClause', $result)) {
|
||||
$result['whereClause'] = array();
|
||||
}
|
||||
if (!array_key_exists('joins', $result)) {
|
||||
$result['joins'] = array();
|
||||
if (!in_array('teams', $result['joins'])) {
|
||||
$result['joins'][] = 'teams';
|
||||
}
|
||||
}
|
||||
$result['whereClause']['Team.id'] = $this->user->get('teamsIds');
|
||||
}
|
||||
}
|
||||
|
||||
public function getSelectParams(array $params, $withAcl = false)
|
||||
{
|
||||
$result = array();
|
||||
|
||||
$this->order($params, $result);
|
||||
$this->limit($params, $result);
|
||||
$this->where($params, $result);
|
||||
if ($withAcl) {
|
||||
$this->access($result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,6 @@ class Auth extends \Slim\Middleware
|
||||
$authSec = $req->headers('PHP_AUTH_PW');
|
||||
|
||||
if ($authKey && $authSec) {
|
||||
|
||||
$isAuthenticated = false;
|
||||
|
||||
$username = $authKey;
|
||||
@@ -51,20 +50,14 @@ class Auth extends \Slim\Middleware
|
||||
$user = $this->entityManager->getRepository('User')->findOne(array(
|
||||
'whereClause' => array(
|
||||
'userName' => $username,
|
||||
'password' => md5($password)
|
||||
),
|
||||
));
|
||||
|
||||
if ($user instanceof \Espo\Entities\User) {
|
||||
|
||||
$this->entityManager->setUser($user);
|
||||
|
||||
if ($password == $user->get('password')) {
|
||||
$this->container->setUser($user);
|
||||
$isAuthenticated = true;
|
||||
}
|
||||
if ($user instanceof \Espo\Entities\User) {
|
||||
$this->entityManager->setUser($user);
|
||||
$this->container->setUser($user);
|
||||
$isAuthenticated = true;
|
||||
}
|
||||
|
||||
|
||||
if ($isAuthenticated) {
|
||||
$this->next->call();
|
||||
} else {
|
||||
|
||||
@@ -7,5 +7,5 @@ class User extends \Espo\Core\ORM\Entity
|
||||
public function isAdmin()
|
||||
{
|
||||
return $this->get('isAdmin');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,8 +60,11 @@ abstract class Entity implements IEntity
|
||||
}
|
||||
}
|
||||
|
||||
public function clear($name)
|
||||
public function clear($name = null)
|
||||
{
|
||||
if (is_null($name)) {
|
||||
$this->reset();
|
||||
}
|
||||
unset($this->valuesContainer[$name]);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace Espo\Services;
|
||||
|
||||
use \Espo\Core\Exceptions\Error;
|
||||
use \Espo\Core\Exceptions\Forbidden;
|
||||
use \Espo\Core\Utils\Util;
|
||||
|
||||
class Record extends \Espo\Core\Services\Base
|
||||
@@ -58,7 +59,14 @@ class Record extends \Espo\Core\Services\Base
|
||||
if (!empty($entity) && !empty($id)) {
|
||||
$this->loadLinkMultipleFields($entity);
|
||||
$this->loadParentNameFields($entity);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($entity) && !empty($id)) {
|
||||
if (!$this->getAcl()->check($entity, 'read')) {
|
||||
throw new Forbidden();
|
||||
}
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
@@ -67,18 +75,7 @@ class Record extends \Espo\Core\Services\Base
|
||||
$fieldDefs = $this->getMetadata()->get('entityDefs.' . $this->entityName . '.fields', array());
|
||||
foreach ($fieldDefs as $field => $defs) {
|
||||
if ($defs['type'] == 'linkMultiple') {
|
||||
if ($entity->hasRelation($field) && $entity->hasField($field . 'Ids')) {
|
||||
$collection = $entity->get($field);
|
||||
$ids = array();
|
||||
$names = new \stdClass();
|
||||
foreach ($collection as $e) {
|
||||
$id = $e->id;
|
||||
$ids[] = $id;
|
||||
$names->$id = $e->get('name');
|
||||
}
|
||||
$entity->set($field . 'Ids', $ids);
|
||||
$entity->set($field . 'Names', $names);
|
||||
}
|
||||
$entity->loadLinkMultipleField($field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
39
application/Espo/Services/User.php
Normal file
39
application/Espo/Services/User.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Espo\Services;
|
||||
|
||||
class User extends Record
|
||||
{
|
||||
public function getEntity($id)
|
||||
{
|
||||
$entity = parent::getEntity($id);
|
||||
$entity->clear('password');
|
||||
return $entity;
|
||||
}
|
||||
|
||||
public function findEntities($params)
|
||||
{
|
||||
$result = parent::findEntities($params);
|
||||
foreach ($result['collection'] as $entity) {
|
||||
$entity->clear('password');
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function createEntity($data)
|
||||
{
|
||||
if (array_key_exists('password', $data)) {
|
||||
$data['password'] = md5($data['password']);
|
||||
}
|
||||
return parent::createEntity($data);
|
||||
}
|
||||
|
||||
public function updateEntity($id, $data)
|
||||
{
|
||||
if (array_key_exists('password', $data)) {
|
||||
$data['password'] = md5($data['password']);
|
||||
}
|
||||
return parent::updateEntity($id, $data);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user