Completed
Branch master (91621e)
by Neomerx
01:35
created

Comments   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 103
Duplicated Lines 19.42 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 0
Metric Value
wmc 9
lcom 1
cbo 8
dl 20
loc 103
rs 10
c 0
b 0
f 0

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php namespace Limoncello\Tests\Auth\Authorization\PolicyEnforcement\Data\Policies;
2
3
/**
4
 * Copyright 2015-2017 [email protected]
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
use Limoncello\Auth\Authorization\PolicyAdministration\Advice;
20
use Limoncello\Auth\Authorization\PolicyAdministration\Logical;
21
use Limoncello\Auth\Authorization\PolicyAdministration\Obligation;
22
use Limoncello\Auth\Authorization\PolicyAdministration\Policy;
23
use Limoncello\Auth\Authorization\PolicyAdministration\Rule;
24
use Limoncello\Auth\Authorization\PolicyDecision\RuleAlgorithm;
25
use Limoncello\Auth\Contracts\Authorization\PolicyAdministration\EvaluationEnum;
26
use Limoncello\Auth\Contracts\Authorization\PolicyAdministration\MethodInterface;
27
use Limoncello\Auth\Contracts\Authorization\PolicyAdministration\PolicyInterface;
28
use Limoncello\Auth\Contracts\Authorization\PolicyAdministration\RuleInterface;
29
use Limoncello\Auth\Contracts\Authorization\PolicyInformation\ContextInterface;
30
use Limoncello\Tests\Auth\Authorization\PolicyEnforcement\Data\ContextProperties;
31
use Limoncello\Tests\Auth\Authorization\PolicyEnforcement\PolicyEnforcementTest;
32
33
/**
34
 * @package Limoncello\Tests\Auth
35
 */
36
abstract class Comments extends General
37
{
38
    /** Operation identity */
39
    const RESOURCE_TYPE = 'comments';
40
41
    /**
42
     * @return PolicyInterface
43
     */
44
    public static function getPolicies()
45
    {
46
        return (new Policy([
47
            static::onIndex(),
48
            static::onRead(),
49
            static::onCreate(),
50
            static::onUpdate(),
51
            static::onDelete(),
52
        ], RuleAlgorithm::permitOverrides())
53
        )
54
            ->setTarget(static::target(ContextProperties::PARAM_RESOURCE_TYPE, static::RESOURCE_TYPE))
55
            ->setName('Comments');
56
    }
57
58
    /**
59
     * @return RuleInterface
60
     */
61
    protected static function onIndex()
62
    {
63
        return (new Rule())->setTarget(static::targetOperationIndex())->setName('index');
64
    }
65
66
    /**
67
     * @return RuleInterface
68
     */
69
    protected static function onRead()
70
    {
71
        return (new Rule())->setTarget(static::targetOperationRead())->setName('read');
72
    }
73
74
    /**
75
     * @return RuleInterface
76
     */
77
    protected static function onCreate()
78
    {
79
        $obligation = new Obligation(EvaluationEnum::PERMIT, [PolicyEnforcementTest::class, 'markObligationAsCalled']);
80
        $advice     = new Advice(EvaluationEnum::PERMIT, [PolicyEnforcementTest::class, 'markAdviceAsCalled']);
81
82
        return (new Rule())->setTarget(static::targetMulti([
83
            ContextProperties::PARAM_OPERATION         => static::OPERATION_CREATE,
84
            ContextProperties::PARAM_USER_IS_SIGNED_IN => true,
85
        ]))->setName('create')->setObligations([$obligation])->setAdvice([$advice]);
86
    }
87
88
    /**
89
     * @return RuleInterface
90
     */
91
    protected static function onUpdate()
92
    {
93
        return (new Rule())
94
            ->setTarget(static::targetMulti([
95
                ContextProperties::PARAM_OPERATION         => static::OPERATION_UPDATE,
96
                ContextProperties::PARAM_USER_IS_SIGNED_IN => true,
97
            ]))
98
            ->setCondition(static::conditionIsCommentOwnerOrAdmin())
99
            ->setName('update');
100
    }
101
102
    /**
103
     * @return MethodInterface
104
     */
105
    protected static function conditionIsCommentOwnerOrAdmin()
106
    {
107
        return new Logical([static::class, 'isCommentOwnerOrAdmin']);
108
    }
109
110
    /**
111
     * @return RuleInterface
112
     */
113
    protected static function onDelete()
114
    {
115
        return (new Rule())
116
            ->setTarget(static::targetMulti([
117
                ContextProperties::PARAM_OPERATION         => static::OPERATION_DELETE,
118
                ContextProperties::PARAM_USER_IS_SIGNED_IN => true,
119
            ]))
120
            ->setCondition(static::conditionIsCommentOwnerOrAdmin())
121
            ->setName('delete');
122
    }
123
124
    /**
125
     * @param ContextInterface $context
126
     *
127
     * @return bool
128
     */
129
    public static function isCommentOwnerOrAdmin(ContextInterface $context)
130
    {
131
        $commentId = $context->get(ContextProperties::PARAM_RESOURCE_IDENTITY);
132
        // for testing purposes let's pretend current user is owner of comment with ID 123
133
        $isOwner = $commentId === 123;
134
        $result  = $isOwner === true || static::isAdmin($context) === true;
135
136
        return $result;
137
    }
138
}
139