Skip to content
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

Public sharing #1

Merged
merged 46 commits into from
Oct 14, 2016
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
562020f
Start work to publish a calendar
tcitworld Jun 29, 2016
cb7f4c2
remove header
tcitworld Aug 2, 2016
8762b03
merge public and main templates
georgehrke Aug 2, 2016
578b927
use html data attr to check if we are on a public page
georgehrke Aug 2, 2016
88e4375
move public-calendars dav prefix to getPubUrl
georgehrke Aug 2, 2016
fd282d1
calendars are never sharable nor writable when accessed in publicMode
georgehrke Aug 2, 2016
928b00b
change wording in getPubUrl
georgehrke Aug 2, 2016
f7f7db7
calendars are always enabled in publicMode
georgehrke Aug 2, 2016
b7f1edf
fullcalendar is neither editable nor selectable in publicMode
georgehrke Aug 2, 2016
a79fb21
rename getPubUrl to getPublicCalendar
georgehrke Aug 2, 2016
cd15f8f
cough cough
georgehrke Aug 2, 2016
b4dacf5
use isPublic(), fix css on button link & public page
tcitworld Aug 2, 2016
2c5688a
bring public test
tcitworld Aug 2, 2016
d5f1f5f
fix public read-only mode
tcitworld Aug 2, 2016
68a2074
fix long names on published calendars
tcitworld Aug 4, 2016
7a3364a
bring buttons to choose between CalDAV or WebDAV address and clean cs…
tcitworld Aug 4, 2016
c2c75c1
bring email
tcitworld Aug 5, 2016
48aac12
send emails without being admin
tcitworld Aug 5, 2016
fdc1b03
fix tests & add basic tests for mailer
tcitworld Aug 5, 2016
31a7893
fix rootScope.baseUrl to work with public urls
georgehrke Aug 5, 2016
15490d6
fix bug from rebase
georgehrke Aug 8, 2016
82058c9
bring calendar name on public page
tcitworld Aug 11, 2016
db9daf0
handle can-be-published property
tcitworld Aug 12, 2016
1dea817
put $window back
tcitworld Aug 14, 2016
b318cf2
change how shareable & publishable properties work
tcitworld Aug 15, 2016
9fb1578
move CalDAV/WebDAV & integration code to settings
tcitworld Aug 16, 2016
f5440a1
fix publish send mail button align
tcitworld Aug 16, 2016
62de958
fallback when allow-sharing-modes is not provided
tcitworld Aug 16, 2016
1232125
Bring emails templates
tcitworld Aug 17, 2016
b3ecdd9
fix tests
tcitworld Aug 17, 2016
5aea54f
change email messages
tcitworld Aug 18, 2016
3498af2
make display more coherent with the files app
tcitworld Aug 22, 2016
3a464af
fix publication without pre-publish url
tcitworld Sep 7, 2016
bba065a
rebase issues
tcitworld Sep 15, 2016
cfcf5e2
fix tests
tcitworld Sep 15, 2016
2856e87
add opengraph support & clean unused routes
tcitworld Sep 19, 2016
240367c
opg only on public page
tcitworld Oct 4, 2016
d2e7a78
fix send button
tcitworld Oct 4, 2016
50f4bf3
correct html/text emails
tcitworld Oct 4, 2016
a775588
use fancy checkbox
tcitworld Oct 4, 2016
cdc8875
fix urls with trailing #
tcitworld Oct 12, 2016
e8e4091
fix mail_from_address default value
georgehrke Oct 13, 2016
3f07bd6
remove ' !' from button in html email
georgehrke Oct 13, 2016
7ff7d30
replace publicly shared with published, so we only use published
georgehrke Oct 13, 2016
1652e00
fix sending plain text emails
georgehrke Oct 13, 2016
2d436cc
fix wording of email sent notifications
georgehrke Oct 13, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion appinfo/application.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,12 @@ public function __construct($params=[]) {
$request = $c->query('Request');
$userSession = $c->getServer()->getUserSession();
$config = $c->getServer()->getConfig();
$mailer = $c->getServer()->getMailer();
$l10n = $c->getServer()->getL10N($c->query('AppName'));
$defaults = new \OCP\Defaults();
$urlGenerator = $c->getServer()->getURLGenerator();

return new Controller\ViewController($c->getAppName(), $request, $userSession, $config);
return new Controller\ViewController($c->getAppName(), $request, $userSession, $config, $mailer, $l10n, $defaults, $urlGenerator);
});
$container->registerService('ProxyController', function(IAppContainer $c) {
$request = $c->query('Request');
Expand Down
3 changes: 3 additions & 0 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
'routes' => [
//Main view
['name' => 'view#index', 'url' => '/', 'verb' => 'GET'],
['name' => 'view#public_index', 'url' => '/public/{calendarid}', 'verb' => 'GET'],
// Tools
['name' => 'view#sendEmailPublicLink', 'url' => '/v1/public/sendmail', 'verb' => 'POST'],
//Timezones
['name' => 'view#get_timezone', 'url' => '/v1/timezones/{id}', 'verb' => 'GET'],
['name' => 'view#get_timezone_with_region', 'url' => '/v1/timezones/{region}/{city}', 'verb' => 'GET'],
Expand Down
135 changes: 131 additions & 4 deletions controller/viewcontroller.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,27 @@
namespace OCA\Calendar\Controller;

use OC\AppFramework\Http;
use OC\L10N\L10N;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\ContentSecurityPolicy;
use OCP\AppFramework\Http\DataDisplayResponse;
use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\Http\NotFoundResponse;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\Defaults;
use OCP\IConfig;
use OCP\IRequest;
use OCP\IUserSession;
use OCP\Mail\IMailer;
use OCP\IURLGenerator;

class ViewController extends Controller {

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

/**
* @var IConfig
*/
Expand All @@ -44,17 +55,40 @@ class ViewController extends Controller {
*/
private $userSession;

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

/**
* @var L10N
*/
private $l10n;

/**
* @var Defaults
*/
private $defaults;

/**
* @param string $appName
* @param IRequest $request an instance of the request
* @param IUserSession $userSession
* @param IConfig $config
* @param IMailer $mailer
* @param L10N $l10N
* @param Defaults $defaults
* @param IURLGenerator $urlGenerator
*/
public function __construct($appName, IRequest $request,
IUserSession $userSession, IConfig $config) {
IUserSession $userSession, IConfig $config, IMailer $mailer, L10N $l10N, Defaults $defaults, IURLGenerator $urlGenerator) {
parent::__construct($appName, $request);
$this->config = $config;
$this->userSession = $userSession;
$this->mailer = $mailer;
$this->l10n = $l10N;
$this->defaults = $defaults;
$this->urlGenerator = $urlGenerator;
}

/**
Expand Down Expand Up @@ -84,9 +118,9 @@ public function index() {
$skipPopover = $this->config->getUserValue($userId, $this->appName, 'skipPopover', 'no');
$weekNumbers = $this->config->getUserValue($userId, $this->appName, 'showWeekNr', 'no');
$defaultColor = $this->config->getAppValue('theming', 'color', '#0082C9');

$webCalWorkaround = $runningOnNextcloud10OrLater ? 'no' : 'yes';

$webCalWorkaround = $runningOnNextcloud10OrLater ? 'no' : 'yes';

return new TemplateResponse('calendar', 'main', [
'appVersion' => $appVersion,
'defaultView' => $defaultView,
Expand All @@ -96,14 +130,52 @@ public function index() {
'supportsClass' => $supportsClass,
'defaultColor' => $defaultColor,
'webCalWorkaround' => $webCalWorkaround,
'isPublic' => false,
]);
}

/**
* @PublicPage
* @NoCSRFRequired
*
* @return TemplateResponse
*/
public function publicIndex() {
$runningOn = $this->config->getSystemValue('version');
$runningOnServer91OrLater = version_compare($runningOn, '9.1', '>=');

$supportsClass = $runningOnServer91OrLater;
$assetPipelineBroken = !$runningOnServer91OrLater;

$isAssetPipelineEnabled = $this->config->getSystemValue('asset-pipeline.enabled', false);
if ($isAssetPipelineEnabled && $assetPipelineBroken) {
return new TemplateResponse('calendar', 'main-asset-pipeline-unsupported');
}

$appVersion = $this->config->getAppValue($this->appName, 'installed_version');

$response = new TemplateResponse('calendar', 'main', [
'appVersion' => $appVersion,
'defaultView' => 'month',
'emailAddress' => '',
'supportsClass' => $supportsClass,
'isPublic' => true,
'shareURL' => $this->request->getServerProtocol() . '://' . $this->request->getServerHost() . $this->request->getRequestUri(),
'previewImage' => $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'favicon-touch.png')),
], 'public');
$response->addHeader('X-Frame-Options', 'ALLOW');
$csp = new ContentSecurityPolicy();
$csp->addAllowedScriptDomain('*');
$response->setContentSecurityPolicy($csp);

return $response;
}

/**
* @NoAdminRequired
*
* @param string $id
* @return DataDisplayResponse
* @return NotFoundResponse|DataDisplayResponse
*/
public function getTimezone($id) {
if (!in_array($id, $this->getTimezoneList())) {
Expand All @@ -120,6 +192,8 @@ public function getTimezone($id) {

/**
* @NoAdminRequired
* @NoCSRFRequired
* @PublicPage
*
* @param $region
* @param $city
Expand All @@ -132,6 +206,8 @@ public function getTimezoneWithRegion($region, $city) {

/**
* @NoAdminRequired
* @PublicPage
* @NoCSRFRequired
*
* @param $region
* @param $subregion
Expand All @@ -155,4 +231,55 @@ private function getTimezoneList() {
return (substr($file, -4) === '.ics');
}));
}

/**
* @param string $to
* @param string $url
* @param string $name
* @return JSONResponse
* @NoAdminRequired
*/
public function sendEmailPublicLink($to, $url, $name) {

$user = $this->userSession->getUser();
$username = $user->getDisplayName();

$subject = $this->l10n->t('%s has published the calendar "%s"', [$username, $name]);

$emailTemplateHTML = new TemplateResponse('calendar', 'mail.publication.html', ['subject' => $subject, 'username' => $username, 'calendarname' => $name, 'calendarurl' => $url, 'defaults' => $this->defaults], 'public');
$bodyHTML = $emailTemplateHTML->render();
$emailTemplateText = new TemplateResponse('calendar', 'mail.publication.text', ['subject' => $subject, 'username' => $username, 'calendarname' => $name, 'calendarurl' => $url], 'blank');
$textBody = $emailTemplateText->render();

$status = $this->sendEmail($to, $subject, $bodyHTML, $textBody);

return new JSONResponse([], $status);
}

/**
* @param string $target
* @param string $subject
* @param string $body
* @param string $textBody
* @return int
*/
private function sendEmail($target, $subject, $body, $textBody) {
if (!$this->mailer->validateMailAddress($target)) {
return Http::STATUS_BAD_REQUEST;
}

$sendFromDomain = $this->config->getSystemValue('mail_domain', 'domain.org');
$sendFromAddress = $this->config->getSystemValue('mail_from_address', 'nextcloud');
$sendFrom = $sendFromAddress . '@' . $sendFromDomain;

$message = $this->mailer->createMessage();
$message->setSubject($subject);
$message->setFrom([$sendFrom => $this->defaults->getName()]);
$message->setTo([$target => 'Recipient']);
$message->setPlainBody($textBody);
$message->setHtmlBody($body);
$this->mailer->send($message);

return Http::STATUS_OK;
}
}
102 changes: 99 additions & 3 deletions css/app/calendarlist.css
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@
width: 100%;
}

#app-navigation .app-navigation-list-item .calendarCheckbox {
#app-navigation .app-navigation-list-item .calendarCheckbox,
#publicinformationscontainer .calendarCheckbox {
position: absolute;
margin-left: 17px;
margin-top: 16px;
Expand Down Expand Up @@ -133,7 +134,7 @@
opacity: .7 !important;
}

#app-navigation .app-navigation-list-item .utils .action:hover span {
#app-navigation .app-navigation-list-item .utils .action span:hover {
opacity: 1;
}

Expand All @@ -157,7 +158,7 @@
}

#app-navigation .app-navigation-list-item > a.calendar-list-cut-name {
padding: 0 106px 0 44px !important;
padding: 0 107px 0 44px !important;
}

