NotificationJob.java 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*
  2. * Nextcloud application
  3. *
  4. * @author Mario Danic
  5. * Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
  6. *
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation, either version 3 of the License, or
  10. * at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. package com.owncloud.android.jobs;
  21. import android.accounts.Account;
  22. import android.app.NotificationManager;
  23. import android.app.PendingIntent;
  24. import android.content.Context;
  25. import android.content.Intent;
  26. import android.graphics.BitmapFactory;
  27. import android.media.RingtoneManager;
  28. import android.support.annotation.NonNull;
  29. import android.support.v4.app.NotificationCompat;
  30. import android.text.TextUtils;
  31. import android.util.Base64;
  32. import android.util.Log;
  33. import com.evernote.android.job.Job;
  34. import com.evernote.android.job.util.support.PersistableBundleCompat;
  35. import com.google.gson.Gson;
  36. import com.owncloud.android.R;
  37. import com.owncloud.android.datamodel.DecryptedPushMessage;
  38. import com.owncloud.android.datamodel.SignatureVerification;
  39. import com.owncloud.android.ui.activity.NotificationsActivity;
  40. import com.owncloud.android.ui.notifications.NotificationUtils;
  41. import com.owncloud.android.utils.PushUtils;
  42. import com.owncloud.android.utils.ThemeUtils;
  43. import java.security.InvalidKeyException;
  44. import java.security.NoSuchAlgorithmException;
  45. import java.security.PrivateKey;
  46. import javax.crypto.Cipher;
  47. import javax.crypto.NoSuchPaddingException;
  48. public class NotificationJob extends Job {
  49. public static final String TAG = "NotificationJob";
  50. public static final String KEY_NOTIFICATION_SUBJECT = "subject";
  51. public static final String KEY_NOTIFICATION_SIGNATURE = "signature";
  52. public static final String KEY_NOTIFICATION_ACCOUNT = "KEY_NOTIFICATION_ACCOUNT";
  53. @NonNull
  54. @Override
  55. protected Result onRunJob(Params params) {
  56. Context context = getContext();
  57. PersistableBundleCompat persistableBundleCompat = getParams().getExtras();
  58. String subject = persistableBundleCompat.getString(KEY_NOTIFICATION_SUBJECT, "");
  59. String signature = persistableBundleCompat.getString(KEY_NOTIFICATION_SIGNATURE, "");
  60. if (!TextUtils.isEmpty(subject) && !TextUtils.isEmpty(signature)) {
  61. try {
  62. byte[] base64DecodedSubject = Base64.decode(subject, Base64.DEFAULT);
  63. byte[] base64DecodedSignature = Base64.decode(signature, Base64.DEFAULT);
  64. PushUtils pushUtils = new PushUtils();
  65. PrivateKey privateKey = (PrivateKey) PushUtils.readKeyFromFile(false);
  66. try {
  67. SignatureVerification signatureVerification = pushUtils.verifySignature(context,
  68. base64DecodedSignature, base64DecodedSubject);
  69. if (signatureVerification.isSignatureValid()) {
  70. Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding");
  71. cipher.init(Cipher.DECRYPT_MODE, privateKey);
  72. byte[] decryptedSubject = cipher.doFinal(base64DecodedSubject);
  73. Gson gson = new Gson();
  74. DecryptedPushMessage decryptedPushMessage = gson.fromJson(new String(decryptedSubject),
  75. DecryptedPushMessage.class);
  76. // We ignore Spreed messages for now
  77. if (!decryptedPushMessage.getApp().equals("spreed")) {
  78. sendNotification(decryptedPushMessage.getSubject(), signatureVerification.getAccount());
  79. }
  80. }
  81. } catch (NoSuchAlgorithmException e1) {
  82. Log.d(TAG, "No proper algorithm to decrypt the message " + e1.getLocalizedMessage());
  83. } catch (NoSuchPaddingException e1) {
  84. Log.d(TAG, "No proper padding to decrypt the message " + e1.getLocalizedMessage());
  85. } catch (InvalidKeyException e1) {
  86. Log.d(TAG, "Invalid private key " + e1.getLocalizedMessage());
  87. }
  88. } catch (Exception exception) {
  89. Log.d(TAG, "Something went very wrong" + exception.getLocalizedMessage());
  90. }
  91. }
  92. return Result.SUCCESS;
  93. }
  94. private void sendNotification(String contentTitle, Account account) {
  95. Context context = getContext();
  96. Intent intent = new Intent(getContext(), NotificationsActivity.class);
  97. intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
  98. intent.putExtra(KEY_NOTIFICATION_ACCOUNT, account.name);
  99. PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_ONE_SHOT);
  100. NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context)
  101. .setSmallIcon(R.drawable.notification_icon)
  102. .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.notification_icon))
  103. .setColor(ThemeUtils.primaryColor(context))
  104. .setShowWhen(true)
  105. .setSubText(account.name)
  106. .setContentTitle(contentTitle)
  107. .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
  108. .setAutoCancel(true)
  109. .setContentIntent(pendingIntent);
  110. if ((android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O)) {
  111. notificationBuilder.setChannelId(NotificationUtils.NOTIFICATION_CHANNEL_PUSH);
  112. }
  113. NotificationManager notificationManager = (NotificationManager)
  114. context.getSystemService(Context.NOTIFICATION_SERVICE);
  115. notificationManager.notify(0, notificationBuilder.build());
  116. }
  117. }