Browse Source

OCS API endpoint to resend welcome message

* send a POST request to ocs/v1.php/cloud/users/USERNAME/resendWelcomeMessage to trigger
  the welcome message to be send
* fixes #3367

example curl statement:

  curl -i https://example.org/ocs/v1.php/cloud/users/USERNAME/welcome -H  "OCS-APIRequest: true" -u admin:password -X POST

Signed-off-by: Morris Jobke <hey@morrisjobke.de>
tags/v12.0.0beta1
Morris Jobke 7 years ago
parent
commit
50f3efad6f
No account linked to committer's email address

+ 1
- 0
apps/provisioning_api/appinfo/routes.php View File

@@ -56,6 +56,7 @@ return [
['root' => '/cloud', 'name' => 'Users#getUserSubAdminGroups', 'url' => '/users/{userId}/subadmins', 'verb' => 'GET'],
['root' => '/cloud', 'name' => 'Users#addSubAdmin', 'url' => '/users/{userId}/subadmins', 'verb' => 'POST'],
['root' => '/cloud', 'name' => 'Users#removeSubAdmin', 'url' => '/users/{userId}/subadmins', 'verb' => 'DELETE'],
['root' => '/cloud', 'name' => 'Users#resendWelcomeMessage', 'url' => '/users/{userId}/welcome', 'verb' => 'POST'],

// Config
['name' => 'AppConfig#getApps', 'url' => '/api/v1/config/apps', 'verb' => 'GET'],

+ 100
- 1
apps/provisioning_api/lib/Controller/UsersController.php View File

@@ -32,6 +32,7 @@ namespace OCA\Provisioning_API\Controller;
use OC\Accounts\AccountManager;
use \OC_Helper;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\OCS\OCSException;
use OCP\AppFramework\OCS\OCSForbiddenException;
use OCP\AppFramework\OCSController;
@@ -41,8 +42,11 @@ use OCP\IGroup;
use OCP\IGroupManager;
use OCP\ILogger;
use OCP\IRequest;
use OCP\IURLGenerator;
use OCP\IUserManager;
use OCP\IUserSession;
use OCP\L10N\IFactory;
use OCP\Mail\IMailer;

class UsersController extends OCSController {

@@ -58,6 +62,16 @@ class UsersController extends OCSController {
private $accountManager;
/** @var ILogger */
private $logger;
/** @var string */
private $fromMailAddress;
/** @var IURLGenerator */
private $urlGenerator;
/** @var IMailer */
private $mailer;
/** @var \OC_Defaults */
private $defaults;
/** @var IFactory */
private $l10nFactory;

/**
* @param string $appName
@@ -68,6 +82,11 @@ class UsersController extends OCSController {
* @param IUserSession $userSession
* @param AccountManager $accountManager
* @param ILogger $logger
* @param string $fromMailAddress
* @param IURLGenerator $urlGenerator
* @param IMailer $mailer
* @param \OC_Defaults $defaults
* @param IFactory $l10nFactory
*/
public function __construct($appName,
IRequest $request,
@@ -76,7 +95,12 @@ class UsersController extends OCSController {
IGroupManager $groupManager,
IUserSession $userSession,
AccountManager $accountManager,
ILogger $logger) {
ILogger $logger,
$fromMailAddress,
IURLGenerator $urlGenerator,
IMailer $mailer,
\OC_Defaults $defaults,
IFactory $l10nFactory) {
parent::__construct($appName, $request);

$this->userManager = $userManager;
@@ -85,6 +109,11 @@ class UsersController extends OCSController {
$this->userSession = $userSession;
$this->accountManager = $accountManager;
$this->logger = $logger;
$this->fromMailAddress = $fromMailAddress;
$this->urlGenerator = $urlGenerator;
$this->mailer = $mailer;
$this->defaults = $defaults;
$this->l10nFactory = $l10nFactory;
}

/**
@@ -718,4 +747,74 @@ class UsersController extends OCSController {
}
return $data;
}

/**
* @NoAdminRequired
* @PasswordConfirmationRequired
*
* resend welcome message
*
* @param string $userId
* @return DataResponse
* @throws OCSException
*/
public function resendWelcomeMessage($userId) {
$currentLoggedInUser = $this->userSession->getUser();

$targetUser = $this->userManager->get($userId);
if($targetUser === null) {
throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
}

// Check if admin / subadmin
$subAdminManager = $this->groupManager->getSubAdmin();
if(!$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
&& !$this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
// No rights
throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
}

$email = $targetUser->getEMailAddress();
if ($email === '' || $email === null) {
throw new OCSException('Email address not available', 101);
}
$username = $targetUser->getUID();
$lang = $this->config->getUserValue($username, 'core', 'lang', 'en');
if (!$this->l10nFactory->languageExists('settings', $lang)) {
$lang = 'en';
}

$l10n = $this->l10nFactory->get('settings', $lang);

// data for the mail template
$mailData = [
'username' => $username,
'url' => $this->urlGenerator->getAbsoluteURL('/')
];

// FIXME: set users language in email
$mail = new TemplateResponse('settings', 'email.new_user', $mailData, 'blank');
$mailContent = $mail->render();

// FIXME: set users language in email
$mail = new TemplateResponse('settings', 'email.new_user_plain_text', $mailData, 'blank');
$plainTextMailContent = $mail->render();

$subject = $l10n->t('Your %s account was created', [$this->defaults->getName()]);

try {
$message = $this->mailer->createMessage();
$message->setTo([$email => $username]);
$message->setSubject($subject);
$message->setHtmlBody($mailContent);
$message->setPlainBody($plainTextMailContent);
$message->setFrom([$this->fromMailAddress => $this->defaults->getName()]);
$this->mailer->send($message);
} catch(\Exception $e) {
$this->logger->error("Can't send new user mail to $email: " . $e->getMessage(), array('app' => 'settings'));
throw new OCSException('Sending email failed', 102);
}

return new DataResponse();
}
}

+ 518
- 0
apps/provisioning_api/tests/Controller/UsersControllerTest.php View File

@@ -38,10 +38,15 @@ use OCP\AppFramework\Http\DataResponse;
use OCP\IConfig;
use OCP\IGroup;
use OCP\ILogger;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\IL10N;
use OCP\IRequest;
use OCP\IURLGenerator;
use OCP\IUser;
use OCP\IUserManager;
use OCP\IUserSession;
use OCP\L10N\IFactory;
use OCP\Mail\IMailer;
use PHPUnit_Framework_MockObject_MockObject;
use Test\TestCase;

@@ -71,6 +76,18 @@ class UsersControllerTest extends TestCase {
/** @var IRequest|PHPUnit_Framework_MockObject_MockObject */
protected $request;

/** @var IURLGenerator | PHPUnit_Framework_MockObject_MockObject */
private $urlGenerator;

/** @var IMailer | PHPUnit_Framework_MockObject_MockObject */
private $mailer;

/** @var \OC_Defaults | PHPUnit_Framework_MockObject_MockObject */
private $defaults;

/** @var IFactory | PHPUnit_Framework_MockObject_MockObject */
private $l10nFactory;

protected function setUp() {
parent::setUp();

@@ -81,6 +98,11 @@ class UsersControllerTest extends TestCase {
$this->logger = $this->createMock(ILogger::class);
$this->request = $this->createMock(IRequest::class);
$this->accountManager = $this->createMock(AccountManager::class);
$this->urlGenerator = $this->createMock(IURLGenerator::class);
$this->mailer = $this->createMock(IMailer::class);
$this->defaults = $this->createMock(\OC_Defaults::class);
$this->l10nFactory = $this->createMock(IFactory::class);

$this->api = $this->getMockBuilder(UsersController::class)
->setConstructorArgs([
'provisioning_api',
@@ -91,6 +113,11 @@ class UsersControllerTest extends TestCase {
$this->userSession,
$this->accountManager,
$this->logger,
'test@example.org',
$this->urlGenerator,
$this->mailer,
$this->defaults,
$this->l10nFactory
])
->setMethods(['fillStorageInfo'])
->getMock();
@@ -2590,6 +2617,11 @@ class UsersControllerTest extends TestCase {
$this->userSession,
$this->accountManager,
$this->logger,
'',
$this->urlGenerator,
$this->mailer,
$this->defaults,
$this->l10nFactory
])
->setMethods(['getUserData'])
->getMock();
@@ -2648,6 +2680,11 @@ class UsersControllerTest extends TestCase {
$this->userSession,
$this->accountManager,
$this->logger,
'',
$this->urlGenerator,
$this->mailer,
$this->defaults,
$this->l10nFactory
])
->setMethods(['getUserData'])
->getMock();
@@ -2671,4 +2708,485 @@ class UsersControllerTest extends TestCase {
$this->assertSame($expected, $api->getUser('uid')->getData());
}

/**
* @expectedException \OCP\AppFramework\OCS\OCSException
* @expectedExceptionCode 997
*/
public function testResendWelcomeMessageWithNotExistingTargetUser() {
$this->userManager
->expects($this->once())
->method('get')
->with('NotExistingUser')
->will($this->returnValue(null));

$this->api->resendWelcomeMessage('NotExistingUser');
}

/**
* @expectedException \OCP\AppFramework\OCS\OCSException
* @expectedExceptionCode 997
*/
public function testResendWelcomeMessageAsSubAdminAndUserIsNotAccessible() {
$loggedInUser = $this->getMockBuilder('OCP\IUser')
->disableOriginalConstructor()
->getMock();
$loggedInUser
->expects($this->exactly(1))
->method('getUID')
->will($this->returnValue('subadmin'));
$targetUser = $this->getMockBuilder('OCP\IUser')
->disableOriginalConstructor()
->getMock();
$this->userSession
->expects($this->once())
->method('getUser')
->will($this->returnValue($loggedInUser));
$this->userManager
->expects($this->once())
->method('get')
->with('UserToGet')
->will($this->returnValue($targetUser));
$this->groupManager
->expects($this->once())
->method('isAdmin')
->with('subadmin')
->will($this->returnValue(false));
$subAdminManager = $this->getMockBuilder('OC\SubAdmin')
->disableOriginalConstructor()
->getMock();
$subAdminManager
->expects($this->once())
->method('isUserAccessible')
->with($loggedInUser, $targetUser)
->will($this->returnValue(false));
$this->groupManager
->expects($this->once())
->method('getSubAdmin')
->will($this->returnValue($subAdminManager));

$this->api->resendWelcomeMessage('UserToGet');
}

/**
* @expectedException \OCP\AppFramework\OCS\OCSException
* @expectedExceptionCode 101
* @expectedExceptionMessage Email address not available
*/
public function testResendWelcomeMessageNoEmail() {
$loggedInUser = $this->getMockBuilder('OCP\IUser')
->disableOriginalConstructor()
->getMock();
$targetUser = $this->getMockBuilder('OCP\IUser')
->disableOriginalConstructor()
->getMock();
$this->userSession
->expects($this->once())
->method('getUser')
->will($this->returnValue($loggedInUser));
$this->userManager
->expects($this->once())
->method('get')
->with('UserToGet')
->will($this->returnValue($targetUser));
$subAdminManager = $this->getMockBuilder('OC\SubAdmin')
->disableOriginalConstructor()
->getMock();
$subAdminManager
->expects($this->once())
->method('isUserAccessible')
->with($loggedInUser, $targetUser)
->will($this->returnValue(true));
$this->groupManager
->expects($this->once())
->method('getSubAdmin')
->will($this->returnValue($subAdminManager));
$targetUser
->expects($this->once())
->method('getEmailAddress')
->will($this->returnValue(''));

$this->api->resendWelcomeMessage('UserToGet');
}

/**
* @expectedException \OCP\AppFramework\OCS\OCSException
* @expectedExceptionCode 101
* @expectedExceptionMessage Email address not available
*/
public function testResendWelcomeMessageNullEmail() {
$loggedInUser = $this->getMockBuilder('OCP\IUser')
->disableOriginalConstructor()
->getMock();
$targetUser = $this->getMockBuilder('OCP\IUser')
->disableOriginalConstructor()
->getMock();
$this->userSession
->expects($this->once())
->method('getUser')
->will($this->returnValue($loggedInUser));
$this->userManager
->expects($this->once())
->method('get')
->with('UserToGet')
->will($this->returnValue($targetUser));
$subAdminManager = $this->getMockBuilder('OC\SubAdmin')
->disableOriginalConstructor()
->getMock();
$subAdminManager
->expects($this->once())
->method('isUserAccessible')
->with($loggedInUser, $targetUser)
->will($this->returnValue(true));
$this->groupManager
->expects($this->once())
->method('getSubAdmin')
->will($this->returnValue($subAdminManager));
$targetUser
->expects($this->once())
->method('getEmailAddress')
->will($this->returnValue(null));

$this->api->resendWelcomeMessage('UserToGet');
}

public function testResendWelcomeMessageSuccess() {
$loggedInUser = $this->getMockBuilder('OCP\IUser')
->disableOriginalConstructor()
->getMock();
$targetUser = $this->getMockBuilder('OCP\IUser')
->disableOriginalConstructor()
->getMock();
$targetUser
->method('getUID')
->willReturn('user-id');
$this->userSession
->expects($this->once())
->method('getUser')
->will($this->returnValue($loggedInUser));
$this->userManager
->expects($this->once())
->method('get')
->with('UserToGet')
->will($this->returnValue($targetUser));
$subAdminManager = $this->getMockBuilder('OC\SubAdmin')
->disableOriginalConstructor()
->getMock();
$subAdminManager
->expects($this->once())
->method('isUserAccessible')
->with($loggedInUser, $targetUser)
->will($this->returnValue(true));
$this->groupManager
->expects($this->once())
->method('getSubAdmin')
->will($this->returnValue($subAdminManager));
$targetUser
->expects($this->once())
->method('getEmailAddress')
->will($this->returnValue('abc@example.org'));
$message = $this->getMockBuilder('\OC\Mail\Message')
->disableOriginalConstructor()->getMock();
$message
->expects($this->at(0))
->method('setTo')
->with(['abc@example.org' => 'user-id']);
$message
->expects($this->at(1))
->method('setSubject')
->with('Your account was created');
$htmlBody = new TemplateResponse(
'settings',
'email.new_user',
[
'username' => 'user-id',
'url' => null,
],
'blank'
);
$message
->expects($this->at(2))
->method('setHtmlBody')
->with($htmlBody->render());
$plainBody = new TemplateResponse(
'settings',
'email.new_user_plain_text',
[
'username' => 'user-id',
'url' => null,
],
'blank'
);
$message
->expects($this->at(3))
->method('setPlainBody')
->with($plainBody->render());
$message
->expects($this->at(4))
->method('setFrom')
->with(['test@example.org' => null]);

$this->mailer
->expects($this->at(0))
->method('createMessage')
->will($this->returnValue($message));
$this->mailer
->expects($this->at(1))
->method('send')
->with($message);

$this->config
->expects($this->at(0))
->method('getUserValue')
->with('user-id', 'core', 'lang')
->willReturn('es');
$l10n = $this->getMockBuilder(IL10N::class)
->disableOriginalConstructor()
->getMock();
$l10n
->expects($this->at(0))
->method('t')
->with('Your %s account was created', [null])
->willReturn('Your account was created');
$this->l10nFactory
->expects($this->at(0))
->method('languageExists')
->with('settings', 'es')
->willReturn(true);
$this->l10nFactory
->expects($this->at(1))
->method('get')
->with('settings', 'es')
->willReturn($l10n);

$this->api->resendWelcomeMessage('UserToGet');
}

public function testResendWelcomeMessageSuccessWithFallbackLanguage() {
$loggedInUser = $this->getMockBuilder('OCP\IUser')
->disableOriginalConstructor()
->getMock();
$targetUser = $this->getMockBuilder('OCP\IUser')
->disableOriginalConstructor()
->getMock();
$targetUser
->method('getUID')
->willReturn('user-id');
$this->userSession
->expects($this->once())
->method('getUser')
->will($this->returnValue($loggedInUser));
$this->userManager
->expects($this->once())
->method('get')
->with('UserToGet')
->will($this->returnValue($targetUser));
$subAdminManager = $this->getMockBuilder('OC\SubAdmin')
->disableOriginalConstructor()
->getMock();
$subAdminManager
->expects($this->once())
->method('isUserAccessible')
->with($loggedInUser, $targetUser)
->will($this->returnValue(true));
$this->groupManager
->expects($this->once())
->method('getSubAdmin')
->will($this->returnValue($subAdminManager));
$targetUser
->expects($this->once())
->method('getEmailAddress')
->will($this->returnValue('abc@example.org'));
$message = $this->getMockBuilder('\OC\Mail\Message')
->disableOriginalConstructor()->getMock();
$message
->expects($this->at(0))
->method('setTo')
->with(['abc@example.org' => 'user-id']);
$message
->expects($this->at(1))
->method('setSubject')
->with('Your account was created');
$htmlBody = new TemplateResponse(
'settings',
'email.new_user',
[
'username' => 'user-id',
'url' => null,
],
'blank'
);
$message
->expects($this->at(2))
->method('setHtmlBody')
->with($htmlBody->render());
$plainBody = new TemplateResponse(
'settings',
'email.new_user_plain_text',
[
'username' => 'user-id',
'url' => null,
],
'blank'
);
$message
->expects($this->at(3))
->method('setPlainBody')
->with($plainBody->render());
$message
->expects($this->at(4))
->method('setFrom')
->with(['test@example.org' => null]);

$this->mailer
->expects($this->at(0))
->method('createMessage')
->will($this->returnValue($message));
$this->mailer
->expects($this->at(1))
->method('send')
->with($message);

$this->config
->expects($this->at(0))
->method('getUserValue')
->with('user-id', 'core', 'lang')
->willReturn('es');
$l10n = $this->getMockBuilder(IL10N::class)
->disableOriginalConstructor()
->getMock();
$l10n
->expects($this->at(0))
->method('t')
->with('Your %s account was created', [null])
->willReturn('Your account was created');
$this->l10nFactory
->expects($this->at(0))
->method('languageExists')
->with('settings', 'es')
->willReturn(false);
$this->l10nFactory
->expects($this->at(1))
->method('get')
->with('settings', 'en')
->willReturn($l10n);

$this->api->resendWelcomeMessage('UserToGet');
}

/**
* @expectedException \OCP\AppFramework\OCS\OCSException
* @expectedExceptionCode 102
* @expectedExceptionMessage Sending email failed
*/
public function testResendWelcomeMessageFailed() {
$loggedInUser = $this->getMockBuilder('OCP\IUser')
->disableOriginalConstructor()
->getMock();
$targetUser = $this->getMockBuilder('OCP\IUser')
->disableOriginalConstructor()
->getMock();
$targetUser
->method('getUID')
->willReturn('user-id');
$this->userSession
->expects($this->once())
->method('getUser')
->will($this->returnValue($loggedInUser));
$this->userManager
->expects($this->once())
->method('get')
->with('UserToGet')
->will($this->returnValue($targetUser));
$subAdminManager = $this->getMockBuilder('OC\SubAdmin')
->disableOriginalConstructor()
->getMock();
$subAdminManager
->expects($this->once())
->method('isUserAccessible')
->with($loggedInUser, $targetUser)
->will($this->returnValue(true));
$this->groupManager
->expects($this->once())
->method('getSubAdmin')
->will($this->returnValue($subAdminManager));
$targetUser
->expects($this->once())
->method('getEmailAddress')
->will($this->returnValue('abc@example.org'));
$message = $this->getMockBuilder('\OC\Mail\Message')
->disableOriginalConstructor()->getMock();
$message
->expects($this->at(0))
->method('setTo')
->with(['abc@example.org' => 'user-id']);
$message
->expects($this->at(1))
->method('setSubject')
->with('Your account was created');
$htmlBody = new TemplateResponse(
'settings',
'email.new_user',
[
'username' => 'user-id',
'url' => null,
],
'blank'
);
$message
->expects($this->at(2))
->method('setHtmlBody')
->with($htmlBody->render());
$plainBody = new TemplateResponse(
'settings',
'email.new_user_plain_text',
[
'username' => 'user-id',
'url' => null,
],
'blank'
);
$message
->expects($this->at(3))
->method('setPlainBody')
->with($plainBody->render());
$message
->expects($this->at(4))
->method('setFrom')
->with(['test@example.org' => null]);

$this->mailer
->expects($this->at(0))
->method('createMessage')
->will($this->returnValue($message));
$this->mailer
->expects($this->at(1))
->method('send')
->will($this->throwException(new \Exception()));

$this->config
->expects($this->at(0))
->method('getUserValue')
->with('user-id', 'core', 'lang')
->willReturn('es');
$l10n = $this->getMockBuilder(IL10N::class)
->disableOriginalConstructor()
->getMock();
$l10n
->expects($this->at(0))
->method('t')
->with('Your %s account was created', [null])
->willReturn('Your account was created');
$this->l10nFactory
->expects($this->at(0))
->method('languageExists')
->with('settings', 'es')
->willReturn(true);
$this->l10nFactory
->expects($this->at(1))
->method('get')
->with('settings', 'es')
->willReturn($l10n);

$this->api->resendWelcomeMessage('UserToGet');
}
}

+ 5
- 0
lib/private/AppFramework/DependencyInjection/DIContainer.php View File

@@ -53,6 +53,7 @@ use OCP\Federation\ICloudIdManager;
use OCP\Files\IAppData;
use OCP\Files\Mount\IMountManager;
use OCP\RichObjectStrings\IValidator;
use OCP\Util;

class DIContainer extends SimpleContainer implements IAppContainer {

@@ -339,6 +340,10 @@ class DIContainer extends SimpleContainer implements IAppContainer {
return $c->query('ServerContainer')->getWebRoot();
});

$this->registerService('fromMailAddress', function() {
return Util::getDefaultEmailAddress('no-reply');
});

$this->registerService('OCP\Encryption\IManager', function ($c) {
return $this->getServer()->getEncryptionManager();
});

Loading…
Cancel
Save