SsoGrantPermissionActivity.java 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. * Nextcloud Android client application
  3. *
  4. * @author David Luhmer
  5. * @author Andy Scherzinger
  6. * Copyright (C) 2018 David Luhmer
  7. * Copyright (C) 2018 Andy Scherzinger
  8. *
  9. * This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Affero General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Affero General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public License
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. */
  22. package com.owncloud.android.ui.activity;
  23. import android.accounts.Account;
  24. import android.accounts.AccountManager;
  25. import android.content.ComponentName;
  26. import android.content.Context;
  27. import android.content.Intent;
  28. import android.content.SharedPreferences;
  29. import android.content.pm.ApplicationInfo;
  30. import android.content.pm.PackageManager;
  31. import android.graphics.Typeface;
  32. import android.graphics.drawable.Drawable;
  33. import android.os.Bundle;
  34. import android.text.Spannable;
  35. import android.text.SpannableStringBuilder;
  36. import android.text.style.ForegroundColorSpan;
  37. import android.text.style.StyleSpan;
  38. import android.util.Log;
  39. import android.widget.Button;
  40. import android.widget.ImageView;
  41. import android.widget.TextView;
  42. import com.nextcloud.android.sso.Constants;
  43. import com.owncloud.android.MainApp;
  44. import com.owncloud.android.R;
  45. import com.owncloud.android.lib.common.OwnCloudAccount;
  46. import com.owncloud.android.lib.common.accounts.AccountUtils;
  47. import com.owncloud.android.lib.common.utils.Log_OC;
  48. import com.owncloud.android.utils.EncryptionUtils;
  49. import java.util.UUID;
  50. import butterknife.BindView;
  51. import butterknife.ButterKnife;
  52. import butterknife.OnClick;
  53. import butterknife.Unbinder;
  54. import static com.nextcloud.android.sso.Constants.DELIMITER;
  55. import static com.nextcloud.android.sso.Constants.EXCEPTION_ACCOUNT_ACCESS_DECLINED;
  56. import static com.nextcloud.android.sso.Constants.EXCEPTION_ACCOUNT_NOT_FOUND;
  57. import static com.nextcloud.android.sso.Constants.NEXTCLOUD_FILES_ACCOUNT;
  58. import static com.nextcloud.android.sso.Constants.NEXTCLOUD_SSO;
  59. import static com.nextcloud.android.sso.Constants.NEXTCLOUD_SSO_EXCEPTION;
  60. import static com.nextcloud.android.sso.Constants.SSO_SHARED_PREFERENCE;
  61. /**
  62. * Activity for granting access rights to a Nextcloud account, used for SSO.
  63. */
  64. public class SsoGrantPermissionActivity extends BaseActivity {
  65. private static final String TAG = SsoGrantPermissionActivity.class.getCanonicalName();
  66. private String packageName;
  67. private Account account;
  68. private Unbinder unbinder;
  69. @BindView(R.id.appIcon)
  70. ImageView appIcon;
  71. @BindView(R.id.permissionText)
  72. TextView permissionText;
  73. @BindView(R.id.btnGrant)
  74. Button grantPermissionButton;
  75. @BindView(R.id.btnDecline)
  76. Button declinePermissionButton;
  77. @Override
  78. protected void onCreate(Bundle savedInstanceState) {
  79. super.onCreate(savedInstanceState);
  80. setContentView(R.layout.activity_sso_grant_permission);
  81. unbinder = ButterKnife.bind(this);
  82. ComponentName callingActivity = getCallingActivity();
  83. if (callingActivity != null) {
  84. packageName = callingActivity.getPackageName();
  85. String appName = getAppNameForPackage(packageName);
  86. account = getIntent().getParcelableExtra(NEXTCLOUD_FILES_ACCOUNT);
  87. permissionText.setText(makeSpecialPartsBold(
  88. getString(R.string.single_sign_on_request_token, appName, account.name),
  89. appName,
  90. account.name)
  91. );
  92. Log.v(TAG, "TOKEN-REQUEST: Calling Package: " + packageName);
  93. Log.v(TAG, "TOKEN-REQUEST: App Name: " + appName);
  94. } else {
  95. // Activity was not started using startActivityForResult!
  96. Log.e(TAG, "Calling Package is null");
  97. setResultAndExit("Request was not executed properly. Use startActivityForResult()");
  98. }
  99. try {
  100. if (packageName != null) {
  101. Drawable appIcon = getPackageManager().getApplicationIcon(packageName);
  102. this.appIcon.setImageDrawable(appIcon);
  103. }
  104. } catch (PackageManager.NameNotFoundException e) {
  105. Log.e(TAG, e.getMessage());
  106. }
  107. }
  108. @Override
  109. protected void onDestroy() {
  110. super.onDestroy();
  111. unbinder.unbind();
  112. }
  113. private SpannableStringBuilder makeSpecialPartsBold(String text, String... toBeStyledText) {
  114. SpannableStringBuilder ssb = new SpannableStringBuilder(text);
  115. for (String textBlock : toBeStyledText) {
  116. int start = text.indexOf(textBlock);
  117. int end = start + textBlock.length();
  118. ssb.setSpan(new StyleSpan(Typeface.BOLD), start, end, 0);
  119. ssb.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.text_color)), start, end,
  120. Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  121. }
  122. return ssb;
  123. }
  124. private void setResultAndExit(String exception) {
  125. Intent data = new Intent();
  126. data.putExtra(NEXTCLOUD_SSO_EXCEPTION, exception);
  127. setResult(RESULT_CANCELED, data);
  128. finish();
  129. }
  130. private String getAppNameForPackage(String pkg) {
  131. final PackageManager pm = getApplicationContext().getPackageManager();
  132. ApplicationInfo ai = null;
  133. try {
  134. ai = pm.getApplicationInfo(pkg, 0);
  135. } catch (final PackageManager.NameNotFoundException e) {
  136. Log.e(TAG, e.getMessage());
  137. }
  138. return (String) (ai != null ? pm.getApplicationLabel(ai) : "(unknown)");
  139. }
  140. @OnClick(R.id.btnDecline)
  141. void exitFailed() {
  142. setResultAndExit(EXCEPTION_ACCOUNT_ACCESS_DECLINED);
  143. }
  144. @OnClick(R.id.btnGrant)
  145. void grantPermission() {
  146. // create token
  147. SharedPreferences sharedPreferences = getSharedPreferences(SSO_SHARED_PREFERENCE, Context.MODE_PRIVATE);
  148. String token = UUID.randomUUID().toString().replaceAll("-", "");
  149. String hashedTokenWithSalt = EncryptionUtils.generateSHA512(token);
  150. SharedPreferences.Editor editor = sharedPreferences.edit();
  151. editor.putString(packageName + DELIMITER + account.name, hashedTokenWithSalt);
  152. editor.apply();
  153. String serverUrl;
  154. String userId;
  155. try {
  156. OwnCloudAccount ocAccount = new OwnCloudAccount(account, this);
  157. serverUrl = ocAccount.getBaseUri().toString();
  158. AccountManager accountManager = AccountManager.get(this);
  159. userId = accountManager.getUserData(account,
  160. com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_USER_ID);
  161. } catch (AccountUtils.AccountNotFoundException e) {
  162. Log_OC.e(TAG, "Account not found");
  163. setResultAndExit(EXCEPTION_ACCOUNT_NOT_FOUND);
  164. return;
  165. }
  166. final Bundle result = new Bundle();
  167. result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
  168. result.putString(AccountManager.KEY_ACCOUNT_TYPE, MainApp.getAccountType(this));
  169. result.putString(AccountManager.KEY_AUTHTOKEN, NEXTCLOUD_SSO);
  170. result.putString(Constants.SSO_USER_ID, userId);
  171. result.putString(Constants.SSO_TOKEN, token);
  172. result.putString(Constants.SSO_SERVER_URL, serverUrl);
  173. Intent data = new Intent();
  174. data.putExtra(NEXTCLOUD_SSO, result);
  175. setResult(RESULT_OK, data);
  176. finish();
  177. }
  178. }