/** * {@inheritdoc} */ public function allowed(WorkflowTransition $transition, WorkflowInterface $workflow, EntityInterface $entity) { $to_state = $transition->getToState()->getId(); // Disable virtual state. if ($to_state == self::NON_STATE) { return FALSE; } $from_state = $this->getState($entity); // Allowed transitions are already filtered so we only need to check // for the transitions defined in the settings if they include a role the // user has. // @see: solution.settings.yml $allowed_conditions = \Drupal::config('solution.settings')->get('transitions'); if (\Drupal::currentUser()->hasPermission('bypass node access')) { return TRUE; } // Check if the user has one of the allowed system roles. $authorized_roles = isset($allowed_conditions[$to_state][$from_state]) ? $allowed_conditions[$to_state][$from_state] : []; $user = $this->workflowUserProvider->getUser(); if (array_intersect($authorized_roles, $user->getRoles())) { return TRUE; } // Check if the user has one of the allowed group roles. $membership = Og::getMembership($entity, $user); return $membership && array_intersect($authorized_roles, $membership->getRolesIds()); }
/** * Handles access to the solution add form through collection pages. * * @param \Drupal\rdf_entity\RdfInterface $rdf_entity * The RDF entity for which the solution is created. * * @return \Drupal\Core\Access\AccessResult * The access result object. */ public function createSolutionAccess(RdfInterface $rdf_entity) { $user = $this->currentUser(); if (empty($rdf_entity) && !$user->isAnonymous()) { return AccessResult::neutral(); } $membership = Og::getMembership($rdf_entity, $user); return !empty($membership) && $membership->hasPermission('create solution rdf_entity') ? AccessResult::allowed() : AccessResult::forbidden(); }
/** * {@inheritdoc} */ public function validateForm(array &$form, FormStateInterface $form_state) { parent::validateForm($form, $form_state); $collection = Rdf::load($form_state->getValue('collection_id')); // Only authenticated users can join a collection. /** @var \Drupal\user\UserInterface $user */ $user = User::load($form_state->getValue('user_id')); if ($user->isAnonymous()) { $form_state->setErrorByName('user', $this->t('<a href=":login">Log in</a> or <a href=":register">register</a> to change your group membership.', [':login' => Url::fromRoute('user.login'), ':register' => Url::fromRoute('user.register')])); } // Check if the user is already a member of the collection. if (Og::isMember($collection, $user)) { $form_state->setErrorByName('collection', $this->t('You already are a member of this collection.')); } }
/** * {@inheritdoc} * * We need to override default transitions allowed because this is also * dependant on the parent's moderation, system roles and organic groups * user roles. In the following method, the allowed transitions per * moderation are checked and then if the transition is allowed, the user * roles by the system and the organic groups are checked. */ public function allowed(WorkflowTransition $transition, WorkflowInterface $workflow, EntityInterface $entity) { $to_state = $transition->getToState()->getId(); // Disable virtual state. if ($to_state == self::NON_STATE) { return FALSE; } $from_state = $this->getState($entity); $parent = $this->getParent($entity); $is_moderated = self::MODERATED; if ($parent) { $is_moderated = $parent->bundle() == 'collection' ? $parent->field_ar_moderation->first()->value : $parent->field_is_moderation->first()->value; } $allowed_transitions = \Drupal::config('joinup_news.settings')->get('transitions'); // Some transitions are not allowed per parent's moderation. // Check for the transitions allowed. // @see: joinup_news.settings.yml if (!isset($allowed_transitions[$is_moderated][$to_state][$from_state])) { return FALSE; } // This Guard class's method called whenever the transitions are checked // even outside the entity CRUD forms. Cases like this is e.g. when trying // to edit the settings of the field. // In these cases, there is no parent entity so we need to check for it. if (empty($parent)) { return FALSE; } // Check if the user has one of the allowed system roles. $authorized_roles = $allowed_transitions[$is_moderated][$to_state][$from_state]; $user = \Drupal::currentUser(); if (array_intersect($authorized_roles, $user->getRoles())) { return TRUE; } // Check if the user has one of the allowed group roles. $membership = Og::getMembership($parent, $user->getAccount()); return $membership && array_intersect($authorized_roles, $membership->getRolesIds()); }
/** * {@inheritdoc} */ public function getRuntimeContexts(array $unqualified_context_ids) { $result = []; $value = NULL; if (($route_object = $this->routeMatch->getRouteObject()) && ($route_contexts = $route_object->getOption('parameters')) && isset($route_contexts['rdf_entity'])) { /** @var \Drupal\rdf_entity\RdfInterface $collection */ if ($collection = $this->routeMatch->getParameter('rdf_entity')) { if ($collection->bundle() == 'collection') { $value = $collection; } } } elseif (($route_parameters = $this->routeMatch->getParameters()) && in_array($this->routeMatch->getRouteName(), $this->getSupportedRoutes())) { foreach ($route_parameters as $route_parameter) { if ($route_parameter instanceof ContentEntityInterface) { $bundle = $route_parameter->bundle(); $entity_type = $route_parameter->getEntityTypeId(); // Check if the object is a og content entity. if (Og::isGroupContent($entity_type, $bundle) && ($groups = $this->membershipManager->getGroupIds($route_parameter, 'rdf_entity', 'collection'))) { // A content can belong to only one rdf_entity. // Check that the content is not an orphaned one. if ($collection_id = reset($groups['rdf_entity'])) { $collection = Rdf::load($collection_id); $value = $collection; } } } } } $cacheability = new CacheableMetadata(); $cacheability->setCacheContexts(['route']); $collection_context_definition = new ContextDefinition('entity', $this->t('Organic group provided by collection'), FALSE); $context = new Context($collection_context_definition, $value); $context->addCacheableDependency($cacheability); $result['og'] = $context; return $result; }
/** * Asserts that a group is owned by a user. * * An ownership is defined as having a specific set of roles in that group. * * @param AccountInterface $user * The user to be checked. * @param RdfInterface $group * The group entity. In this project, only rdf entities are groups. * @param array $roles * An array of roles to be checked. Roles must be passed as simple names * and not as full IDs. Names will be converted accordingly to IDs. * * @throws \Exception * Throws exception when the user is not a member or is not an owner. */ protected function assertOgGroupOwnership(AccountInterface $user, RdfInterface $group, $roles) { $membership = Og::getMembership($group, $user); if (empty($membership)) { throw new \Exception("User {$user->getAccountName()} is not a member of the {$group->label()} group."); } $roles = $this->convertOgRoleNamesToIds($roles, $group); if (array_intersect($roles, $membership->getRolesIds()) != $roles) { throw new \Exception("User {$user->getAccountName()} is not the owner of the {$group->label()} group."); } }
/** * Access check for the LeaveCollectionConfirmForm. * * @param \Drupal\rdf_entity\RdfInterface $rdf_entity * The collection that is on the verge of losing a member. * * @return \Drupal\Core\Access\AccessResult * The access result object. */ public static function access(RdfInterface $rdf_entity) { /** @var \Drupal\Core\Session\AccountProxyInterface $account_proxy */ $account_proxy = \Drupal::service('current_user'); // Deny access if the user is not logged in. if ($account_proxy->isAnonymous()) { return AccessResult::forbidden(); } // Only allow access if the current user is a member of the collection. $user = User::load($account_proxy->id()); return AccessResult::allowedIf(Og::isMember($rdf_entity, $user)); }