SlackInvite::canView()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
4
/**
5
 * Class SlackInvite
6
 *
7
 * @property string $Name
8
 * @property string $Email
9
 * @property boolean $Invited
10
 * @property string $Message
11
 */
12
class SlackInvite extends DataObject implements PermissionProvider
0 ignored issues
show
Bug introduced by
The type DataObject was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
Bug introduced by
The type PermissionProvider was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
{
14
    private static $db = [
15
        'Name'    => 'Varchar(255)',
16
        'Email'   => 'Varchar(255)',
17
        'Invited' => 'Boolean(false)',
18
        'Message' => 'Varchar(255)',
19
    ];
20
21
    private static $summary_fields = [
22
        'Created',
23
        'Name',
24
        'Email',
25
        'Invited.Nice',
26
        'Message'
27
    ];
28
29
    private static $field_labels = [
30
        'Created'      => 'Invite requested on',
31
        'Name'         => 'Name',
32
        'Email'        => 'Email address',
33
        'Invited.Nice' => 'Invite successful'
34
    ];
35
36
    private static $messages = [
37
        'not_authed'        => 'No valid Slack Token provided, please check your settings',
38
        'already_invited'   => 'User has already received an email invitation',
39
        'already_in_team'   => 'User is already part of the team',
40
        'channel_not_found' => 'Provided channel ID does not match an existing channel in your workspace',
41
        'sent_recently'     => 'When using resend=true, the email has been sent recently already',
42
        'user_disabled'     => 'User account has been deactivated',
43
        'missing_scope'     => 'Using an access_token not authorized for "client" scope',
44
        'invalid_email'     => 'Invalid email address (e.g. "qwe"). Note that Slack does not recognize some email addresses even though they are technically valid. This is a known issue.',
45
        'not_allowed'       => 'When SSO is enabeld this method can not be used to invite new users except guests. The SCIM API needs to be used instead to invite new users. '
46
    ];
47
48
    private static $better_buttons_actions = [
0 ignored issues
show
Unused Code introduced by
The property $better_buttons_actions is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
49
        'resendInvite'
50
    ];
51
52
    public function getCMSFields()
53
    {
54
        $fields = parent::getCMSFields();
55
        $fields->removeByName(['Invited']);
56
        if (!$this->Invited) {
57
            $fields->addFieldToTab(
58
                'Root.Main',
59
                LiteralField::create(
0 ignored issues
show
Bug introduced by
The type LiteralField was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
60
                    'resend',
61
                    _t('SlackInvite.Resend', '<p>To resend an invite, click the resend button in the overview</p>')
0 ignored issues
show
Bug introduced by
The function _t was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

61
                    /** @scrutinizer ignore-call */ 
62
                    _t('SlackInvite.Resend', '<p>To resend an invite, click the resend button in the overview</p>')
Loading history...
62
                )
63
            );
64
        }
65
        $fields->addFieldToTab('Root.Main', ReadonlyField::create('Message', 'API Message'));
0 ignored issues
show
Bug introduced by
The type ReadonlyField was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
66
        $fields->addFieldToTab(
67
            'Root.Main',
68
            ReadonlyField::create('InvitedStatus', 'Invite successful', $this->dbObject('Invited')->Nice())
69
        );
70
71
        return $fields;
72
    }
73
74
    /**
75
     * If BetterButtons is installed, add a button to resend or retry
76
     * @return mixed
77
     */
78
    public function getBetterButtonsActions()
79
    {
80
        $fields = parent::getBetterButtonsActions();
81
        if ($this->Invited) {
82
            $fields->push(
83
                BetterButtonCustomAction::create('resendInvite', 'Resend')
0 ignored issues
show
Bug introduced by
The type BetterButtonCustomAction was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
84
                ->setRedirectType(BetterButtonCustomAction::REFRESH)
85
            );
86
        } else {
87
            $fields->push(
88
                BetterButtonCustomAction::create('resendInvite', 'Retry')
89
                ->setRedirectType(BetterButtonCustomAction::REFRESH)
90
            );
91
        }
92
93
        return $fields;
94
    }
95
96
    /**
97
     * If the user isn't invited yet, send out the invite
98
     * @throws ValidationException
99
     */
100
    public function onBeforeWrite()
101
    {
102
        parent::onBeforeWrite();
103
        // Only attempt to send when there is no ID
104
        // This prevents retrying from the CMS from ending up in an endless loop
105
        if (!$this->ID) {
106
            $this->inviteUser();
107
        }
108
    }
109
110
111
    /**
112
     * This method is public, so it can be addressed from the CMS.
113
     *
114
     * @param bool $resend
115
     * @throws ValidationException
116
     */
117
    public function inviteUser($resend = false)
118
    {
119
        /** @var SiteConfig $config */
120
        $config = SiteConfig::current_site_config();
0 ignored issues
show
Bug introduced by
The type SiteConfig was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
121
        // Break if there is a configuration error
122
        if (!$config->SlackURL || !$config->SlackToken || !$config->SlackChannel) {
123
            $this->Invited = false;
124
        } else {
125
            /** @var RestfulService $service with an _uncached_ response */
126
            $params = [
127
                'token'      => $config->SlackToken,
128
                'type'       => 'post',
129
                'email'      => $this->Email,
130
                'set_active' => true,
131
                'channel'    => $config->SlackChannel,
132
                'scope'      => 'identify,read,post,client',
133
            ];
134
135
            if ($resend) {
136
                $params['resend'] = true;
137
            }
138
            if ($this->Name) {
139
                $params['first_name'] = $this->Name;
140
            }
141
142
            $this->doRequestEmail($config, $params);
143
        }
144
    }
145
146
147
    /**
148
     * @param SiteConfig $config
149
     * @param array $params
150
     * @return bool|$this
151
     * @throws \ValidationException
152
     */
153
    private function doRequestEmail($config, $params)
154
    {
155
        $now = time();
156
        $service = RestfulService::create($config->SlackURL, 0);
0 ignored issues
show
Bug introduced by
The type RestfulService was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
157
158
        $response = $service->request('/api/users.admin.invite?t=' . $now, 'POST', $params);
159
        $result = Convert::json2array($response->getBody());
0 ignored issues
show
Bug introduced by
The type Convert was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
160
161
        if (isset($result['error'])) {
162
            /** @noinspection PhpParamsInspection */
163
            SS_Log::log($result['error'], SS_Log::ERR);
0 ignored issues
show
Bug introduced by
The type SS_Log was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
164
            $this->Message = static::$messages[$result['error']];
0 ignored issues
show
Bug introduced by
Since $messages is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $messages to at least protected.
Loading history...
165
166
            if ($result['error'] === 'already_invited' || $result['error'] === 'already_in_team') {
167
                $this->Message .= '; Invite successful';
168
                $this->Invited = true;
169
            }
170
        } else {
171
            $this->Message = 'Invite successful';
172
            $this->Invited = (bool)$result['ok'];
173
        }
174
175
        if ($this->Invited) {
176
            $this->deleteDuplicates();
177
        }
178
179
        $isModelAdmin = Controller::curr() instanceof ModelAdmin;
0 ignored issues
show
Bug introduced by
The type Controller was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
Bug introduced by
The type ModelAdmin was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
180
        /*
181
         * Only write here if we're in the CMS, don't write if the invite failed
182
         * As that will cause a possible infinite loop
183
         */
184
        if ((bool)$this->Invited === true && $isModelAdmin) {
185
            $this->write();
186
187
            return $this->Message;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->Message also could return the type string which is incompatible with the documented return type boolean|SlackInvite.
Loading history...
188
        } elseif ($isModelAdmin) {
189
            return $this->Message;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->Message also could return the type string which is incompatible with the documented return type boolean|SlackInvite.
Loading history...
190
        }
191
192
        return $this;
193
    }
194
195
    /**
196
     * Remove duplicates after a successful invite
197
     */
198
    public function deleteDuplicates()
199
    {
200
        /** @var DataList|SlackInvite[] $thisDuplicates */
201
        $thisDuplicates = static::get()
202
            ->filter(['Email' => $this->Email, 'Invited' => false])
203
            ->exclude(['ID' => $this->ID]);
204
205
        if ($this->Invited === true && $thisDuplicates->count() > 0) {
206
            // This user tried multiple times, now that Invited is true, let's delete the others
207
            $thisDuplicates->removeAll();
208
        }
209
    }
210
211
    /**
212
     * Re-send this invite
213
     * @throws ValidationException
214
     */
215
    public function resendInvite()
216
    {
217
        // Resend the invite. If the user has been invited before it should re-send
218
        // The instance is needed so we know if we should write inside the `inviteUser` method
219
        $this->inviteUser((bool)$this->Invited);
220
    }
221
222
    /**
223
     * Permissions
224
     *
225
     * @return array
226
     */
227
    public function providePermissions()
228
    {
229
        return [
230
            'EDIT_SLACKINVITE'   => [
231
                'name'     => _t('SlackInvite.PERMISSION_EDIT_DESCRIPTION', 'Edit Slack invites'),
0 ignored issues
show
Bug introduced by
The function _t was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

231
                'name'     => /** @scrutinizer ignore-call */ _t('SlackInvite.PERMISSION_EDIT_DESCRIPTION', 'Edit Slack invites'),
Loading history...
232
                'category' => _t('Permissions.SLACK_SLACKINVITE', 'Slack permissions'),
233
                'help'     => _t(
234
                    'SlackInvite.PERMISSION_EDIT_HELP',
235
                    'Permission required to edit existing Slack invites.'
236
                )
237
            ],
238
            'DELETE_SLACKINVITE' => [
239
                'name'     => _t('SlackInvite.PERMISSION_DELETE_DESCRIPTION', 'Delete Slack invites'),
240
                'category' => _t('Permissions.SLACK_SLACKINVITE', 'Slack permissions'),
241
                'help'     => _t(
242
                    'SlackInvite.PERMISSION_DELETE_HELP',
243
                    'Permission required to delete existing Slack invites.'
244
                )
245
            ],
246
            'VIEW_SLACKINVITE'   => [
247
                'name'     => _t('SlackInvite.PERMISSION_VIEW_DESCRIPTION', 'View Slack invites'),
248
                'category' => _t('Permissions.SLACK_SLACKINVITE', 'Slack permissions'),
249
                'help'     => _t(
250
                    'SlackInvite.PERMISSION_VIEW_HELP',
251
                    'Permission required to view existing Slack invites.'
252
                )
253
            ],
254
        ];
255
    }
256
257
258
    /**
259
     * Don't create them from the CMS
260
     * {@inheritdoc}
261
     */
262
    public function canCreate($member = null, $context = [])
263
    {
264
        return false;
265
    }
266
267
    /**
268
     * Edit is useful for if someone mis-typed it's email address
269
     * {@inheritdoc}
270
     */
271
    public function canEdit($member = null)
272
    {
273
        return Permission::checkMember($member, array('EDIT_SLACKINVITE', 'CMS_ACCESS_SlackInviteAdmin'));
0 ignored issues
show
Bug introduced by
The type Permission was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
274
    }
275
276
    /**
277
     * {@inheritdoc}
278
     */
279
    public function canDelete($member = null)
280
    {
281
        return Permission::checkMember($member, array('DELETE_SLACKINVITE', 'CMS_ACCESS_SlackInviteAdmin'));
282
    }
283
284
    /**
285
     * {@inheritdoc}
286
     */
287
    public function canView($member = null)
288
    {
289
        return Permission::checkMember($member, array('VIEW_SLACKINVITE', 'CMS_ACCESS_SlackInviteAdmin'));
290
    }
291
}
292