Search in sources :

Example 1 with Profile

use of co.krypt.krypton.protocol.Profile in project krypton-android by kryptco.

the class MeFragment method updateUI.

@Subscribe(threadMode = ThreadMode.MAIN)
public void updateUI(IdentityService.GetProfileResult r) {
    Profile me = r.profile;
    if (me != null) {
        profileEmail.setText(me.email);
        profileEmail.setTextColor(getResources().getColor(R.color.appBlack, null));
        shareButton.setOnClickListener(v -> {
            if (me != null) {
                Intent sendIntent = new Intent();
                sendIntent.setAction(Intent.ACTION_SEND);
                sendIntent.putExtra(Intent.EXTRA_TEXT, me.shareText());
                sendIntent.setType("text/plain");
                startActivity(Intent.createChooser(sendIntent, "Share your Krypton SSH Public Key"));
            }
        });
    } else {
        Log.e(TAG, "no profile");
    }
}
Also used : Intent(android.content.Intent) Profile(co.krypt.krypton.protocol.Profile) Subscribe(org.greenrobot.eventbus.Subscribe)

Example 2 with Profile

use of co.krypt.krypton.protocol.Profile in project krypton-android by kryptco.

the class MeStorage method loadWithUserID.

public Profile loadWithUserID(@Nullable UserID userID) {
    synchronized (lock) {
        String meJSON = preferences.getString("ME", null);
        if (meJSON == null) {
            Log.i(TAG, "no profile found");
            return null;
        }
        Profile me = JSON.fromJson(meJSON, Profile.class);
        if (me == null) {
            Log.i(TAG, "no profile found");
            return null;
        }
        try {
            SSHKeyPairI kp = getOrLoadKeyPair(context);
            if (kp != null) {
                me.sshWirePublicKey = kp.publicKeySSHWireFormat();
                if (userID != null) {
                    try {
                        List<UserID> userIDs = getUserIDs();
                        // keep USER_ID_LIMIT most recent UserIDs
                        if (userIDs.remove(userID)) {
                            userIDs.add(userID);
                        } else {
                            if (userIDs.size() >= USER_ID_LIMIT) {
                                userIDs.remove(0);
                            }
                            userIDs.add(userID);
                            PGPPublicKey pgpPublicKey = PGPManager.publicKeyWithIdentities(kp, userIDs);
                            me.pgpPublicKey = pgpPublicKey.serializedBytes();
                            if (userIDs.size() == USER_ID_LIMIT) {
                                // detect abuse of exporting PGP userIDs
                                Notifications.notifyPGPKeyExport(context, pgpPublicKey);
                            }
                        }
                        set(me, userIDs);
                    } catch (PGPException | IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (InvalidKeyException | IOException | CryptoException e) {
            e.printStackTrace();
        }
        try {
            me.teamCheckpoint = TeamDataProvider.getTeamCheckpoint(context).success;
        } catch (Native.NotLinked notLinked) {
            notLinked.printStackTrace();
        }
        return me;
    }
}
Also used : SSHKeyPairI(co.krypt.krypton.crypto.SSHKeyPairI) PGPPublicKey(co.krypt.krypton.pgp.PGPPublicKey) IOException(java.io.IOException) InvalidKeyException(java.security.InvalidKeyException) Profile(co.krypt.krypton.protocol.Profile) PGPException(co.krypt.krypton.pgp.PGPException) Native(co.krypt.krypton.team.Native) UserID(co.krypt.krypton.pgp.UserID) CryptoException(co.krypt.krypton.exception.CryptoException)

Example 3 with Profile

use of co.krypt.krypton.protocol.Profile in project krypton-android by kryptco.

the class MemberQR method onCreateView.

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    final View v = inflater.inflate(R.layout.fragment_teams_invite_inperson_member_qr, container, false);
    qrPayloads.set(null);
    qr = v.findViewById(R.id.memberQRCode);
    AppCompatButton cancelButton = v.findViewById(R.id.cancelButton);
    cancelButton.setOnClickListener(v_ -> {
        Transitions.beginFade(this).remove(this).commitAllowingStateLoss();
    });
    loadQRProgress = v.findViewById(R.id.loadQRProgressBar);
    joinProgress = v.findViewById(R.id.memberJoinProgress);
    joinProgress.setAlpha(0);
    Sigchain.AdminQRPayload adminQRPayload = MemberScan.lastScannedPayload.get();
    if (adminQRPayload == null) {
        getFragmentManager().popBackStackImmediate();
    } else {
        new Thread(() -> {
            Profile p = new MeStorage(getContext()).load();
            if (p == null) {
                Error.shortToast(getContext(), "Error loading profile, first generate your Krypton SSH key");
            } else {
                EventBus.getDefault().register(this);
                EventBus.getDefault().post(new TeamService.GenerateClient(C.background(getContext()), new Sigchain.GenerateClientInput(p, adminQRPayload.teamPublicKey, adminQRPayload.lastBlockHash)));
            }
        }).start();
    }
    return v;
}
Also used : Sigchain(co.krypt.krypton.team.Sigchain) MeStorage(co.krypt.krypton.me.MeStorage) View(android.view.View) AppCompatImageView(android.support.v7.widget.AppCompatImageView) Profile(co.krypt.krypton.protocol.Profile) AppCompatButton(android.support.v7.widget.AppCompatButton) Nullable(android.support.annotation.Nullable)

Example 4 with Profile

use of co.krypt.krypton.protocol.Profile in project krypton-android by kryptco.

the class OnboardingVerifyEmailFragment method onCreateView.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    final View rootView = inflater.inflate(R.layout.fragment_teams_onboarding_verify_email, container, false);
    Button cancelButton = rootView.findViewById(R.id.cancelButton);
    cancelButton.setOnClickListener(v -> {
        progress.reset();
        getActivity().finish();
    });
    ProgressBar progressBar = rootView.findViewById(R.id.progressBar);
    progressBar.setAlpha(0);
    Button changeButton = rootView.findViewById(R.id.changeButton);
    changeButton.setEnabled(false);
    Button resendButton = rootView.findViewById(R.id.resendButton);
    resendButton.setEnabled(false);
    ConstraintLayout checkYourEmailContainer = rootView.findViewById(R.id.checkYourEmailContainer);
    checkYourEmailContainer.setAlpha(0);
    AppCompatTextView teamName = rootView.findViewById(R.id.teamName);
    teamName.setText(progress.getTeamOnboardingData().name);
    emailEditText = rootView.findViewById(R.id.profileEmail);
    InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
    Runnable focusEmail = () -> {
        emailEditText.setEnabled(true);
        emailEditText.requestFocus();
        if (imm != null) {
            imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
        }
        progressBar.animate().alpha(0).setDuration(500).start();
    };
    focusEmail.run();
    Runnable requestEmailChallenge = () -> {
        emailEditText.setEnabled(false);
        emailEditText.clearFocus();
        if (imm != null) {
            imm.hideSoftInputFromWindow(emailEditText.getWindowToken(), 0);
        }
        progressBar.animate().alpha(1).setDuration(1000).start();
        final String email = emailEditText.getEditableText().toString();
        new Thread(() -> {
            MeStorage meStorage = Silo.shared(getContext()).meStorage();
            try {
                meStorage.setEmail(email);
            } catch (CryptoException e) {
                Error.shortToast(getContext(), "Failed to set email: " + e.getMessage());
                e.printStackTrace();
                return;
            }
            Profile me = meStorage.load();
            progress.updateTeamData((s, d) -> {
                if (s.equals(CreateStage.VERIFY_EMAIL) || s.equals(CreateStage.EMAIL_CHALLENGE_SENT)) {
                    d.creatorProfile = me;
                    Log.i(TAG, "requesting email challenge...");
                    try {
                        final Sigchain.NativeResult<JsonObject> result = TeamDataProvider.requestEmailChallenge(getContext(), email);
                        emailEditText.post(() -> {
                            if (result.success != null) {
                                Log.i(TAG, "request email challenge success");
                                progressBar.animate().alpha(0).setDuration(500).start();
                                checkYourEmailContainer.animate().alpha(1).setDuration(1000).start();
                                changeButton.setEnabled(true);
                                resendButton.setEnabled(true);
                            } else {
                                Log.i(TAG, "request email challenge failure: " + result.error);
                                Error.shortToast(getContext(), "Error sending email: " + result.error);
                                focusEmail.run();
                            }
                        });
                        if (result.success != null) {
                            return CreateStage.EMAIL_CHALLENGE_SENT;
                        } else {
                            return s;
                        }
                    } catch (Native.NotLinked notLinked) {
                        notLinked.printStackTrace();
                    }
                }
                return s;
            });
        }).start();
    };
    emailEditText.setOnEditorActionListener((v, i, ev) -> {
        requestEmailChallenge.run();
        return false;
    });
    emailEditText.setOnFocusChangeListener((view, b) -> {
        if (view.isEnabled() && !b) {
            requestEmailChallenge.run();
        }
    });
    resendButton.setOnClickListener(v -> {
        requestEmailChallenge.run();
    });
    changeButton.setOnClickListener(v -> {
        focusEmail.run();
    });
    Button submitButton = rootView.findViewById(R.id.submitButton);
    submitButton.setEnabled(false);
    submitButton.setAlpha(0);
    submitButton.setOnClickListener(v -> {
        FragmentManager fragmentManager = getFragmentManager();
        if (fragmentManager != null) {
            fragmentManager.beginTransaction().setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_right, R.anim.exit_to_left).replace(R.id.fragment_teams, new OnboardingLoadTeamFragment()).commitNowAllowingStateLoss();
        }
    });
    EventBus.getDefault().register(this);
    EventBus.getDefault().post(new IdentityService.GetProfile(getContext()));
    return rootView;
}
Also used : Sigchain(co.krypt.krypton.team.Sigchain) AppCompatTextView(android.support.v7.widget.AppCompatTextView) JsonObject(com.google.gson.JsonObject) InputMethodManager(android.view.inputmethod.InputMethodManager) View(android.view.View) AppCompatTextView(android.support.v7.widget.AppCompatTextView) Profile(co.krypt.krypton.protocol.Profile) ConstraintLayout(android.support.constraint.ConstraintLayout) Native(co.krypt.krypton.team.Native) FragmentManager(android.support.v4.app.FragmentManager) IdentityService(co.krypt.krypton.silo.IdentityService) Button(android.widget.Button) MeStorage(co.krypt.krypton.me.MeStorage) CryptoException(co.krypt.krypton.exception.CryptoException) ProgressBar(android.widget.ProgressBar)

Example 5 with Profile

use of co.krypt.krypton.protocol.Profile in project krypton-android by kryptco.

the class VerifyEmailFragment method onCreateView.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    final View rootView = inflater.inflate(R.layout.fragment_teams_onboarding_verify_email, container, false);
    Button cancelButton = rootView.findViewById(R.id.cancelButton);
    cancelButton.setOnClickListener(v -> {
        progress.resetAndDeleteTeam(v.getContext());
        getActivity().finish();
    });
    ProgressBar progressBar = rootView.findViewById(R.id.progressBar);
    progressBar.setAlpha(0);
    Button submitButton = rootView.findViewById(R.id.submitButton);
    Button changeButton = rootView.findViewById(R.id.changeButton);
    Button resendButton = rootView.findViewById(R.id.resendButton);
    AppCompatTextView checkYourEmailText = rootView.findViewById(R.id.checkYourEmailText);
    AppCompatTextView checkYourEmailSubtext = rootView.findViewById(R.id.checkYourEmailSubtext);
    AppCompatEditText emailEditText = rootView.findViewById(R.id.profileEmail);
    InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
    Runnable onSubmitUI = () -> {
        emailEditText.setEnabled(false);
        emailEditText.clearFocus();
        if (imm != null) {
            imm.hideSoftInputFromWindow(emailEditText.getWindowToken(), 0);
        }
        progressBar.animate().alpha(1).setDuration(1000).start();
        submitButton.setEnabled(false);
        submitButton.animate().alpha(0).setDuration(500).start();
        checkYourEmailSubtext.animate().alpha(0).setDuration(500).start();
        checkYourEmailText.animate().alpha(0).setDuration(500).start();
    };
    Runnable onEditUI = () -> {
        emailEditText.setEnabled(true);
        submitButton.animate().alpha(1).setDuration(500).start();
        changeButton.animate().alpha(0).setDuration(500).start();
        resendButton.animate().alpha(0).setDuration(500).start();
        submitButton.setEnabled(true);
        changeButton.setEnabled(false);
        resendButton.setEnabled(false);
        checkYourEmailSubtext.animate().alpha(0).setDuration(500).start();
        checkYourEmailText.animate().alpha(0).setDuration(500).start();
        progressBar.animate().alpha(0).setDuration(500).start();
    };
    Runnable onSuccessUI = () -> {
        progressBar.animate().alpha(0).setDuration(500).start();
        changeButton.animate().alpha(1).setDuration(1000).start();
        resendButton.animate().alpha(1).setDuration(1000).start();
        submitButton.animate().alpha(0).setDuration(500).start();
        changeButton.setEnabled(true);
        resendButton.setEnabled(true);
        checkYourEmailSubtext.animate().alpha(1).setDuration(500).start();
        checkYourEmailText.animate().alpha(1).setDuration(500).start();
    };
    Runnable focusEmail = () -> {
        onEditUI.run();
        emailEditText.requestFocus();
        if (imm != null) {
            imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
        }
    };
    Runnable onErrorUI = () -> {
        focusEmail.run();
        Toast.makeText(getContext(), "Error sending email verification.", Toast.LENGTH_SHORT).show();
    };
    submitButton.setAlpha(1);
    changeButton.setAlpha(0);
    resendButton.setAlpha(0);
    checkYourEmailSubtext.setAlpha(0);
    checkYourEmailText.setAlpha(0);
    changeButton.setEnabled(false);
    resendButton.setEnabled(false);
    AppCompatTextView teamName = rootView.findViewById(R.id.teamName);
    teamName.setText(progress.getTeamOnboardingData().decryptInviteOutput.teamName);
    String initialEmail = Silo.shared(getContext().getApplicationContext()).meStorage().load().email;
    emailEditText.setText(initialEmail);
    final Sigchain.IndirectInvitationRestriction restriction = progress.getTeamOnboardingData().decryptInviteOutput.indirectInvitationSecret.restriction;
    Runnable requestEmailChallenge = () -> {
        final String email = emailEditText.getEditableText().toString();
        if (!Email.verifyEmailPattern.matcher(email).matches()) {
            Toast.makeText(getContext(), "Please enter a valid email.", Toast.LENGTH_SHORT).show();
            return;
        }
        if (!restriction.isSatisfiedByEmail(email)) {
            if (restriction.domain != null) {
                Toast.makeText(getContext(), "Email must end with @" + restriction.domain, Toast.LENGTH_SHORT).show();
            } else if (restriction.emails != null) {
                Toast.makeText(getContext(), "Invite link not valid for this email address.", Toast.LENGTH_SHORT).show();
            }
            return;
        }
        onSubmitUI.run();
        new Thread(() -> {
            MeStorage meStorage = Silo.shared(getContext()).meStorage();
            try {
                meStorage.setEmail(email);
            } catch (CryptoException e) {
                co.krypt.krypton.uiutils.Error.shortToast(getContext(), "Failed to set email: " + e.getMessage());
                e.printStackTrace();
                return;
            }
            Profile me = meStorage.load();
            progress.updateTeamData((s, d) -> {
                if (s.equals(JoinStage.VERIFY_EMAIL)) {
                    d.profile = me;
                    Log.i(TAG, "requesting email challenge...");
                    try {
                        final Sigchain.NativeResult<JsonObject> result = TeamDataProvider.requestEmailChallenge(getContext(), email);
                        emailEditText.post(() -> {
                            if (result.success != null) {
                                Log.i(TAG, "request email challenge success");
                                onSuccessUI.run();
                            } else {
                                Log.i(TAG, "request email challenge failure");
                                onErrorUI.run();
                            }
                        });
                        if (result.success != null) {
                            return JoinStage.CHALLENGE_EMAIL_SENT;
                        } else {
                            return s;
                        }
                    } catch (Native.NotLinked notLinked) {
                        notLinked.printStackTrace();
                    }
                }
                return s;
            });
        }).start();
    };
    final Runnable setSelectionBeforeDomain = () -> {
        String currentEmail = emailEditText.getText().toString();
        if (restriction.domain != null) {
            String domainSuffix = "@" + restriction.domain;
            if (currentEmail.length() >= domainSuffix.length()) {
                if (emailEditText.getSelectionStart() == emailEditText.getSelectionEnd()) {
                    if (emailEditText.getSelectionStart() > currentEmail.length() - domainSuffix.length()) {
                        emailEditText.setSelection(currentEmail.length() - domainSuffix.length());
                    }
                }
            }
        }
    };
    emailEditText.setOnEditorActionListener((v, i, ev) -> {
        requestEmailChallenge.run();
        return false;
    });
    // focus before adding listener
    focusEmail.run();
    setSelectionBeforeDomain.run();
    emailEditText.setOnFocusChangeListener((view, b) -> {
        if (view.isEnabled()) {
            if (b) {
                setSelectionBeforeDomain.run();
            }
        }
    });
    emailEditText.setOnClickListener(v -> setSelectionBeforeDomain.run());
    final AtomicReference<String> lastEmail = new AtomicReference<>(new String(emailEditText.getText().toString()));
    if (!restriction.isSatisfiedByEmail(lastEmail.get())) {
        if (restriction.domain != null) {
            lastEmail.set("@" + restriction.domain);
        } else if (restriction.emails != null && restriction.emails.length == 1) {
            lastEmail.set(restriction.emails[0]);
        } else {
            lastEmail.set("");
        }
        emailEditText.setText(lastEmail.get());
    }
    final Runnable updateTextColor = () -> {
        if (Email.verifyEmailPattern.matcher(emailEditText.getText()).matches()) {
            emailEditText.setTextColor(getContext().getColor(R.color.appGreen));
        } else {
            emailEditText.setTextColor(getContext().getColor(R.color.appGray));
        }
    };
    updateTextColor.run();
    final TextWatcher domainCheck = new TextWatcher() {

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            lastEmail.set(s.toString());
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            updateTextColor.run();
        }

        @Override
        public void afterTextChanged(Editable s) {
            if (restriction.domain != null) {
                if (!s.toString().endsWith("@" + restriction.domain)) {
                    emailEditText.removeTextChangedListener(this);
                    s.clear();
                    s.append(lastEmail.get());
                    setSelectionBeforeDomain.run();
                    emailEditText.addTextChangedListener(this);
                    Toast.makeText(getContext(), "Email must end with @" + restriction.domain, Toast.LENGTH_SHORT).show();
                }
            }
        }
    };
    emailEditText.addTextChangedListener(domainCheck);
    resendButton.setOnClickListener(v -> {
        requestEmailChallenge.run();
    });
    changeButton.setOnClickListener(v -> {
        focusEmail.run();
    });
    submitButton.setOnClickListener(v -> requestEmailChallenge.run());
    return rootView;
}
Also used : Sigchain(co.krypt.krypton.team.Sigchain) AppCompatTextView(android.support.v7.widget.AppCompatTextView) JsonObject(com.google.gson.JsonObject) InputMethodManager(android.view.inputmethod.InputMethodManager) AtomicReference(java.util.concurrent.atomic.AtomicReference) View(android.view.View) AppCompatTextView(android.support.v7.widget.AppCompatTextView) Profile(co.krypt.krypton.protocol.Profile) Native(co.krypt.krypton.team.Native) AppCompatEditText(android.support.v7.widget.AppCompatEditText) Button(android.widget.Button) MeStorage(co.krypt.krypton.me.MeStorage) TextWatcher(android.text.TextWatcher) Editable(android.text.Editable) CryptoException(co.krypt.krypton.exception.CryptoException) ProgressBar(android.widget.ProgressBar)

Aggregations

Profile (co.krypt.krypton.protocol.Profile)10 View (android.view.View)5 MeStorage (co.krypt.krypton.me.MeStorage)5 InputMethodManager (android.view.inputmethod.InputMethodManager)4 CryptoException (co.krypt.krypton.exception.CryptoException)4 Native (co.krypt.krypton.team.Native)4 Sigchain (co.krypt.krypton.team.Sigchain)4 Intent (android.content.Intent)2 Bundle (android.os.Bundle)2 Fragment (android.support.v4.app.Fragment)2 FragmentActivity (android.support.v4.app.FragmentActivity)2 AppCompatTextView (android.support.v7.widget.AppCompatTextView)2 Editable (android.text.Editable)2 TextWatcher (android.text.TextWatcher)2 Button (android.widget.Button)2 ProgressBar (android.widget.ProgressBar)2 Analytics (co.krypt.krypton.analytics.Analytics)2 SSHKeyPairI (co.krypt.krypton.crypto.SSHKeyPairI)2 JsonObject (com.google.gson.JsonObject)2 Context (android.content.Context)1