Skip to content

Commit

Permalink
fix: fix correct checking/unlocking radicle identity
Browse files Browse the repository at this point in the history
  • Loading branch information
JChrist committed Jan 20, 2025
1 parent 3b3c6f1 commit ac9f938
Show file tree
Hide file tree
Showing 19 changed files with 307 additions and 191 deletions.
14 changes: 14 additions & 0 deletions jrad/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ pub extern "system" fn issueCommentReact(inp: *const c_char) -> *const c_char {
}
}

#[derive(Serialize, Deserialize, Clone, Debug)]
struct BaseProfileInfo {
home: Option<String>,
passphrase: Option<String>,
}

#[derive(Serialize, Deserialize, Clone, Debug)]
struct ChangeIssueTitleDesc {
repo_id: RepoId,
Expand Down Expand Up @@ -371,6 +377,14 @@ pub fn resolve_embed(repo: &Repository, embed: ContentEmbed) -> Result<Embed<Uri
fn read_input(input: *const c_char) -> Result<String, anyhow::Error> {
let input_str = unsafe { std::ffi::CStr::from_ptr(input) };
let input_string = input_str.to_str()?;
let base_info: BaseProfileInfo = serde_json::from_str(input_string)?;
if base_info.home.is_some() {
std::env::set_var("RAD_HOME", base_info.home.unwrap());
}
if base_info.passphrase.is_some() {
std::env::set_var("RAD_PASSPHRASE", base_info.passphrase.unwrap());
}

Ok(String::from(input_string))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,52 +92,61 @@ private RadicleProjectSettings getProjectSettings() {
return projectHandler.loadSettings();
}


private ProcessOutput unlockIdentity(String radHome, String radPath, IdentityDialog dialog) {
if (project == null && repo == null) {
return new ProcessOutput(0);
}
var pr = project != null ? project : repo.getProject();
var output = rad.self(radHome, radPath);
var lines = output.getStdoutLines(true);
final var idOutput = rad.self(radHome, radPath);
final var hasIdentity = RadAction.isSuccess(idOutput);
var lines = idOutput.getStdoutLines(true);
var radDetails = new RadDetails(lines);
var isIdentityUnlocked = rad.isIdentityUnlocked(radDetails.keyHash);
var hasIdentity = RadAction.isSuccess(output);
var projectSettings = new RadicleProjectSettingsHandler(pr);
final var isIdentityUnlocked = rad.isIdentityUnlocked(radDetails.keyHash);
if (isIdentityUnlocked) {
return new ProcessOutput(0);
}
final var projectSettings = new RadicleProjectSettingsHandler(pr);
String storedPassword = null;
if (hasIdentity) {
// check if key has no passphrase
var ok = rad.isPassphraseCorrect("", radHome);
if (ok) {
projectSettings.savePassphrase(radDetails.nodeId, "");
rad.auth("", "", radHome, radPath);
return new ProcessOutput(0);
}
// the key has a non-empty passphrase, check if we have saved a password
storedPassword = projectSettings.getPassword(radDetails.nodeId);
}
var hasStoredPassword = storedPassword != null;
var showDialog = ((!hasIdentity || !isIdentityUnlocked) && !hasStoredPassword);
IdentityDialog.IdentityDialogData dialogData = null;
if (showDialog) {
var authService = project.getService(AuthService.class);
var title = !hasIdentity ? RadicleBundle.message("newIdentity") :
RadicleBundle.message("unlockIdentity");
dialogData = authService.showIdentityDialog(title, hasIdentity, dialog);
final var hasStoredPassword = storedPassword != null;
boolean hasCorrectStoredPassword = hasStoredPassword;
if (hasIdentity && hasStoredPassword) {
hasCorrectStoredPassword = rad.isPassphraseCorrect(storedPassword, radHome);
}
if (!isIdentityUnlocked && hasIdentity && hasStoredPassword) {
var authOutput = rad.auth(storedPassword, "", radHome, radPath);
var success = RadAuth.validateOutput(authOutput);
if (!RadAction.isSuccess(success)) {
projectSettings.savePassphrase(radDetails.nodeId, null);
}
return success;
var showDialog = !hasIdentity || !hasStoredPassword || !hasCorrectStoredPassword;
if (!showDialog) {
// attempt to unlock identity (add key to ssh-agent)
rad.auth(storedPassword, "", radHome, radPath);
return new ProcessOutput(0);
}
if (dialogData != null) {
var authOutput = rad.auth(dialogData.passphrase(), dialogData.alias(), radHome, radPath);
var success = RadAuth.validateOutput(authOutput);
if (RadAction.isSuccess(success)) {
output = rad.self(radHome, radPath);
lines = output.getStdoutLines(true);
radDetails = new RadDetails(lines);
projectSettings.savePassphrase(radDetails.nodeId, dialogData.passphrase());
}
return success;
var authService = project.getService(AuthService.class);
var title = !hasIdentity ? RadicleBundle.message("newIdentity") : RadicleBundle.message("unlockIdentity");
final var dialogData = authService.showIdentityDialog(title, hasIdentity, dialog);
if (hasIdentity) {
// we already had an identity, so check the passphrase again
hasCorrectStoredPassword = rad.isPassphraseCorrect(dialogData.passphrase(), radHome);
if (!hasCorrectStoredPassword) {
return new ProcessOutput(-1);
}
}
var newOutput = new ProcessOutput(showDialog ? -1 : 0);
newOutput.appendStderr(RadicleBundle.message("unableToUnlock"));
return newOutput;
// either create the new identity, or attempt to unlock the existing one
rad.auth(dialogData.passphrase(), dialogData.alias(), radHome, radPath);
var output = rad.self(radHome, radPath);
lines = output.getStdoutLines(true);
radDetails = new RadDetails(lines);
projectSettings.savePassphrase(radDetails.nodeId, dialogData.passphrase());
return new ProcessOutput(0);
}

public ProcessOutput perform(CountDownLatch latch, String radHome, String radPath, IdentityDialog dialog) {
Expand Down Expand Up @@ -292,6 +301,18 @@ public static boolean isSuccess(ProcessOutput out) {
return !out.isTimeout() && !out.isCancelled() && out.getExitCode() == 0;
}

public static ProcessOutput validateAuthOutput(ProcessOutput output) {
/* rad auth return success exit code (0) and a failed msg if the password is wrong */
var isSuccess = RadAction.isSuccess(output) && !output.getStdout().contains("failed") &&
!output.getStdout().contains("Nothing to do, ssh-agent is not running.");
var pr = new ProcessOutput(isSuccess ? 0 : -1);
/* Write from stdOut to stdErr in order to appear the message in the notification */
var stdOut = output.getStdout();
var errorMessage = !Strings.isNullOrEmpty(stdOut) ? stdOut : RadicleBundle.message("radCliError");
pr.appendStderr(errorMessage);
return pr;
}

public static class ConfigureRadCliNotificationAction extends NotificationAction {
final Project project;

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import com.google.common.base.Charsets;
import com.google.common.base.Strings;
import com.intellij.execution.CommandLineUtil;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.util.ExecUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import network.radicle.jetbrains.radiclejetbrainsplugin.config.RadicleProjectSettingsHandler;
Expand Down Expand Up @@ -104,7 +104,7 @@ private String getExportRadPassphrase() {
if (Strings.isNullOrEmpty(password)) {
return "";
}
return "export RAD_PASSPHRASE=" + ExecUtil.escapeUnixShellArgument(password);
return "export RAD_PASSPHRASE=" + CommandLineUtil.posixQuote(password);
}

private String getRandomScriptName() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,18 @@ private void unlockOrCreateIdentity() {
var radHome = getPathFromTextField(radHomeField);
var radPath = getPathFromTextField(radPathField);
var radSelf = new RadSelf(radHome, radPath, myProject);
var output = radSelf.perform(radHome, radPath, dialog);
final var output = radSelf.perform(radHome, radPath, dialog);
var lines = output.getStdoutLines(true);
radDetails = new RadDetails(lines);
logger.debug("got rad details: {}", radDetails.did);
var cli = myProject.getService(RadicleCliService.class);
if (cli != null) {
cli.resetIdentity();
}
myLatch.countDown();
if (!RadAction.isSuccess(output)) {
ApplicationManager.getApplication().invokeLater(() -> this.msgLabel.setText(RadicleBundle.message("unableToUnlock")), ModalityState.any());
return;
}
// check if rad home is non-default
if (Strings.isNullOrEmpty(autoDetectRadHome.detected)) {
autoDetectRadHome.detect();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public JComponent createCommentSection(List<RadDiscussion> discussionList) {
}
var panel = new BorderLayoutPanel();
panel.setOpaque(false);
var editorPane = new MarkDownEditorPaneFactory(message, radIssue.project, radIssue.projectId, file);
var editorPane = new MarkDownEditorPaneFactory(message, radIssue.project, radIssue.projectId, file, panel);
panel.addToCenter(StatusMessageComponentFactory.INSTANCE.create(editorPane.htmlEditorPane(), StatusMessageType.WARNING));

Check warning on line 122 in src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/issues/overview/IssueComponent.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'com.intellij.collaboration.ui.codereview.timeline.StatusMessageComponentFactory' is declared in unstable package 'com.intellij.collaboration.ui.codereview.timeline' marked with @ApiStatus.Experimental

Check warning on line 122 in src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/issues/overview/IssueComponent.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'INSTANCE' is declared in unstable package 'com.intellij.collaboration.ui.codereview.timeline' marked with @ApiStatus.Experimental

Check warning on line 122 in src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/issues/overview/IssueComponent.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'com.intellij.collaboration.ui.codereview.timeline.StatusMessageComponentFactory' is declared in unstable package 'com.intellij.collaboration.ui.codereview.timeline' marked with @ApiStatus.Experimental

Check warning on line 122 in src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/issues/overview/IssueComponent.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'INSTANCE' is declared in unstable package 'com.intellij.collaboration.ui.codereview.timeline' marked with @ApiStatus.Experimental

Check warning on line 122 in src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/issues/overview/IssueComponent.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'WARNING' is declared in unstable package 'com.intellij.collaboration.ui.codereview.timeline' marked with @ApiStatus.Experimental

Check warning on line 122 in src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/issues/overview/IssueComponent.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'create(javax.swing.JComponent, com.intellij.collaboration.ui.codereview.timeline.StatusMessageType)' is declared in unstable package 'com.intellij.collaboration.ui.codereview.timeline' marked with @ApiStatus.Experimental

Check warning on line 122 in src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/issues/overview/IssueComponent.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'com.intellij.collaboration.ui.codereview.timeline.StatusMessageType' is declared in unstable package 'com.intellij.collaboration.ui.codereview.timeline' marked with @ApiStatus.Experimental
emojiPanel = new IssueEmojiPanel(issueModel, com.reactions, com.id, radDetails);
var verticalPanel = getVerticalPanel(5);
Expand Down Expand Up @@ -173,8 +173,7 @@ public boolean createComment(DragAndDropField field) {

private JComponent getDescription() {
var bodyIssue = radIssue.getDescription();
var editorPane = new MarkDownEditorPaneFactory(bodyIssue, radIssue.project, radIssue.projectId, file);
descPanel = Utils.descriptionPanel(editorPane, radIssue.project, "issue.change.description", f -> {
descPanel = Utils.descriptionPanel(bodyIssue, radIssue.project, radIssue.projectId, file, "issue.change.description", f -> {
var newDesc = f.getText();
if (Strings.isNullOrEmpty(newDesc)) {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ private void updateCommitFileComponents(LinkLabel<?> fromLabel, JLabel toLabel)
ApplicationManager.getApplication().executeOnPooledThread(() -> {
//Start loading indicator
progressStripe.startLoading();
//Get project information from httpd
//Get project information
projectInfo = getProjectInfo(mySelectedRepo);
if (projectInfo == null) {
return;
Expand Down Expand Up @@ -305,7 +305,8 @@ private void createPatch() {
RadicleBundle.message("findRemoteErrorDesc"));
return;
}
ApplicationManager.getApplication().executeOnPooledThread(() -> {
// execute in background via rad, so that the jobs get assigned a progress indicator and ij stops throwing useless errors
radicleProjectService.executeInBackground(() -> {
newPatchButton.setEnabled(false);
loadingPanel.setVisible(true);
var cli = project.getService(RadicleCliService.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public JComponent createCommitComponent() {
}

public void updateFileAndCommitComponents(GitRepository repo, String revNumber, String mainBranchHead, int retriesAttempt) {
ApplicationManager.getApplication().executeOnPooledThread(() -> {
radicleProjectService.executeInBackground(() -> {
try {
var changes = calculatePatchCommits(repo, mainBranchHead, revNumber);
calculatePatchChanges(repo, mainBranchHead, revNumber);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ public JComponent getThreadActionsComponent(ThreadModel myThreadsModel) {
}

private JComponent createComponent(RadDiscussion disc) {
var editorPane = new MarkDownEditorPaneFactory(disc.body, patch.project, patch.radProject.id, patch.repo.getRoot());
final var verticalPanel = getVerticalPanel(5);
var editorPane = new MarkDownEditorPaneFactory(disc.body, patch.project, patch.radProject.id, patch.repo.getRoot(), verticalPanel);
var revisionId = patch.findRevisionId(disc.id);
var isOutDated = !patch.isDiscussionBelongedToLatestRevision(disc);
var panelHandle = new EditablePanelHandler.PanelBuilder(patch.project, editorPane.htmlEditorPane(),
Expand Down Expand Up @@ -171,7 +172,6 @@ private JComponent createComponent(RadDiscussion disc) {
titleText.append(" (OUTDATED)");
}
builder.withHeader(new JLabel(MarkDownEditorPaneFactory.wrapHtml(titleText.toString())), actionsPanel);

Check warning on line 174 in src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/patches/review/PatchReviewThreadComponentFactory.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'withHeader(javax.swing.JComponent, javax.swing.JComponent)' is declared in unstable package 'com.intellij.collaboration.ui.codereview' marked with @ApiStatus.Experimental

Check warning on line 174 in src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/patches/review/PatchReviewThreadComponentFactory.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'withHeader(javax.swing.JComponent, javax.swing.JComponent)' is declared in unstable package 'com.intellij.collaboration.ui.codereview' marked with @ApiStatus.Experimental
var verticalPanel = getVerticalPanel(5);
verticalPanel.add(builder.build());

Check warning on line 175 in src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/patches/review/PatchReviewThreadComponentFactory.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'build()' is declared in unstable package 'com.intellij.collaboration.ui.codereview' marked with @ApiStatus.Experimental

Check warning on line 175 in src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/patches/review/PatchReviewThreadComponentFactory.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'build()' is declared in unstable package 'com.intellij.collaboration.ui.codereview' marked with @ApiStatus.Experimental
var emojiJPanel = emojiPanel.getEmojiPanel();
emojiJPanel.setBorder(BorderFactory.createEmptyBorder(PADDING_TOP_BOTTOM, PADDING_LEFT, PADDING_TOP_BOTTOM, 0));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,7 @@ public JComponent createDescSection() {
if (Strings.isNullOrEmpty(description)) {
description = RadicleBundle.message("noDescription");
}
var editorPane = new MarkDownEditorPaneFactory(description, patch.project, patch.radProject.id, file);
descSection = Utils.descriptionPanel(editorPane, patch.project, "patch.proposal.change.description", f -> {
descSection = Utils.descriptionPanel(description, patch.project, patch.radProject.id, file, "patch.proposal.change.description", f -> {
var newDesc = f.getText();
if (Strings.isNullOrEmpty(newDesc)) {
return false;
Expand Down Expand Up @@ -153,8 +152,8 @@ private JComponent createReviewComponent(RadPatch.Review review) {
var message = Strings.nullToEmpty(review.summary());
var panel = new BorderLayoutPanel();
panel.setOpaque(false);
var editorPane = new MarkDownEditorPaneFactory(message, patch.project, patch.radProject.id, file);
var myPanel = Utils.getVerticalPanel(1);
var editorPane = new MarkDownEditorPaneFactory(message, patch.project, patch.radProject.id, file, myPanel);
myPanel.setOpaque(false);
myPanel.add(editorPane.htmlEditorPane());
var verdictMsg = review.verdict() == RadPatch.Review.Verdict.ACCEPT ? RadicleBundle.message("approved") : RadicleBundle.message("requestChanges");
Expand Down Expand Up @@ -182,7 +181,7 @@ private JComponent createCommentComponent(RadDiscussion com) {
}
var panel = new BorderLayoutPanel();
panel.setOpaque(false);
var editorPane = new MarkDownEditorPaneFactory(message, patch.project, patch.radProject.id, file);
var editorPane = new MarkDownEditorPaneFactory(message, patch.project, patch.radProject.id, file, panel);
panel.addToCenter(StatusMessageComponentFactory.INSTANCE.create(editorPane.htmlEditorPane(), StatusMessageType.WARNING));

Check warning on line 185 in src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/patches/timeline/TimelineComponentFactory.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'create(javax.swing.JComponent, com.intellij.collaboration.ui.codereview.timeline.StatusMessageType)' is declared in unstable package 'com.intellij.collaboration.ui.codereview.timeline' marked with @ApiStatus.Experimental

Check warning on line 185 in src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/patches/timeline/TimelineComponentFactory.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'com.intellij.collaboration.ui.codereview.timeline.StatusMessageComponentFactory' is declared in unstable package 'com.intellij.collaboration.ui.codereview.timeline' marked with @ApiStatus.Experimental

Check warning on line 185 in src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/patches/timeline/TimelineComponentFactory.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'com.intellij.collaboration.ui.codereview.timeline.StatusMessageType' is declared in unstable package 'com.intellij.collaboration.ui.codereview.timeline' marked with @ApiStatus.Experimental

Check warning on line 185 in src/main/java/network/radicle/jetbrains/radiclejetbrainsplugin/patches/timeline/TimelineComponentFactory.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unstable API Usage

'INSTANCE' is declared in unstable package 'com.intellij.collaboration.ui.codereview.timeline' marked with @ApiStatus.Experimental
emojiPanel = new PatchEmojiPanel(patchModel, com.reactions, com.id, radDetails);
var verticalPanel = Utils.getVerticalPanel(5);
Expand Down
Loading

0 comments on commit ac9f938

Please sign in to comment.