-
Notifications
You must be signed in to change notification settings - Fork 448
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pkp/pkp-lib#10571 limit email template access by user groups #10581
base: main
Are you sure you want to change the base?
Changes from all commits
45a86ac
f702945
ced55fc
13fdaf2
7ba258c
7b9785c
5411845
0f4d4f5
de58aab
362d0be
c4fe1b7
20aaeaa
7b1fae9
cf5219a
2ae5004
80068ac
d2e9586
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -235,13 +235,17 @@ public function getMainEmailTemplatesFilename() | |
* skipping others | ||
* @param bool $skipExisting If true, do not install email templates | ||
* that already exist in the database | ||
* @param bool $recordTemplateGroupAccess - If true, records the templates as unrestricted. For versions 3.6 or higher, this value should be set to true when calling `installEmailTemplates`. | ||
* By default, it is set to false to ensure compatibility with older processes (e.g., migrations) | ||
* where the `email_template_user_group_access` table may not exist at the time of execution. | ||
* | ||
*/ | ||
public function installEmailTemplates( | ||
string $templatesFile, | ||
array $locales = [], | ||
?string $emailKey = null, | ||
bool $skipExisting = false | ||
bool $skipExisting = false, | ||
$recordTemplateGroupAccess = false | ||
): bool { | ||
$xmlDao = new XMLDAO(); | ||
$data = $xmlDao->parseStruct($templatesFile, ['email']); | ||
|
@@ -281,6 +285,20 @@ public function installEmailTemplates( | |
$this->installAlternateEmailTemplates($contextId, $attrs['key']); | ||
} | ||
} | ||
|
||
if ($recordTemplateGroupAccess) { | ||
// Default to true if `isUnrestricted` is not set. | ||
$isUnrestricted = $attrs['isUnrestricted'] ?? '1'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this check is enough to cover any plugin-related issues or the email template XML not having this flag. I don't think you need the |
||
|
||
if ($isUnrestricted !== '1' && $isUnrestricted !== '0') { | ||
throw new Exception('Invalid value given for the `isUnrestricted` attribute on the ' . $attrs['key'] . ' template.'); | ||
} | ||
|
||
$contextIds = app()->get('context')->getIds(); | ||
foreach ($contextIds as $contextId) { | ||
Repo::emailTemplate()->markTemplateAsUnrestricted($attrs['key'], (bool)$isUnrestricted, $contextId); | ||
} | ||
} | ||
} | ||
return true; | ||
} | ||
|
@@ -381,7 +399,7 @@ public function installAlternateEmailTemplates(int $contextId, ?string $emailKey | |
'Tried to install email template as an alternate to `' . $alternateTo . '`, but no default template exists with this key. Installing ' . $alternateTo . ' email template first', | ||
E_USER_WARNING | ||
); | ||
$this->installEmailTemplates(Repo::emailTemplate()->dao->getMainEmailTemplatesFilename(), [], $alternateTo); | ||
$this->installEmailTemplates(Repo::emailTemplate()->dao->getMainEmailTemplatesFilename(), [], $alternateTo, false, true); | ||
} | ||
|
||
DB::table($this->table)->insert([ | ||
|
@@ -448,4 +466,37 @@ protected function getUniqueKey(EmailTemplate $emailTemplate): string | |
|
||
return $key; | ||
} | ||
|
||
|
||
/** | ||
* Sets email template's unrestricted status to their defaults | ||
*/ | ||
public function setTemplateDefaultUnrestirctedSetting(int $contextId, ?array $emailKeys = null) | ||
{ | ||
$xmlDao = new XMLDAO(); | ||
$data = $xmlDao->parseStruct($this->getMainEmailTemplatesFilename(), ['email']); | ||
|
||
if (!isset($data['email'])) { | ||
return false; | ||
} | ||
|
||
foreach ($data['email'] as $entry) { | ||
$attrs = $entry['attributes']; | ||
|
||
if ($emailKeys !== null && !in_array($attrs['key'], $emailKeys)) { | ||
continue; | ||
} | ||
|
||
// Default to true if `isUnrestricted` is not set. | ||
$isUnrestricted = $attrs['isUnrestricted'] ?? '1'; | ||
|
||
if ($isUnrestricted !== '1' && $isUnrestricted !== '0') { | ||
throw new Exception('Invalid value given for the `isUnrestricted` attribute on the ' . $attrs['key'] . ' template.'); | ||
} | ||
|
||
Repo::emailTemplate()->markTemplateAsUnrestricted($attrs['key'], (bool)$isUnrestricted, $contextId); | ||
} | ||
|
||
return true; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
<?php | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Needs file docblock. |
||
|
||
/** | ||
* @file classes/emailTemplate/EmailTemplateAccessGroup.php | ||
* | ||
* Copyright (c) 2014-2024 Simon Fraser University | ||
* Copyright (c) 2000-2024 John Willinsky | ||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING. | ||
* | ||
* @class EmailTemplateAccessGroup | ||
* | ||
* @ingroup emailTemplate | ||
* | ||
* @brief Eloquent model for email template user group access | ||
*/ | ||
|
||
namespace PKP\emailTemplate; | ||
|
||
use Eloquence\Behaviours\HasCamelCasing; | ||
use Illuminate\Database\Eloquent\Builder; | ||
use Illuminate\Database\Eloquent\Model; | ||
|
||
class EmailTemplateAccessGroup extends Model | ||
{ | ||
use HasCamelCasing; | ||
|
||
public $timestamps = false; | ||
protected $primaryKey = 'email_template_user_group_access_id'; | ||
protected $table = 'email_template_user_group_access'; | ||
protected $fillable = ['userGroupId', 'contextId', 'emailKey']; | ||
|
||
|
||
/** | ||
* Scope a query to only include email template access records for email templates with specific keys. | ||
*/ | ||
public function scopeWithEmailKey(Builder $query, ?array $keys): Builder | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would include a comment on what these scopes do for reference (e.g. optionally filter by email key). Same for the two below as well. |
||
{ | ||
return $query->when(!empty($keys), function ($query) use ($keys) { | ||
return $query->whereIn('email_key', $keys); | ||
}); | ||
} | ||
|
||
/** | ||
* Scope a query to only include email template access records that are related to a specific context ID. | ||
*/ | ||
public function scopeWithContextId(Builder $query, int $contextId): Builder | ||
{ | ||
return $query->where('context_id', $contextId); | ||
} | ||
|
||
/** | ||
* Scope a query to only include email template access records for specific user group IDs. | ||
*/ | ||
public function scopeWithGroupIds(Builder $query, array $ids): Builder | ||
{ | ||
return $query->whereIn('user_group_id', $ids); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mention this directly below, but I don't think this optional parameter will be necessary. I think the assumption of "unrestricted if no additional data provided" below is enough.