Skip to content

Commit

Permalink
feat(csharp/ExcelAddIn): allow insecure JSON URL for Core+; choose py…
Browse files Browse the repository at this point in the history
…thon/groovy for Core (#6008)

Add GUI elements (and wire them up) 
1. ... for allowing insecure JSON URL fetches for Enterprise Core+
2. ...for selecting the session type (groovy vs python) for Community
Core
3. ...for closing the "Set Credentials" dialog box upon setting the
credentials
  • Loading branch information
kosak committed Aug 31, 2024
1 parent 0932ef2 commit afbb84b
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 33 deletions.
2 changes: 2 additions & 0 deletions csharp/ExcelAddIn/factories/CredentialsDialogFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ void OnSetCredentialsButtonClicked() {
if (cvm.IsDefault) {
sm.SetDefaultCredentials(newCreds);
}

credentialsDialog!.Close();
}

void OnTestCredentialsButtonClicked() {
Expand Down
13 changes: 11 additions & 2 deletions csharp/ExcelAddIn/factories/SessionBaseFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,21 @@ internal static class SessionBaseFactory {
public static SessionBase Create(CredentialsBase credentials, WorkerThread workerThread) {
return credentials.AcceptVisitor<SessionBase>(
core => {
var client = Client.Connect(core.ConnectionString, new ClientOptions());
var options = new ClientOptions();
options.SetSessionType(core.SessionTypeIsPython ? "python" : "groovy");
var client = Client.Connect(core.ConnectionString, options);
return new CoreSession(client);
},

corePlus => {
var session = SessionManager.FromUrl("Deephaven Excel", corePlus.JsonUrl);
var handler = new HttpClientHandler();
if (!corePlus.ValidateCertificate) {
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.ServerCertificateCustomValidationCallback = (_, _, _, _) => true;
}
var hc = new HttpClient(handler);
var json = hc.GetStringAsync(corePlus.JsonUrl).Result;
var session = SessionManager.FromJson("Deephaven Excel", json);
if (!session.PasswordAuthentication(corePlus.User, corePlus.Password, corePlus.OperateAs)) {
throw new Exception("Authentication failed");
}
Expand Down
17 changes: 11 additions & 6 deletions csharp/ExcelAddIn/models/Credentials.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,38 @@
public abstract class CredentialsBase(EndpointId id) {
public readonly EndpointId Id = id;

public static CredentialsBase OfCore(EndpointId id, string connectionString) {
return new CoreCredentials(id, connectionString);
public static CredentialsBase OfCore(EndpointId id, string connectionString, bool sessionTypeIsPython) {
return new CoreCredentials(id, connectionString, sessionTypeIsPython);
}

public static CredentialsBase OfCorePlus(EndpointId id, string jsonUrl, string userId,
string password, string operateAs) {
return new CorePlusCredentials(id, jsonUrl, userId, password, operateAs);
string password, string operateAs, bool validateCertificate) {
return new CorePlusCredentials(id, jsonUrl, userId, password, operateAs, validateCertificate);
}

public abstract T AcceptVisitor<T>(Func<CoreCredentials, T> ofCore,
Func<CorePlusCredentials, T> ofCorePlus);
}

public sealed class CoreCredentials(EndpointId id, string connectionString) : CredentialsBase(id) {
public sealed class CoreCredentials(
EndpointId id,
string connectionString,
bool sessionTypeIsPython) : CredentialsBase(id) {
public readonly string ConnectionString = connectionString;
public readonly bool SessionTypeIsPython = sessionTypeIsPython;

public override T AcceptVisitor<T>(Func<CoreCredentials, T> ofCore, Func<CorePlusCredentials, T> ofCorePlus) {
return ofCore(this);
}
}

public sealed class CorePlusCredentials(EndpointId id, string jsonUrl, string user, string password,
string operateAs) : CredentialsBase(id) {
string operateAs, bool validateCertificate) : CredentialsBase(id) {
public readonly string JsonUrl = jsonUrl;
public readonly string User = user;
public readonly string Password = password;
public readonly string OperateAs = operateAs;
public readonly bool ValidateCertificate = validateCertificate;

public override T AcceptVisitor<T>(Func<CoreCredentials, T> ofCore, Func<CorePlusCredentials, T> ofCorePlus) {
return ofCorePlus(this);
Expand Down
50 changes: 47 additions & 3 deletions csharp/ExcelAddIn/viewmodels/CredentialsDialogViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ public static CredentialsDialogViewModel OfIdButOtherwiseEmpty(string id) {
}

public static CredentialsDialogViewModel OfIdAndCredentials(string id, CredentialsBase credentials) {
var result = new CredentialsDialogViewModel { Id = id };
var result = new CredentialsDialogViewModel {
Id = credentials.Id.Id
};
_ = credentials.AcceptVisitor(
core => {
result._isCorePlus = false;
result.ConnectionString = core.ConnectionString;
result.SessionTypeIsPython = core.SessionTypeIsPython;
return Unit.Instance;
},
corePlus => {
Expand All @@ -29,6 +32,7 @@ public static CredentialsDialogViewModel OfIdAndCredentials(string id, Credentia
result.UserId = corePlus.User;
result.Password = corePlus.Password;
result.OperateAs = corePlus.OperateAs;
result.ValidateCertificate = corePlus.ValidateCertificate;
return Unit.Instance;
});

Expand All @@ -38,12 +42,14 @@ public static CredentialsDialogViewModel OfIdAndCredentials(string id, Credentia
private string _id = "";
private bool _isDefault = false;
private bool _isCorePlus = true;
private bool _sessionTypeIsPython = true;

// Core properties
private string _connectionString = "";

// Core+ properties
private string _jsonUrl = "";
private bool _validateCertificate = true;
private string _userId = "";
private string _password = "";
private string _operateAs = "";
Expand Down Expand Up @@ -80,8 +86,8 @@ void CheckMissing(string field, string name) {

var epId = new EndpointId(_id);
result = _isCorePlus
? CredentialsBase.OfCorePlus(epId, _jsonUrl, _userId, _password, _operateAs)
: CredentialsBase.OfCore(epId, _connectionString);
? CredentialsBase.OfCorePlus(epId, _jsonUrl, _userId, _password, _operateAs, _validateCertificate)
: CredentialsBase.OfCore(epId, _connectionString, _sessionTypeIsPython);
return true;
}

Expand Down Expand Up @@ -201,6 +207,44 @@ public string OperateAs {
}
}

public bool ValidateCertificate {
get => _validateCertificate;
set {
if (_validateCertificate == value) {
return;
}

_validateCertificate = value;
OnPropertyChanged();
}
}

public bool SessionTypeIsPython {
get => _sessionTypeIsPython;
set {
if (_sessionTypeIsPython == value) {
return;
}

_sessionTypeIsPython = value;
OnPropertyChanged();
OnPropertyChanged(nameof(SessionTypeIsGroovy));
}
}

public bool SessionTypeIsGroovy {
get => !_sessionTypeIsPython;
set {
if (!_sessionTypeIsPython == value) {
return;
}

_sessionTypeIsPython = !value;
OnPropertyChanged();
OnPropertyChanged(nameof(SessionTypeIsPython));
}
}

private void OnPropertyChanged([CallerMemberName] string? name = null) {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
Expand Down
97 changes: 77 additions & 20 deletions csharp/ExcelAddIn/views/CredentialsDialog.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions csharp/ExcelAddIn/views/CredentialsDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,18 @@ public CredentialsDialog(CredentialsDialogViewModel vm, Action onSetCredentialsB
userIdBox.DataBindings.Add(nameof(userIdBox.Text), vm, nameof(vm.UserId));
passwordBox.DataBindings.Add(nameof(passwordBox.Text), vm, nameof(vm.Password));
operateAsBox.DataBindings.Add(nameof(operateAsBox.Text), vm, nameof(vm.OperateAs));
validateCertCheckBox.DataBindings.Add(nameof(validateCertCheckBox.Checked), vm, nameof(vm.ValidateCertificate));

// Bind the Core property (there's just one)
connectionStringBox.DataBindings.Add(nameof(connectionStringBox.Text),
vm, nameof(vm.ConnectionString));

// Bind the SessionType checkboxes
sessionTypeIsPythonButton.DataBindings.Add(nameof(sessionTypeIsPythonButton.Checked),
vm, nameof(vm.SessionTypeIsPython));
sessionTypeIsGroovyButton.DataBindings.Add(nameof(sessionTypeIsGroovyButton.Checked),
vm, nameof(vm.SessionTypeIsGroovy));

// Bind the IsDefault property
makeDefaultCheckBox.DataBindings.Add(nameof(makeDefaultCheckBox.Checked),
vm, nameof(vm.IsDefault));
Expand Down
Loading

0 comments on commit afbb84b

Please sign in to comment.