credential lists are now loaded and saved from the provider list

This commit is contained in:
David Sparer
2017-02-11 20:30:39 -07:00
parent e5b22255e9
commit 72b8cd2ac8
13 changed files with 444 additions and 170 deletions

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using mRemoteNG.Credential;
@@ -11,25 +12,19 @@ namespace mRemoteNG.Config.Serializers.CredentialProviderSerializer
public string Serialize(IEnumerable<ICredentialRepository> credentialProviderCatalog)
{
var xmlDocument = new XDocument(new XDeclaration("1.0", "utf-8", null));
var rootElement = new XElement(XName.Get("CredentialRepositories"));
var rootElement = new XElement("CredentialRepositories",
from provider in credentialProviderCatalog
select new XElement("CredentialRepository",
new XAttribute("Id", provider.Config.Id),
new XAttribute("TypeName", provider.Config.TypeName),
new XAttribute("Title", provider.Config.Title),
new XAttribute("Source", provider.Config.Source)
)
);
xmlDocument.Add(rootElement);
foreach (var provider in credentialProviderCatalog)
{
rootElement.Add(SerializeCredentialProvider(provider));
}
var declaration = xmlDocument.Declaration.ToString();
var documentBody = xmlDocument.ToString();
return string.Concat(declaration, Environment.NewLine, documentBody);
}
private XElement SerializeCredentialProvider(ICredentialRepository provider)
{
return new XElement("CredentialRepository",
new XAttribute(XName.Get("Id"), provider.Config.Id),
new XAttribute(XName.Get("TypeName"), provider.Config.TypeName),
new XAttribute(XName.Get("Title"), provider.Config.Title),
new XAttribute(XName.Get("Source"), provider.Config.Source)
);
}
}
}

View File

@@ -20,6 +20,7 @@ namespace mRemoteNG.Credential
if (Contains(credentialProvider.Config.Id)) return;
_credentialProviders.Add(credentialProvider);
credentialProvider.PropertyChanged += CredentialProviderOnPropertyChanged;
credentialProvider.CollectionChanged += CredentialProviderOnCollectionChanged;
RaiseCollectionChangedEvent(NotifyCollectionChangedAction.Add, new[] { credentialProvider });
}
@@ -27,6 +28,7 @@ namespace mRemoteNG.Credential
{
if (!Contains(credentialProvider.Config.Id)) return;
credentialProvider.PropertyChanged -= CredentialProviderOnPropertyChanged;
credentialProvider.CollectionChanged -= CredentialProviderOnCollectionChanged;
_credentialProviders.Remove(credentialProvider);
RaiseCollectionChangedEvent(NotifyCollectionChangedAction.Remove, new[] {credentialProvider});
}
@@ -58,13 +60,28 @@ namespace mRemoteNG.Credential
private void CredentialProviderOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
var repo = sender as ICredentialRepository;
if (repo == null) return;
repo.SaveCredentials();
RaiseCollectionChangedEvent(NotifyCollectionChangedAction.Add, new[] { sender });
}
private void CredentialProviderOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
{
var repo = sender as ICredentialRepository;
if (repo == null) return;
repo.SaveCredentials();
RaiseCollectionChangedEvent(sender, args);
}
public event NotifyCollectionChangedEventHandler CollectionChanged;
private void RaiseCollectionChangedEvent(NotifyCollectionChangedAction action, IList items)
{
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(action, items));
}
private void RaiseCollectionChangedEvent(object sender, NotifyCollectionChangedEventArgs e)
{
CollectionChanged?.Invoke(sender, e);
}
}
}

View File

