Passed
Push — master ( 89d863...63ecd9 )
by Stefan
05:04
created

Logopath   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 190
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
dl 0
loc 190
rs 10
c 2
b 0
f 0
wmc 23
lcom 2
cbo 2

6 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 40 1
A addUserEmail() 0 4 1
A addScreenshot() 0 5 2
C determineMailsToSend() 0 48 12
B isEndUserContactUseful() 0 12 5
A weNeedToTalk() 0 5 2
1
<?php
2
3
/*
4
 * ******************************************************************************
5
 * Copyright 2011-2017 DANTE Ltd. and GÉANT on behalf of the GN3, GN3+, GN4-1 
6
 * and GN4-2 consortia
7
 *
8
 * License: see the web/copyright.php file in the file structure
9
 * ******************************************************************************
10
 */
11
12
namespace core\diag;
13
14
/**
15
 * This class evaluates the evidence of previous Telepath and/or Sociopath runs
16
 * and figures out whom to send emails to, and with that content. It then sends
17
 * these emails.
18
 */
19
class Logopath extends AbstractTest {
20
21
    /**
22
     * storing the end user's email, if he has given it to us
23
     * @var string
24
     */
25
    private $userEmail;
26
27
    /**
28
     * maybe the user has some additional evidence directly on his device?
29
     * @var string
30
     */
31
    private $additionalScreenshot;
32
    private $mailStack;
33
34
    const EDUROAM_OT = 0;
35
    const NRO_IDP = 1;
36
    const NRO_SP = 2;
37
    const IDP = 3;
38
    const SP = 4;
39
    const ENDUSER = 5;
40
41
    /** we start all our mails with a common prefix, internationalised
42
     *
43
     * @var string
44
     */
45
    private $subjectPrefix;
46
47
    /** and we end with a greeting/disclaimer
48
     *
49
     * @var string
50
     */
51
    private $finalGreeting;
52
53
    /**
54
     * We need to vet user inputs.
55
     * @var \web\lib\common\InputValidation
56
     */
57
    private $validatorInstance;
58
59
    /**
60
     * will be filled with the exact emails to send, by determineMailsToSend()
61
     * @var array
62
     */
63
    private $mailQueue;
64
    
65
    /**
66
     *
67
     * @var array
68
     */
69
    private $concreteRecipients;
70
71
// cases to consider
72
    const IDP_EXISTS_BUT_NO_DATABASE = 100;
73
74
    public function __construct() {
75
        parent::__construct();
76
        $this->userEmail = FALSE;
0 ignored issues
show
Documentation Bug introduced by
The property $userEmail was declared of type string, but FALSE is of type false. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
77
        $this->additionalScreenshot = FALSE;
0 ignored issues
show
Documentation Bug introduced by
The property $additionalScreenshot was declared of type string, but FALSE is of type false. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
78
        
79
        $this->mailQueue = [];
80
        $this->concreteRecipients = [];
81
        
82
        $this->validatorInstance = new \web\lib\common\InputValidation();
83
84
        $this->possibleFailureReasons = $_SESSION["SUSPECTS"] ?? []; // if we know nothing, don't talk to anyone
85
        $this->additionalFindings = $_SESSION["EVIDENCE"] ?? [];
86
87
        $this->subjectPrefix = _("[eduroam Diagnostics]") . " ";
88
        $this->finalGreeting = "\n"
89
                . _("(This service is in an early stage. We apologise if this is a false alert. If this is the case, please send an email report to [email protected], forwarding the entire message (including the 'SUSPECTS' and 'EVIDENCE' data at the end), and explain why this is a false positive.)")
90
                . "\n"
91
                . _("Yours sincerely,") . "\n"
92
                . "\n"
93
                . _("The eduroam diagnostics algorithms");
94
95
        $this->mailStack = [
96
            Logopath::IDP_EXISTS_BUT_NO_DATABASE => [
97
                "to" => [Logopath::NRO_IDP],
98
                "cc" => [Logopath::EDUROAM_OT],
99
                "bcc" => [],
100
                "reply-to" => [Logopath::EDUROAM_OT],
101
                "subject" => _("[POLICYVIOLATION NATIONAL] IdP with no entry in eduroam database"),
102
                "body" => _("Dear NRO administrator,") . "\n"
103
                . "\n"
104
                . wordwrap(sprintf(_("an end-user requested diagnostics for realm %s. Real-time connectivity checks determined that the realm exists, but we were unable to find an IdP with that realm in the eduroam database."), "foo.bar")) . "\n"
105
                . "\n"
106
                . _("By not listing IdPs in the eduroam database, you are violating the eduroam policy.") . "\n"
107
                . "\n"
108
                . _("Additionally, this creates operational issues. In particular, we are unable to direct end users to their IdP for further diagnosis/instructions because there are no contact points for that IdP in the database.") . "\n"
109
                . "\n"
110
                . "Please stop the policy violation ASAP by listing the IdP which is associated to this realm.",
111
            ],
112
        ];
113
    }
114
115
    /**
116
     * 
117
     * @param string $userEmail
118
     */
119
    public function addUserEmail($userEmail) {
120
// returns FALSE if it was not given or bogus, otherwise stores this as mail target
121
        $this->userEmail = $this->validatorInstance->email($userEmail);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->validatorInstance->email($userEmail) can also be of type false. However, the property $userEmail is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
122
    }
123
124
    public function addScreenshot($binaryData) {
125
        if ($this->validatorInstance->image($binaryData) === TRUE) {
126
            $this->additionalScreenshot = $binaryData;
127
        }
128
    }
129
130
    /**
131
     * looks at probabilities and evidence, and decides which mail scenario(s) to send
132
     */
133
    public function determineMailsToSend() {
134
        $this->mailQueue = [];
135
// check for IDP_EXISTS_BUT_NO_DATABASE
136
        if (!in_array(AbstractTest::INFRA_NONEXISTENTREALM, $this->possibleFailureReasons) && $this->additionalFindings[AbstractTest::INFRA_NONEXISTENTREALM]['DATABASE_STATUS']['ID2'] < 0) {
137
            $this->mailQueue[] = Logopath::IDP_EXISTS_BUT_NO_DATABASE;
138
        }
139
140
// after collecting all the conditions, find the target entities in all
141
// the mails, and check if they resolve to a known mail address. If they
142
// do not, this triggers more mails about missing contact info.
143
144
        $abstractRecipients = [];
145
        foreach ($this->mailQueue as $mail) {
146
            $abstractRecipients = array_unique(array_merge($this->mailStack[$mail]['to'], $this->mailStack[$mail]['cc'], $this->mailStack[$mail]['bcc'], $this->mailStack[$mail]['reply-to']));
147
        }
148
// who are those guys? Here is significant legwork in terms of DB lookup
149
        $this->concreteRecipients = [];
150
        foreach ($abstractRecipients as $oneRecipient) {
151
            switch ($oneRecipient) {
152
                case Logopath::EDUROAM_OT:
153
                    $this->concreteRecipients[$oneRecipient] = "[email protected]";
154
                    break;
155
                case Logopath::ENDUSER:
156
// will be filled when sending, from $this->userEmail
157
// hence the +1 below
158
                    break;
159
                case Logopath::IDP:
160
// TODO
161
                    break;
162
                case Logopath::NRO_IDP:
163
// TODO
164
                    break;
165
                case Logopath::SP:
166
// TODO
167
                    break;
168
                case Logopath::NRO_SP:
169
// TODO
170
                    break;
171
            }
172
        }
173
// now see if we lack pertinent recipient info, and add corresponding
174
// mails to the list
175
        if (count($abstractRecipients) != count($this->concreteRecipients) + 1) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
176
            // there is a discrepancy, do something ...
177
            // we need to add a mail to the next higher hierarchy level as escalation
178
            // but may also have to remove the lower one because we don't know the guy.
179
        }
180
    }
181
182
    /**
183
     * sees if it is useful to ask the user for his contact details or screenshots
184
     */
185
    public function isEndUserContactUseful() {
186
        $contactUseful = FALSE;
187
        $this->determineMailsToSend();
188
        foreach ($this->mailQueue as $oneMail) {
189
            if (in_array(Logopath::ENDUSER, $this->mailStack[$oneMail]['to']) ||
190
                    in_array(Logopath::ENDUSER, $this->mailStack[$oneMail]['cc']) ||
191
                    in_array(Logopath::ENDUSER, $this->mailStack[$oneMail]['bcc'])) {
192
                $contactUseful = TRUE;
193
            }
194
        }
195
        return $contactUseful;
196
    }
197
198
    /**
199
     * sends the mails. Only call this after either determineMailsToSend() or
200
     * isEndUserContactUseful(), otherwise it will do nothing.
201
     */
202
    public function weNeedToTalk() {
203
        foreach ($this->mailQueue as $oneMail) {
0 ignored issues
show
Unused Code introduced by
This foreach statement is empty and can be removed.

This check looks for foreach loops that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

Consider removing the loop.

Loading history...
204
            // just send the mail out, TODO
205
        }
206
    }
207
208
}
209