55 */
66namespace OCA \ShareByMail ;
77
8+ use OC \Share20 \DefaultShareProvider ;
89use OC \Share20 \Exception \InvalidShare ;
910use OC \Share20 \Share ;
1011use OC \User \NoUserException ;
2930use OCP \Security \ISecureRandom ;
3031use OCP \Share \Exceptions \GenericShareException ;
3132use OCP \Share \Exceptions \ShareNotFound ;
33+ use OCP \Share \IAttributes ;
3234use OCP \Share \IManager as IShareManager ;
3335use OCP \Share \IShare ;
3436use OCP \Share \IShareProviderWithNotification ;
3941 *
4042 * @package OCA\ShareByMail
4143 */
42- class ShareByMailProvider implements IShareProviderWithNotification {
44+ class ShareByMailProvider extends DefaultShareProvider implements IShareProviderWithNotification {
4345 /**
4446 * Return the identifier of this provider.
4547 *
@@ -76,11 +78,10 @@ public function __construct(
7678 */
7779 public function create (IShare $ share ): IShare {
7880 $ shareWith = $ share ->getSharedWith ();
79- /*
80- * Check if file is not already shared with the remote user
81- */
81+ // Check if file is not already shared with the given email,
82+ // if we have an email at all.
8283 $ alreadyShared = $ this ->getSharedWith ($ shareWith , IShare::TYPE_EMAIL , $ share ->getNode (), 1 , 0 );
83- if (! empty ($ alreadyShared )) {
84+ if ($ shareWith !== '' && ! empty ($ alreadyShared )){
8485 $ message = 'Sharing %1$s failed, because this item is already shared with the account %2$s ' ;
8586 $ message_t = $ this ->l ->t ('Sharing %1$s failed, because this item is already shared with the account %2$s ' , [$ share ->getNode ()->getName (), $ shareWith ]);
8687 $ this ->logger ->debug (sprintf ($ message , $ share ->getNode ()->getName (), $ shareWith ), ['app ' => 'Federated File Sharing ' ]);
@@ -224,7 +225,8 @@ protected function createMailShare(IShare $share): int {
224225 $ share ->getHideDownload (),
225226 $ share ->getLabel (),
226227 $ share ->getExpirationDate (),
227- $ share ->getNote ()
228+ $ share ->getNote (),
229+ $ share ->getAttributes (),
228230 );
229231 }
230232
@@ -233,11 +235,17 @@ protected function createMailShare(IShare $share): int {
233235 */
234236 public function sendMailNotification (IShare $ share ): bool {
235237 $ shareId = $ share ->getId ();
236- if (!$ this ->mailer ->validateMailAddress ($ share ->getSharedWith ())) {
238+
239+ $ emails = $ this ->getSharedWithEmails ($ share );
240+ $ validEmails = array_filter ($ emails , function ($ email ) {
241+ return $ this ->mailer ->validateMailAddress ($ email );
242+ });
243+
244+ if (count ($ validEmails ) === 0 ) {
237245 $ this ->removeShareFromTable ($ shareId );
238- $ e = new HintException ('Failed to send share by mail. Got an invalid email address: ' . $ share -> getSharedWith ( ),
246+ $ e = new HintException ('Failed to send share by mail. Could not find a valid email address: ' . join ( ' , ' , $ emails ),
239247 $ this ->l ->t ('Failed to send share by email. Got an invalid email address ' ));
240- $ this ->logger ->error ('Failed to send share by mail. Got an invalid email address ' . $ share -> getSharedWith ( ), [
248+ $ this ->logger ->error ('Failed to send share by mail. Could not find a valid email address ' . join ( ' , ' , $ emails ), [
241249 'app ' => 'sharebymail ' ,
242250 'exception ' => $ e ,
243251 ]);
@@ -250,7 +258,7 @@ public function sendMailNotification(IShare $share): bool {
250258 $ share ->getNode ()->getName (),
251259 $ link ,
252260 $ share ->getSharedBy (),
253- $ share -> getSharedWith () ,
261+ $ emails ,
254262 $ share ->getExpirationDate (),
255263 $ share ->getNote ()
256264 );
@@ -293,7 +301,7 @@ public function sendMailNotification(IShare $share): bool {
293301 * @param string $filename file/folder name
294302 * @param string $link link to the file/folder
295303 * @param string $initiator user ID of share sender
296- * @param string $shareWith email addresses
304+ * @param string[] $shareWith email addresses
297305 * @param \DateTime|null $expiration expiration date
298306 * @param string $note note
299307 * @throws \Exception If mail couldn't be sent
@@ -302,7 +310,7 @@ protected function sendEmail(
302310 string $ filename ,
303311 string $ link ,
304312 string $ initiator ,
305- string $ shareWith ,
313+ array $ shareWith ,
306314 ?\DateTime $ expiration = null ,
307315 string $ note = '' ,
308316 ): void {
@@ -337,7 +345,13 @@ protected function sendEmail(
337345 $ link
338346 );
339347
340- $ message ->setTo ([$ shareWith ]);
348+ // If multiple recipients are given, we send the mail to all of them
349+ if (count ($ shareWith ) > 1 ) {
350+ // We do not want to expose the email addresses of the other recipients
351+ $ message ->setBcc ($ shareWith );
352+ } else {
353+ $ message ->setTo ($ shareWith );
354+ }
341355
342356 // The "From" contains the sharers name
343357 $ instanceName = $ this ->defaults ->getName ();
@@ -618,7 +632,8 @@ protected function addShareToDB(
618632 ?bool $ hideDownload ,
619633 ?string $ label ,
620634 ?\DateTimeInterface $ expirationTime ,
621- ?string $ note = ''
635+ ?string $ note = '' ,
636+ ?IAttributes $ attributes = null ,
622637 ): int {
623638 $ qb = $ this ->dbConnection ->getQueryBuilder ();
624639 $ qb ->insert ('share ' )
@@ -640,6 +655,10 @@ protected function addShareToDB(
640655 ->setValue ('note ' , $ qb ->createNamedParameter ($ note ))
641656 ->setValue ('mail_send ' , $ qb ->createNamedParameter (1 ));
642657
658+ // set share attributes
659+ $ shareAttributes = $ this ->formatShareAttributes ($ attributes );
660+
661+ $ qb ->setValue ('attributes ' , $ qb ->createNamedParameter ($ shareAttributes ));
643662 if ($ expirationTime !== null ) {
644663 $ qb ->setValue ('expiration ' , $ qb ->createNamedParameter ($ expirationTime , IQueryBuilder::PARAM_DATE ));
645664 }
@@ -955,6 +974,8 @@ protected function createShareObject(array $data): IShare {
955974 }
956975 }
957976
977+ $ share = $ this ->updateShareAttributes ($ share , $ data ['attributes ' ]);
978+
958979 $ share ->setNodeId ((int )$ data ['file_source ' ]);
959980 $ share ->setNodeType ($ data ['item_type ' ]);
960981
@@ -1137,4 +1158,17 @@ public function getAllShares(): iterable {
11371158 }
11381159 $ cursor ->closeCursor ();
11391160 }
1161+
1162+ /**
1163+ * Extract the emails from the share
1164+ * It can be a single email, from the share_with field
1165+ * or a list of emails from the emails attributes field.
1166+ */
1167+ protected function getSharedWithEmails (IShare $ share ) {
1168+ $ attributes = $ share ->getAttributes ()->getAttribute ('sharedWith ' , 'emails ' );
1169+ if (isset ($ attributes ) && is_array ($ attributes ) && !empty ($ attributes )) {
1170+ return $ attributes ;
1171+ }
1172+ return [$ share ->getSharedWith ()];
1173+ }
11401174}
0 commit comments