@@ -1,11 +1,12 @@
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using mRemoteNG.Credential.Repositories;
namespace mRemoteNG.Credential
{
public interface ICredentialRepository : INotifyPropertyChanged
public interface ICredentialRepository : INotifyPropertyChanged, INotifyCollectionChanged
{
ICredentialRepositoryConfig Config { get; }
IList<ICredentialRecord> CredentialRecords { get; }

View File

@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using mRemoteNG.Config.DataProviders;
@@ -27,7 +29,8 @@ namespace mRemoteNG.Credential.Repositories
throw new ArgumentNullException(nameof(config));
Config = config;
CredentialRecords = new List<ICredentialRecord>();
CredentialRecords = new ObservableCollection<ICredentialRecord>();
((ObservableCollection<ICredentialRecord>) CredentialRecords).CollectionChanged += RaiseCollectionChangedEvent;
Config.PropertyChanged += (sender, args) => RaisePropertyChangedEvent(args);
_dataProvider = dataProvider;
_deserializer = new XmlCredentialDeserializer();
@@ -52,9 +55,15 @@ namespace mRemoteNG.Credential.Repositories
}
public event PropertyChangedEventHandler PropertyChanged;
public event NotifyCollectionChangedEventHandler CollectionChanged;
protected virtual void RaisePropertyChangedEvent(PropertyChangedEventArgs args)
{
PropertyChanged?.Invoke(this, args);
}
protected virtual void RaiseCollectionChangedEvent(object sender, NotifyCollectionChangedEventArgs args)
{
CollectionChanged?.Invoke(this, args);
}
}
}

View File

@@ -0,0 +1,127 @@
namespace mRemoteNG.UI.Controls
{
partial class CredentialRecordListView
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.objectListView1 = new BrightIdeasSoftware.ObjectListView();
this.olvColumnCredentialId = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
this.olvColumnTitle = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
this.olvColumnUsername = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
this.olvColumnDomain = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
this.olvColumnRepositorySource = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
this.olvColumnRepositoryTitle = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
((System.ComponentModel.ISupportInitialize)(this.objectListView1)).BeginInit();
this.SuspendLayout();
//
// objectListView1
//
this.objectListView1.AllColumns.Add(this.olvColumnTitle);
this.objectListView1.AllColumns.Add(this.olvColumnUsername);
this.objectListView1.AllColumns.Add(this.olvColumnDomain);
this.objectListView1.AllColumns.Add(this.olvColumnCredentialId);
this.objectListView1.AllColumns.Add(this.olvColumnRepositoryTitle);
this.objectListView1.AllColumns.Add(this.olvColumnRepositorySource);
this.objectListView1.CellEditUseWholeCell = false;
this.objectListView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.olvColumnTitle,
this.olvColumnUsername,
this.olvColumnDomain,
this.olvColumnRepositoryTitle});
this.objectListView1.CopySelectionOnControlC = false;
this.objectListView1.CopySelectionOnControlCUsesDragSource = false;
this.objectListView1.Cursor = System.Windows.Forms.Cursors.Default;
this.objectListView1.Dock = System.Windows.Forms.DockStyle.Fill;
this.objectListView1.FullRowSelect = true;
this.objectListView1.HideSelection = false;
this.objectListView1.Location = new System.Drawing.Point(0, 0);
this.objectListView1.Name = "objectListView1";
this.objectListView1.SelectAllOnControlA = false;
this.objectListView1.ShowGroups = false;
this.objectListView1.Size = new System.Drawing.Size(367, 204);
this.objectListView1.TabIndex = 2;
this.objectListView1.UseCompatibleStateImageBehavior = false;
this.objectListView1.UseNotifyPropertyChanged = true;
this.objectListView1.View = System.Windows.Forms.View.Details;
//
// olvColumnCredentialId
//
this.olvColumnCredentialId.AspectName = "";
this.olvColumnCredentialId.DisplayIndex = 0;
this.olvColumnCredentialId.IsEditable = false;
this.olvColumnCredentialId.IsVisible = false;
this.olvColumnCredentialId.Text = "Credential ID";
//
// olvColumnTitle
//
this.olvColumnTitle.AspectName = "";
this.olvColumnTitle.Groupable = false;
this.olvColumnTitle.Text = "Title";
//
// olvColumnUsername
//
this.olvColumnUsername.AspectName = "";
this.olvColumnUsername.Text = "Username";
//
// olvColumnDomain
//
this.olvColumnDomain.AspectName = "";
this.olvColumnDomain.Text = "Domain";
//
// olvColumnRepositorySource
//
this.olvColumnRepositorySource.DisplayIndex = 4;
this.olvColumnRepositorySource.IsVisible = false;
this.olvColumnRepositorySource.Text = "Source";
//
// olvColumnRepositoryTitle
//
this.olvColumnRepositoryTitle.Text = "Repository Title";
//
// CredentialRecordListView
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.objectListView1);
this.Name = "CredentialRecordListView";
this.Size = new System.Drawing.Size(367, 204);
((System.ComponentModel.ISupportInitialize)(this.objectListView1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private BrightIdeasSoftware.ObjectListView objectListView1;
private BrightIdeasSoftware.OLVColumn olvColumnCredentialId;
private BrightIdeasSoftware.OLVColumn olvColumnTitle;
private BrightIdeasSoftware.OLVColumn olvColumnUsername;
private BrightIdeasSoftware.OLVColumn olvColumnDomain;
private BrightIdeasSoftware.OLVColumn olvColumnRepositorySource;
private BrightIdeasSoftware.OLVColumn olvColumnRepositoryTitle;
}
}