#app-navigation .app-navigation-list-item .editfieldset {
Expand Down Expand Up @@ -313,6 +314,101 @@
height: 44px;
}

/* Public */

#app-navigation .davbuttons {
width: 100%;
height: 44px;
}

#app-navigation .davbuttons .button {
font-weight: normal;
padding: 8px;
width: 48%;
}

#app-navigation .davbuttons .button.first {
margin-left: 5px;
-webkit-border-radius: 3px 0 0 3px;
-ms-border-radius: 3px 0 0 3px;
border-radius: 3px 0 0 3px;
}

#app-navigation .davbuttons .button.last {
margin-left: -8px;
-webkit-border-radius: 0 3px 3px 0;
-moz-border-radius: 0 3px 3px 0;
-ms-border-radius: 0 3px 3px 0;
border-radius: 0 3px 3px 0;
}

.public-calendar-name {
font-size: 20px;
padding: 5px;
border-radius: 5px;
margin: 5px auto;
}

input.public-linkinput {
width: 94%;
margin: 6px auto;
}

#publicinformationscontainer .displayname {
padding-left: 44px !important;
}

#publicinformationscontainer .calendarCheckbox {
cursor: default;
margin-top: 5px;
}

.public-ics-download {
width: 100%;
display: block;
height: 25px;
font-weight: 300;
font-size: 14px;
cursor: pointer;
z-index: 10;
padding: 7px 0 0;
text-align: center;
background-color: rgba(240, 240, 240, .9);
border: 1px solid rgba(240, 240, 240, .9);
background-position: 5%;
border-radius: 3px;
margin: 7px auto;
}

.integration-code {
width: 93%;
height: 100px;
margin: 5px auto;
}

.public-left-side {
margin: 100px 10px auto;
}

/* Publishing */
.publishing {
margin: auto 10px;
}

.publication-tools {
cursor: pointer;
margin: 5px auto auto 5px;
}

input.mailerInput {
width: 94%;
}

.mailerInput + button {
width: 100%;
padding: 6px;
}

/* Calendar Sharing */
input.shareeInput {
width: 89%;
Expand Down
Loading