Mercurial > hg > marc.net
diff ARClient/frmEditResource.cs @ 0:90ea68d4f92f
First release
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Sat, 08 Nov 2014 22:43:51 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ARClient/frmEditResource.cs Sat Nov 08 22:43:51 2014 +0100 @@ -0,0 +1,371 @@ +using System; +using System.Collections; +using System.Net; +using System.Text; +using System.Windows.Forms; + +namespace ARClient { + partial class frmEditResource : Form { + public Form1 MainForm { get; set; } + public Byte[] Label = null; + public IDictionary Value = new Hashtable(); + public UInt32 UpdateSerial = 0; + + public frmEditResource() { + InitializeComponent(); + radTypeDomain.Checked = true; + } + + private void frmEditResource_Load(object sender, EventArgs e) { + tabControl1_SelectedIndexChanged(null, null); + } + public void ImportData() { + tabControl1.SelectedIndex = 1; + } + + private void radType_CheckedChanged(object sender, EventArgs e) { + if (radTypeDomain.Checked) { + lblLabelHint.Text = "Enter the domain name including the top level component. For an Anonet domain, your domain name must end in '.ano'."; + if (Label != null && Label.Length > 1 && Label[0] == 4) txtLabelValue.Text = Encoding.UTF8.GetString(Label, 1, Label.Length - 1); + else txtLabelValue_TextChanged(sender, e); + } else if (radTypeIPv4.Checked) { + lblLabelHint.Text = "Enter the IPv4 network in CIDR notation, e.g. '1.2.3.0/24'."; + if (Label != null && Label.Length == 6 && Label[0] == 1) txtLabelValue.Text = Label[1].ToString() + "." + Label[2].ToString() + "." + Label[3].ToString() + "." + Label[4].ToString() + "/" + Label[5].ToString(); + else txtLabelValue_TextChanged(sender, e); + } else if (radTypeIPv6.Checked) { + lblLabelHint.Text = "Enter the IPv6 network in CIDR notation, e.g. 'fd63:1e39:6f73:001b::/64'."; + if (Label != null && Label.Length == 18 && Label[0] == 2) { + Byte[] address = new Byte[16]; + Buffer.BlockCopy(Label, 2, address, 0, 16); + txtLabelValue.Text = (new IPAddress(address)).ToString() + "/" + Label[17].ToString(); + } else txtLabelValue_TextChanged(sender, e); + } else if (radTypeASNumber.Checked) { + lblLabelHint.Text = "Enter the AS number."; + if (Label != null && Label.Length == 5 && Label[0] == 3) txtLabelValue.Text = Functions.DecodeInt32BigEndian(Label, 1).ToString(); + else txtLabelValue_TextChanged(sender, e); + } else if (radTypeOtherHex.Checked) { + lblLabelHint.Text = "Expert usage! Enter the raw label value in hexadecimal notation."; + if (Label != null) txtLabelValue.Text = Functions.bin2hex(Label); + else txtLabelValue_TextChanged(sender, e); + } else { + lblLabelHint.Text = "Select a resource type."; + } + } + + private Boolean TryParseLabel() { + Label = null; + if (radTypeDomain.Checked) { + if (txtLabelValue.Text.Length < 1) return false; + Byte[] bytes = Encoding.UTF8.GetBytes(txtLabelValue.Text.ToLowerInvariant()); + Label = new Byte[bytes.Length + 1]; + Label[0] = 4; + bytes.CopyTo(Label, 1); + return true; + } else if (radTypeIPv4.Checked) { + String[] parts1 = txtLabelValue.Text.Split('/'); + if (parts1.Length != 2) return false; + String[] parts2 = parts1[0].Split('.'); + if (parts2.Length != 4) return false; + Byte[] bytes = new Byte[6]; + bytes[0] = 1; + for (int i = 0; i < 4; i++) if (!Byte.TryParse(parts2[i], out bytes[i + 1])) return false; + if (!Byte.TryParse(parts1[1], out bytes[5])) return false; + if (bytes[5] > 32) return false; + Label = bytes; + return true; + } else if (radTypeIPv6.Checked) { + String[] parts1 = txtLabelValue.Text.Split('/'); + if (parts1.Length != 2) return false; + IPAddress addr; + if (!IPAddress.TryParse(parts1[0], out addr)) return false; + if (addr.AddressFamily != System.Net.Sockets.AddressFamily.InterNetworkV6) return false; + Byte len; + if (!Byte.TryParse(parts1[1], out len)) return false; + if (len > 128) return false; + Label = new Byte[18]; + Label[0] = 2; + addr.GetAddressBytes().CopyTo(Label, 1); + Label[17] = len; + return true; + } else if (radTypeASNumber.Checked) { + UInt32 asn; + if (!UInt32.TryParse(txtLabelValue.Text, out asn)) return false; + Label = new Byte[5]; + Label[0] = 3; + Functions.EncodeInt32BigEndian(asn).CopyTo(Label, 1); + return true; + } else if (radTypeOtherHex.Checked) { + Label = Functions.hex2bin(txtLabelValue.Text); + return Label != null; + } else { + return false; + } + } + + private void txtLabelValue_TextChanged(object sender, EventArgs e) { + Boolean valid = TryParseLabel(); + lblLabelValid.Visible = !valid; + btnLabelNext.Visible = valid; + } + + private void btnLabelNext_Click(object sender, EventArgs e) { + tabControl1.SelectedIndex++; + } + + private void UpdateValueTree() { + lvwData.SuspendLayout(); + lvwData.Nodes.Clear(); + + if (Value is IDictionary) { + foreach (DictionaryEntry child in (IDictionary)Value) lvwData.Nodes.Add(AddResourceValueInTree(child.Key.ToString() + ": ", child.Value)); + } else if (Value is ICollection) { + foreach (Object child in (ICollection)Value) lvwData.Nodes.Add(AddResourceValueInTree(String.Empty, child)); + } else if (Value == null) { + lvwData.Nodes.Add("Null").Tag = null; + } else { + lvwData.Nodes.Add(Value.ToString()).Tag = Value; + } + + lvwData.ResumeLayout(); + } + private TreeNode AddResourceValueInTree(String prefix, Object value) { + TreeNode node = new TreeNode(); + if (value is IDictionary) { + node.Text = prefix + "Dictionary"; + foreach (DictionaryEntry child in (IDictionary)value) node.Nodes.Add(AddResourceValueInTree(child.Key.ToString() + ": ", child.Value)); + } else if (value is ICollection) { + node.Text = prefix + "Collection"; + foreach (Object child in (ICollection)value) node.Nodes.Add(AddResourceValueInTree(String.Empty, child)); + } else if (value == null) { + node.Text = prefix + "Null"; + } else { + node.Text = prefix + value.ToString(); + } + node.Tag = value; + node.Expand(); + return node; + } + + private void btnDataSetOwner_Click(object sender, EventArgs e) { + frmTextInput form = new frmTextInput(); + form.Text = "MARC - Resource data"; + form.Description = "Enter the owner name:"; + if (!(Value is IDictionary)) Value = new Hashtable(); + if (Value.Contains("owner")) form.Value = Value["owner"].ToString(); + if (form.ShowDialog(this) != DialogResult.OK) return; + Value["owner"] = form.Value; + UpdateValueTree(); + } + private void btnDataSetDescription_Click(object sender, EventArgs e) { + frmTextInput form = new frmTextInput(); + form.Text = "MARC - Resource data"; + form.Description = "Enter the resource description:"; + if (!(Value is IDictionary)) Value = new Hashtable(); + if (Value.Contains("descr")) form.Value = Value["descr"].ToString(); + if (form.ShowDialog(this) != DialogResult.OK) return; + Value["descr"] = form.Value; + UpdateValueTree(); + } + private void btnDataAddDNS_Click(object sender, EventArgs e) { + frmTextInput form = new frmTextInput(); + form.Text = "MARC - Resource data"; + form.Description = "Enter the nameserver name in the current zone, or add a dot ad the end to use a nameserver in another zone:"; + form.Value = "ns1"; + if (form.ShowDialog(this) != DialogResult.OK) return; + String nsname = form.Value; + String nsip4 = null, nsip6 = null; + if (!nsname.EndsWith(".")) { + form.Description = "Enter the nameserver IPv4 address, if any:"; + form.Value = ""; + if (form.ShowDialog(this) == DialogResult.OK) nsip4 = form.Value; + form.Description = "Enter the nameserver IPv6 address, if any:"; + form.Value = ""; + if (form.ShowDialog(this) == DialogResult.OK) nsip6 = form.Value; + } + if (!(Value is IDictionary)) Value = new Hashtable(); + if (Value["ns"] == null || !(Value["ns"] is IDictionary)) Value["ns"] = new Hashtable(); + IDictionary dns = (IDictionary)Value["ns"]; + IList ns = new ArrayList(); + dns[nsname] = ns; + if (nsip4 != null && nsip4.Length > 0) ns.Add(nsip4); + if (nsip6 != null && nsip6.Length > 0) ns.Add(nsip6); + UpdateValueTree(); + } + + private void btnDataEditString_Click(object sender, EventArgs e) { + if (lvwData.SelectedNode == null || lvwData.SelectedNode.Tag == null) return; + frmTextInput form = new frmTextInput(); + form.Text = "MARC - Resource data"; + form.Description = "Enter the new value:"; + form.Value = lvwData.SelectedNode.Tag.ToString(); + if (form.ShowDialog(this) != DialogResult.OK) return; + Object parent = lvwData.SelectedNode.Parent == null ? Value : lvwData.SelectedNode.Parent.Tag; + if (parent == null) return; + if (parent is IDictionary) { + foreach (DictionaryEntry entry in ((IDictionary)parent)) { + if (lvwData.SelectedNode.Tag == entry.Value) { + ((IDictionary)parent)[entry.Key] = form.Value; + break; + } + } + } else if (parent is IList) { + for (int i = 0; i < ((IList)parent).Count; i++) { + if (((IList)parent)[i] == lvwData.SelectedNode.Tag) ((IList)parent)[i] = form.Value; + } + } + UpdateValueTree(); + } + + private void btnDataAddSring_Click(object sender, EventArgs e) { + Object parent = lvwData.SelectedNode == null ? Value : lvwData.SelectedNode.Tag; + if (!(parent is IDictionary || parent is IList)) return; + frmTextInput form = new frmTextInput(); + form.Text = "MARC - Resource data"; + String dkey = null; + if (parent is IDictionary) { + form.Description = "Enter the dictionary key:"; + if (form.ShowDialog(this) != DialogResult.OK) return; + dkey = form.Value; + } + form.Value = String.Empty; + form.Description = "Enter the value:"; + if (form.ShowDialog(this) != DialogResult.OK) return; + if (parent is IDictionary) { + ((IDictionary)parent)[dkey]= form.Value; + } else if (parent is IList) { + ((IList)parent).Add(form.Value); + } + UpdateValueTree(); + } + + private void btnDataAddCollection_Click(object sender, EventArgs e) { + Object parent = lvwData.SelectedNode == null ? Value : lvwData.SelectedNode.Tag; + if (parent is IDictionary) { + frmTextInput form = new frmTextInput(); + form.Text = "MARC - Resource data"; + form.Description = "Enter the dictionary key:"; + if (form.ShowDialog(this) != DialogResult.OK) return; + ((IDictionary)parent)[form.Value] = new ArrayList(); + } else if (parent is IList) { + ((IList)parent).Add(new ArrayList()); + } + UpdateValueTree(); + } + + private void btnDataAddDictionary_Click(object sender, EventArgs e) { + Object parent = lvwData.SelectedNode == null ? Value : lvwData.SelectedNode.Tag; + if (parent is IDictionary) { + frmTextInput form = new frmTextInput(); + form.Text = "MARC - Resource data"; + form.Description = "Enter the dictionary key:"; + if (form.ShowDialog(this) != DialogResult.OK) return; + ((IDictionary)parent)[form.Value] = new Hashtable(); + } else if (parent is IList) { + ((IList)parent).Add(new Hashtable()); + } + UpdateValueTree(); + } + + private void btnDataDelete_Click(object sender, EventArgs e) { + if (lvwData.SelectedNode == null || lvwData.SelectedNode.Tag == null) return; + Object parent = lvwData.SelectedNode.Parent == null ? Value : lvwData.SelectedNode.Parent.Tag; + if (parent == null) return; + if (parent is IDictionary) { + foreach (DictionaryEntry entry in ((IDictionary)parent)) { + if (lvwData.SelectedNode.Tag == entry.Value) { + ((IDictionary)parent).Remove(entry.Key); + break; + } + } + } else if (parent is IList) { + ((IList)parent).Remove(lvwData.SelectedNode.Tag); + } + UpdateValueTree(); + } + + private void btnDataDeleteAll_Click(object sender, EventArgs e) { + Value = null; + UpdateValueTree(); + } + + private void UpdateResourceStatus() { + MARCUpdate resource; + grpUpdateConflict.Visible = false; + grpUpdateExport.Visible = true; + txtUpdateLabel.Text = Functions.GetNameForLabel(Label); + UpdateSerial = checked((UInt32)MARCUpdate.DateTimeToUnix(DateTime.Now)); + if (MainForm.Resources.TryGetValue(new MARCLabel(Label), out resource)) { + txtUpdateCurrentOwner.Text = Functions.bin2hex(resource.Key.Bytes); + txtUpdateCurrentTransfer.Text = resource.Transfer == null ? "None" : Functions.bin2hex(resource.Transfer.Value.Bytes); + txtUpdateCurrentSerial.Text = resource.Serial.ToString() + " (" + resource.UpdateTimestamp.ToShortDateString() + ")"; + txtUpdateCurrentExpiration.Text = resource.Expiration == null ? "None" : resource.Expiration.Value.ToString() + " (" + resource.ExpirationTimestamp.ToShortDateString() + ")"; + if (!resource.CanUpdate(MainForm.PublicKey)) { + txtUpdateCurrentStatus.Text = "Not available"; + grpUpdateConflict.Visible = true; + grpUpdateExport.Visible = false; + return; + } + txtUpdateCurrentStatus.Text = "Registered"; + if (UpdateSerial <= resource.Serial) UpdateSerial = resource.Serial + 1; + txtUpdateCurrentSize.Text = resource.UpdateMessage.Length.ToString(); + } else { + txtUpdateCurrentOwner.Text = "None"; + txtUpdateCurrentTransfer.Text = "None"; + txtUpdateCurrentSerial.Text = String.Empty; + txtUpdateCurrentStatus.Text = "Free"; + txtUpdateCurrentSize.Text = "N/A"; + } + txtUpdateOwner.Text = MainForm.PublicKey.ToString(); + dtpUpdateExpiration.Value = DateTime.Now.AddYears(1); + dtpUpdateExpiration.Checked = false; + chkUpdateTransferEnabled.Checked = false; + } + + private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) { + if (tabControl1.SelectedIndex == 0) { + if (Label != null && Label.Length > 0) { + switch (Label[0]) { + case 1: radTypeIPv4.Checked = true; break; + case 2: radTypeIPv6.Checked = true; break; + case 3: radTypeASNumber.Checked = true; break; + case 4: radTypeDomain.Checked = true; break; + default: radTypeOtherHex.Checked = true; break; + } + } + radType_CheckedChanged(sender, e); + txtLabelValue_TextChanged(sender, e); + } else if (Label == null || Label.Length == 0) { + MessageBox.Show("The selected label is not valid. Please correct the label and try again.", "MARC - Invalid label", MessageBoxButtons.OK, MessageBoxIcon.Error); + tabControl1.SelectedIndex = 0; + } else if (tabControl1.SelectedIndex == 1) { + UpdateValueTree(); + } else if (tabControl1.SelectedIndex == 2) { + UpdateResourceStatus(); + } + } + + private void btnUpdateDelete_Click(object sender, EventArgs e) { + MARCLabel l = new MARCLabel(Label); + MainForm.ResourceHasChanged(null, MainForm.Resources[l]); + MainForm.Resources.Remove(l); + UpdateResourceStatus(); + } + + private void btnUpdateNow_Click(object sender, EventArgs e) { + UInt32? Expiration = null; + Byte[] Transfer = null; + if (dtpUpdateExpiration.Checked) { + DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + Expiration = checked((UInt32)(dtpUpdateExpiration.Value.ToUniversalTime() - epoch).TotalSeconds); + } + if (chkUpdateTransferEnabled.Checked) { + Transfer = Functions.hex2bin(txtUpdateTransfer.Text); + } + MARCUpdate update = MARCUpdate.Create(MainForm.SecretKey, UpdateSerial, Label, Value, Expiration, Transfer); + txtUpdateCurrentSize.Text = update.UpdateMessage.Length.ToString() + " bytes"; + MainForm.ReplaceOrAddResource(update); + MainForm.DatabaseSaved = false; + UpdateResourceStatus(); + } + } +} \ No newline at end of file