View File

@@ -0,0 +1,122 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using BrightIdeasSoftware;
using mRemoteNG.Credential;
using mRemoteNG.UI.Controls.PageSequence;
namespace mRemoteNG.UI.Controls
{
public partial class CredentialRecordListView : SequencedControl
{
private ICredentialRepositoryList _credentialRepositoryList = new CredentialRepositoryList();
public ICredentialRepositoryList CredentialRepositoryList
{
get { return _credentialRepositoryList; }
set
{
_credentialRepositoryList.CollectionChanged -= CredentialRepositoryListOnCollectionChanged;
_credentialRepositoryList = value;
_credentialRepositoryList.CollectionChanged += CredentialRepositoryListOnCollectionChanged;
SetObjectList();
objectListView1.AutoResizeColumns();
}
}
public KeyValuePair<ICredentialRecord, ICredentialRepository> SelectedObject => CastRowObject(objectListView1.SelectedObject);
public CredentialRecordListView()
{
InitializeComponent();
olvColumnCredentialId.AspectGetter = CredentialIdAspectGetter;
olvColumnTitle.AspectGetter = CredentialTitleAspectGetter;
olvColumnUsername.AspectGetter = CredentialUsernameAspectGetter;
olvColumnDomain.AspectGetter = CredentialDomainAspectGetter;
olvColumnRepositorySource.AspectGetter = CredentialSourceAspectGetter;
olvColumnRepositoryTitle.AspectGetter = RepoTitleAspectGetter;
objectListView1.SelectionChanged += (sender, args) => RaiseSelectionChangedEvent();
objectListView1.CellClick += RaiseCellClickEvent;
ApplyLanguage();
}
private void SetObjectList()
{
var objects = new Dictionary<ICredentialRecord, ICredentialRepository>();
foreach (var repository in _credentialRepositoryList.CredentialProviders)
{
foreach (var credential in repository.CredentialRecords)
objects.Add(credential, repository);
}
objectListView1.SetObjects(objects, true);
}
private void ApplyLanguage()
{
olvColumnTitle.Text = Language.strTitle;
olvColumnUsername.Text = Language.strPropertyNameUsername;
olvColumnDomain.Text = Language.strPropertyNameDomain;
}
private object CredentialIdAspectGetter(object rowObject)
{
var keyValuePair = CastRowObject(rowObject);
return keyValuePair.Key.Id;
}
private object CredentialTitleAspectGetter(object rowObject)
{
var keyValuePair = CastRowObject(rowObject);
return keyValuePair.Key.Title;
}
private object CredentialUsernameAspectGetter(object rowObject)
{
var keyValuePair = CastRowObject(rowObject);
return keyValuePair.Key.Username;
}
private object CredentialDomainAspectGetter(object rowObject)
{
var keyValuePair = CastRowObject(rowObject);
return keyValuePair.Key.Domain;
}
private object CredentialSourceAspectGetter(object rowObject)
{
var keyValuePair = CastRowObject(rowObject);
return keyValuePair.Value.Config.Source;
}
private object RepoTitleAspectGetter(object rowObject)
{
var keyValuePair = CastRowObject(rowObject);
return keyValuePair.Value.Config.Title;
}
private KeyValuePair<ICredentialRecord, ICredentialRepository> CastRowObject(object model)
{
if (!(model is KeyValuePair<ICredentialRecord, ICredentialRepository>)) return default(KeyValuePair<ICredentialRecord, ICredentialRepository>);
var keyValuePair = (KeyValuePair<ICredentialRecord, ICredentialRepository>)model;
return keyValuePair;
}
private void CredentialRepositoryListOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
{
SetObjectList();
}
public event EventHandler SelectionChanged;
private void RaiseSelectionChangedEvent()
{
SelectionChanged?.Invoke(this, EventArgs.Empty);
}
public event EventHandler<CellClickEventArgs> CellClick;
private void RaiseCellClickEvent(object sender, CellClickEventArgs args)
{
CellClick?.Invoke(sender, args);
}
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -59,6 +59,8 @@ namespace mRemoteNG.UI.Forms.CredentialManagerPages
private void buttonAccept_Click_1(object sender, EventArgs e)
{
SaveFormToCredential();
if (!_credentialRepository.CredentialRecords.Contains(_credentialRecord))
_credentialRepository.CredentialRecords.Add(_credentialRecord);
RaiseNextPageEvent();
}

View File

@@ -28,80 +28,12 @@
/// </summary>
private void InitializeComponent()
{
this.objectListView1 = new BrightIdeasSoftware.ObjectListView();
this.olvColumnCredentialId = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
this.olvColumnTitle = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
this.olvColumnUsername = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
this.olvColumnDomain = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
this.olvColumnSource = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
this.buttonAdd = new System.Windows.Forms.Button();
this.buttonRemove = new System.Windows.Forms.Button();
this.buttonEdit = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.objectListView1)).BeginInit();
this.credentialRecordListView = new mRemoteNG.UI.Controls.CredentialRecordListView();
this.SuspendLayout();
//
// objectListView1
//
this.objectListView1.AllColumns.Add(this.olvColumnCredentialId);
this.objectListView1.AllColumns.Add(this.olvColumnTitle);
this.objectListView1.AllColumns.Add(this.olvColumnUsername);
this.objectListView1.AllColumns.Add(this.olvColumnDomain);
this.objectListView1.AllColumns.Add(this.olvColumnSource);
this.objectListView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.objectListView1.CellEditUseWholeCell = false;
this.objectListView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.olvColumnCredentialId,
this.olvColumnTitle,
this.olvColumnUsername,
this.olvColumnDomain,
this.olvColumnSource});
this.objectListView1.CopySelectionOnControlC = false;
this.objectListView1.CopySelectionOnControlCUsesDragSource = false;
this.objectListView1.Cursor = System.Windows.Forms.Cursors.Default;
this.objectListView1.FullRowSelect = true;
this.objectListView1.HideSelection = false;
this.objectListView1.Location = new System.Drawing.Point(0, 0);
this.objectListView1.Name = "objectListView1";
this.objectListView1.SelectAllOnControlA = false;
this.objectListView1.ShowGroups = false;
this.objectListView1.Size = new System.Drawing.Size(383, 235);
this.objectListView1.TabIndex = 1;
this.objectListView1.UseCompatibleStateImageBehavior = false;
this.objectListView1.UseNotifyPropertyChanged = true;
this.objectListView1.View = System.Windows.Forms.View.Details;
//
// olvColumnCredentialId
//
this.olvColumnCredentialId.AspectName = "";
this.olvColumnCredentialId.IsEditable = false;
this.olvColumnCredentialId.IsVisible = false;
this.olvColumnCredentialId.Text = "Credential ID";
//
// olvColumnTitle
//
this.olvColumnTitle.AspectName = "";
this.olvColumnTitle.FillsFreeSpace = true;
this.olvColumnTitle.Groupable = false;
this.olvColumnTitle.Text = "Title";
//
// olvColumnUsername
//
this.olvColumnUsername.AspectName = "";
this.olvColumnUsername.FillsFreeSpace = true;
this.olvColumnUsername.Text = "Username";
//
// olvColumnDomain
//
this.olvColumnDomain.AspectName = "";
this.olvColumnDomain.FillsFreeSpace = true;
this.olvColumnDomain.Text = "Domain";
//
// olvColumnSource
//
this.olvColumnSource.Text = "Source";
//
// buttonAdd
//
this.buttonAdd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
@@ -141,31 +73,34 @@
this.buttonEdit.UseVisualStyleBackColor = true;
this.buttonEdit.Click += new System.EventHandler(this.buttonEdit_Click);
//
// credentialRecordListView
//
this.credentialRecordListView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.credentialRecordListView.Location = new System.Drawing.Point(0, 0);
this.credentialRecordListView.Name = "credentialRecordListView";
this.credentialRecordListView.Size = new System.Drawing.Size(383, 235);
this.credentialRecordListView.TabIndex = 6;
//
// CredentialListPage
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.credentialRecordListView);
this.Controls.Add(this.buttonEdit);
this.Controls.Add(this.buttonAdd);
this.Controls.Add(this.buttonRemove);
this.Controls.Add(this.objectListView1);
this.Name = "CredentialListPage";
this.Size = new System.Drawing.Size(383, 276);
((System.ComponentModel.ISupportInitialize)(this.objectListView1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private BrightIdeasSoftware.ObjectListView objectListView1;
private BrightIdeasSoftware.OLVColumn olvColumnTitle;
private BrightIdeasSoftware.OLVColumn olvColumnUsername;
private BrightIdeasSoftware.OLVColumn olvColumnDomain;
private System.Windows.Forms.Button buttonAdd;
private System.Windows.Forms.Button buttonRemove;
private BrightIdeasSoftware.OLVColumn olvColumnCredentialId;
private BrightIdeasSoftware.OLVColumn olvColumnSource;
private System.Windows.Forms.Button buttonEdit;
private Controls.CredentialRecordListView credentialRecordListView;
}
}

View File

@@ -25,76 +25,24 @@ namespace mRemoteNG.UI.Forms.CredentialManagerPages
_credentialRepositoryList = credentialRepositoryList;
InitializeComponent();
ApplyLanguage();
CredentialsChanged += (sender, args) => SetObjectList();
objectListView1.CellClick += HandleCellDoubleClick;
objectListView1.SelectionChanged += ObjectListView1OnSelectionChanged;
objectListView1.KeyDown += ObjectListView1OnEnterPressed;
objectListView1.KeyDown += OnAPressed;
objectListView1.KeyDown += OnDeletePressed;
olvColumnCredentialId.AspectGetter = CredentialIdAspectGetter;
olvColumnTitle.AspectGetter = CredentialTitleAspectGetter;
olvColumnUsername.AspectGetter = CredentialUsernameAspectGetter;
olvColumnDomain.AspectGetter = CredentialDomainAspectGetter;
olvColumnSource.AspectGetter = CredentialSourceAspectGetter;
SetObjectList();
}
private object CredentialIdAspectGetter(object rowObject)
{
var keyValuePair = CastRowObject(rowObject);
return keyValuePair.Key.Id;
}
private object CredentialTitleAspectGetter(object rowObject)
{
var keyValuePair = CastRowObject(rowObject);
return keyValuePair.Key.Title;
}
private object CredentialUsernameAspectGetter(object rowObject)
{
var keyValuePair = CastRowObject(rowObject);
return keyValuePair.Key.Username;
}
private object CredentialDomainAspectGetter(object rowObject)
{
var keyValuePair = CastRowObject(rowObject);
return keyValuePair.Key.Domain;
}
private object CredentialSourceAspectGetter(object rowObject)
{
var keyValuePair = CastRowObject(rowObject);
return keyValuePair.Value.Config.Source;
}
private void SetObjectList()
{
var objects = new Dictionary<ICredentialRecord, ICredentialRepository>();
foreach (var repository in _credentialRepositoryList.CredentialProviders)
{
foreach(var credential in repository.CredentialRecords)
objects.Add(credential, repository);
}
objectListView1.SetObjects(objects, true);
credentialRecordListView.CellClick += HandleCellDoubleClick;
credentialRecordListView.SelectionChanged += ObjectListView1OnSelectionChanged;
credentialRecordListView.KeyDown += ObjectListView1OnEnterPressed;
credentialRecordListView.KeyDown += OnAPressed;
credentialRecordListView.KeyDown += OnDeletePressed;
credentialRecordListView.CredentialRepositoryList = _credentialRepositoryList;
}
private void ApplyLanguage()
{
Text = Language.strCredentialManager;
olvColumnTitle.Text = Language.strTitle;
olvColumnUsername.Text = Language.strPropertyNameUsername;
olvColumnDomain.Text = Language.strPropertyNameDomain;
buttonAdd.Text = Language.strAdd;
buttonRemove.Text = Language.strRemove;
}
private void RemoveSelectedCredential()
{
if (objectListView1.SelectedObject == null) return;
var selectedCredential = CastRowObject(objectListView1.SelectedObject);
var selectedCredential = credentialRecordListView.SelectedObject;
if (!DeletionConfirmer.Confirm(selectedCredential.Key)) return;
selectedCredential.Value.CredentialRecords.Remove(selectedCredential.Key);
RaiseCredentialsChangedEvent(this);
@@ -103,8 +51,7 @@ namespace mRemoteNG.UI.Forms.CredentialManagerPages
private void HandleCellDoubleClick(object sender, CellClickEventArgs cellClickEventArgs)
{
if (cellClickEventArgs.ClickCount < 2) return;
var clickedCredential = CastRowObject(cellClickEventArgs.Model);
EditCredential(clickedCredential);
EditCredential(credentialRecordListView.SelectedObject);
}
private void AddCredential()
@@ -136,8 +83,7 @@ namespace mRemoteNG.UI.Forms.CredentialManagerPages
private void buttonEdit_Click(object sender, EventArgs e)
{
var selectedCredential = CastRowObject(objectListView1.SelectedObject);
EditCredential(selectedCredential);
EditCredential(credentialRecordListView.SelectedObject);
}
private void buttonRemove_Click(object sender, EventArgs e)
@@ -145,18 +91,10 @@ namespace mRemoteNG.UI.Forms.CredentialManagerPages
RemoveSelectedCredential();
}
private KeyValuePair<ICredentialRecord, ICredentialRepository> CastRowObject(object model)
{
if (!(model is KeyValuePair<ICredentialRecord, ICredentialRepository>)) return default(KeyValuePair<ICredentialRecord, ICredentialRepository>);
var keyValuePair = (KeyValuePair<ICredentialRecord, ICredentialRepository>)model;
return keyValuePair;
}
private void ObjectListView1OnEnterPressed(object sender, KeyEventArgs keyEventArgs)
{
if (keyEventArgs.KeyCode != Keys.Enter) return;
var selectedCredentialAndRepoPair = CastRowObject(objectListView1.SelectedObject);
EditCredential(selectedCredentialAndRepoPair);
EditCredential(credentialRecordListView.SelectedObject);
keyEventArgs.Handled = true;
keyEventArgs.SuppressKeyPress = true;
}
@@ -179,7 +117,7 @@ namespace mRemoteNG.UI.Forms.CredentialManagerPages
private void ObjectListView1OnSelectionChanged(object sender, EventArgs eventArgs)
{
buttonRemove.Enabled = objectListView1.SelectedObjects.Count != 0;
buttonRemove.Enabled = credentialRecordListView.SelectedObject.Key != null;
}
public event EventHandler CredentialsChanged;

View File

@@ -68,7 +68,7 @@ namespace mRemoteNG.UI.Forms.CredentialManagerPages.CredentialRepositoryEditorPa
private bool AllRequiredFieldsFilledOut()
{
return newPasswordBoxes.PasswordsMatch && !string.IsNullOrEmpty(_repositoryConfig.Source);
return newPasswordBoxes.PasswordsMatch && !string.IsNullOrEmpty(textBoxFilePath.Text);
}
private void buttonBack_Click(object sender, EventArgs e)

View File

@@ -21,7 +21,6 @@ namespace mRemoteNG.UI.Forms.CredentialManagerPages
private void Continue(ICredentialRepository credentialRepository)
{
var newCred = new CredentialRecord();
credentialRepository.CredentialRecords.Add(newCred);
var newCredPage = new CredentialEditorPage(newCred, credentialRepository);
RaisePageReplacementEvent(newCredPage, RelativePagePosition.NextPage);
RaiseNextPageEvent();

View File

@@ -299,6 +299,12 @@
<Compile Include="UI\Controls\CredentialRecordListBox.Designer.cs">
<DependentUpon>CredentialRecordListBox.cs</DependentUpon>
</Compile>
<Compile Include="UI\Controls\CredentialRecordListView.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="UI\Controls\CredentialRecordListView.Designer.cs">
<DependentUpon>CredentialRecordListView.cs</DependentUpon>
</Compile>
<Compile Include="UI\Controls\CredentialRepositoryListView.cs">
<SubType>UserControl</SubType>
</Compile>
@@ -675,6 +681,9 @@
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Resources\Language\Language.tr-TR.resx" />
<EmbeddedResource Include="UI\Controls\CredentialRecordListView.resx">
<DependentUpon>CredentialRecordListView.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="UI\Controls\CredentialRepositoryListView.resx">
<DependentUpon>CredentialRepositoryListView.cs</DependentUpon>
</EmbeddedResource>