diff --git a/core/core.go b/core/core.go index 5bf5ec9..8a3711f 100644 --- a/core/core.go +++ b/core/core.go @@ -118,7 +118,7 @@ type OrderRequest struct { Duration string Uses string Data []byte - Label string + Labels []string } type OrderInfoRequest struct { @@ -400,17 +400,16 @@ func Delegate(jsonIn []byte) ([]byte, error) { // Make sure we capture the number who have already delegated. for _, delegatedUser := range s.Users { - for _, delegatedLabel := range s.Labels { - if orderKey, found := orders.FindOrder(delegatedUser, delegatedLabel); found { - order := orders.Orders[orderKey] - order.AdminsDelegated = append(order.AdminsDelegated, s.Name) - order.Delegated++ - orders.Orders[orderKey] = order + if orderKey, found := orders.FindOrder(delegatedUser, s.Labels); found { + order := orders.Orders[orderKey] + order.AdminsDelegated = append(order.AdminsDelegated, s.Name) - // Notify the hipchat room that there was a new delegator - orders.NotifyDelegation(s.Name, delegatedLabel, delegatedUser, orderKey, s.Time) + order.Delegated++ + orders.Orders[orderKey] = order + + // Notify the hipchat room that there was a new delegator + orders.NotifyDelegation(s.Name, delegatedUser, orderKey, s.Time, s.Labels) - } } } @@ -614,11 +613,9 @@ func Decrypt(jsonIn []byte) ([]byte, error) { } // Cleanup any orders that have been fulfilled and notify the room. - for _, label := range allLabels { - if orderKey, found := orders.FindOrder(s.Name, label); found { - delete(orders.Orders, orderKey) - orders.NotifyOrderFulfilled(s.Name, orderKey) - } + if orderKey, found := orders.FindOrder(s.Name, allLabels); found { + delete(orders.Orders, orderKey) + orders.NotifyOrderFulfilled(s.Name, orderKey) } return jsonResponse(out) } @@ -767,21 +764,19 @@ func Order(jsonIn []byte) (out []byte, err error) { cache.Refresh() orderNum := order.GenerateNum() - adminsDelegated, numDelegated := cache.DelegateStatus(o.Name, o.Label, owners) + adminsDelegated, numDelegated := cache.DelegateStatus(o.Name, o.Labels, owners) duration, err := time.ParseDuration(o.Duration) if err != nil { jsonStatusError(err) } currentTime := time.Now() - expiryTime := currentTime.Add(duration) ord := order.CreateOrder(o.Name, - o.Label, orderNum, currentTime, - expiryTime, duration, adminsDelegated, owners, + o.Labels, numDelegated) orders.Orders[orderNum] = ord out, err = json.Marshal(ord) @@ -790,7 +785,7 @@ func Order(jsonIn []byte) (out []byte, err error) { altOwners := records.GetAltNamesFromName(orders.AlternateName, owners) // Let everyone on hipchat know there is a new order. - orders.NotifyNewOrder(o.Name, o.Duration, o.Label, o.Uses, orderNum, altOwners) + orders.NotifyNewOrder(o.Name, o.Duration, o.Uses, orderNum, o.Labels, altOwners) if err != nil { return jsonStatusError(err) } diff --git a/index.html b/index.html index 0d28049..9b8f189 100644 --- a/index.html +++ b/index.html @@ -330,8 +330,8 @@
"+htmlspecialchars(jj)+": "+htmlspecialchars(JSON.stringify(respData[jj]))+"
"; + } else { + msgText += ""+htmlspecialchars(jj)+": "+htmlspecialchars(respData[jj])+"
"; + } } $form.find('.feedback').empty().append(makeAlert({ type: 'success', message: msgText })); } catch (e) { @@ -730,6 +775,10 @@ } }); }); + $('body').on('submit', 'form#orderlink', function(evt){ + evt.preventDefault(); + createLink(); + }); // Init from query string if possible. var queryParams = document.location.search; @@ -767,9 +816,20 @@ break; } if (setValue) { - setValue.val(value); + setValue.val(decodeURIComponent(value)); } } + function createLink() { + var delegator = decodeURIComponent(document.getElementById("orderlink-delegator").value); + var delegatee = decodeURIComponent(document.getElementById("orderlink-delegatefor").value); + var duration = decodeURIComponent(document.getElementById("orderlink-duration").value); + var orderNum = decodeURIComponent(document.getElementById("orderlink-ordernum").value); + var labels = decodeURIComponent(document.getElementById("orderlink-labels").value); + var uses = decodeURIComponent(document.getElementById("orderlink-uses").value); + + var link = "https://" + document.location.host + "?delegator="+ delegator + "&delegatee="+ delegatee + "&label=" + labels + "&ordernum=" + orderNum + "&uses=" + uses + "&duration="+ duration; + $('.orderlink-feedback').empty().append(makeAlert({ type: 'success', message: ''+htmlspecialchars(link)+'
' }) ); + } function htmlspecialchars(s) { if (!isNaN(s)) { return s; diff --git a/keycache/keycache.go b/keycache/keycache.go index 1b65d5a..77d2218 100644 --- a/keycache/keycache.go +++ b/keycache/keycache.go @@ -309,7 +309,7 @@ func (cache *Cache) DecryptShares(in [][]byte, name, user string, labels []strin // DelegateStatus will return a list of admins who have delegated to a particular user, for a particular label. // This is useful information to have when determining the status of an order and conveying order progress. -func (cache *Cache) DelegateStatus(name string, label string, admins []string) (adminsDelegated []string, hasDelegated int) { +func (cache *Cache) DelegateStatus(name string, labels, admins []string) (adminsDelegated []string, hasDelegated int) { // Iterate over the admins of the ciphertext to look for users // who have already delegated the label to the delegatee. for _, admin := range admins { @@ -317,23 +317,22 @@ func (cache *Cache) DelegateStatus(name string, label string, admins []string) ( if di.Name != admin { continue } - labelFound := false nameFound := false for _, user := range use.Users { if user == name { nameFound = true } } - for _, l := range use.Labels { - if l == label { - labelFound = true + for _, ol := range use.Labels { + for _, il := range labels { + if ol == il { + if nameFound { + adminsDelegated = append(adminsDelegated, admin) + hasDelegated++ + } + } } } - if labelFound && nameFound { - adminsDelegated = append(adminsDelegated, admin) - hasDelegated++ - } - } } return diff --git a/order/order.go b/order/order.go index e8e87fd..0465ae9 100644 --- a/order/order.go +++ b/order/order.go @@ -22,12 +22,11 @@ type Order struct { Num string TimeRequested time.Time - ExpiryTime time.Time DurationRequested time.Duration Delegated int AdminsDelegated []string Admins []string - Label string + Labels []string } type OrderIndex struct { @@ -47,12 +46,11 @@ type Orderer struct { AlternateName string } -func CreateOrder(name string, labels string, orderNum string, time time.Time, expiryTime time.Time, duration time.Duration, adminsDelegated, contacts []string, numDelegated int) (ord Order) { +func CreateOrder(name, orderNum string, time time.Time, duration time.Duration, adminsDelegated, contacts, labels []string, numDelegated int) (ord Order) { ord.Name = name ord.Num = orderNum - ord.Label = labels + ord.Labels = labels ord.TimeRequested = time - ord.ExpiryTime = expiryTime ord.DurationRequested = duration ord.AdminsDelegated = adminsDelegated ord.Admins = contacts @@ -79,13 +77,23 @@ func NewOrderer(hipchatClient hipchat.HipchatClient) (o Orderer) { func notify(o *Orderer, msg, color string) { o.Hipchat.Notify(msg, color) } -func (o *Orderer) NotifyNewOrder(name, duration, label, uses, orderNum string, owners map[string]string) { - n := fmt.Sprintf(NewOrder, name, label, uses, duration) +func (o *Orderer) NotifyNewOrder(name, duration, uses, orderNum string, labels []string, owners map[string]string) { + labelList := "" + for i, label := range labels { + if i == 0 { + labelList += label + } else { + // Never include spaces in something go URI encodes. Go will + // add a + to the string, instead of a %20 + labelList += "," + label + } + } + n := fmt.Sprintf(NewOrder, name, labelList, uses, duration) notify(o, n, hipchat.RedBackground) for owner, hipchatName := range owners { queryParams := url.Values{ "delegator": {owner}, - "label": {label}, + "label": {labelList}, "duration": {duration}, "uses": {uses}, "ordernum": {orderNum}, @@ -95,8 +103,16 @@ func (o *Orderer) NotifyNewOrder(name, duration, label, uses, orderNum string, o } } -func (o *Orderer) NotifyDelegation(delegator, label, delegatee, orderNum, duration string) { - n := fmt.Sprintf(NewDelegation, delegator, label, delegatee, orderNum, duration) +func (o *Orderer) NotifyDelegation(delegator, delegatee, orderNum, duration string, labels []string) { + labelList := "" + for i, label := range labels { + if i == 0 { + labelList += label + } else { + labelList += ", " + label + } + } + n := fmt.Sprintf(NewDelegation, delegator, labelList, delegatee, orderNum, duration) notify(o, n, hipchat.YellowBackground) } func (o *Orderer) NotifyOrderFulfilled(name, orderNum string) { @@ -104,15 +120,24 @@ func (o *Orderer) NotifyOrderFulfilled(name, orderNum string) { notify(o, n, hipchat.PurpleBackground) } -func (o *Orderer) FindOrder(name, label string) (string, bool) { +func (o *Orderer) FindOrder(name string, labels []string) (string, bool) { for key, order := range o.Orders { if name != order.Name { continue } - if label != order.Label { - continue - } + for _, ol := range order.Labels { + foundLabel := false + for _, il := range labels { + if il == ol { + foundLabel = true + continue + } + } + if !foundLabel { + return "", false + } + } return key, true } return "", false diff --git a/redoctober.go b/redoctober.go index a0cbc70..bb14b68 100644 --- a/redoctober.go +++ b/redoctober.go @@ -204,9 +204,9 @@ const usage = `Usage: redoctober -static"+htmlspecialchars(jj)+": "+htmlspecialchars(respData[jj])+"
"; + if (typeof(respData[jj]) == "object") { + msgText += ""+htmlspecialchars(jj)+": "+htmlspecialchars(JSON.stringify(respData[jj]))+"
"; + } else { + msgText += ""+htmlspecialchars(jj)+": "+htmlspecialchars(respData[jj])+"
"; + } } $form.find('.feedback').empty().append(makeAlert({ type: 'success', message: msgText })); } catch (e) { @@ -1012,6 +1057,10 @@ var indexHtml = []byte(` } }); }); + $('body').on('submit', 'form#orderlink', function(evt){ + evt.preventDefault(); + createLink(); + }); // Init from query string if possible. var queryParams = document.location.search; @@ -1049,9 +1098,20 @@ var indexHtml = []byte(` break; } if (setValue) { - setValue.val(value); + setValue.val(decodeURIComponent(value)); } } + function createLink() { + var delegator = decodeURIComponent(document.getElementById("orderlink-delegator").value); + var delegatee = decodeURIComponent(document.getElementById("orderlink-delegatefor").value); + var duration = decodeURIComponent(document.getElementById("orderlink-duration").value); + var orderNum = decodeURIComponent(document.getElementById("orderlink-ordernum").value); + var labels = decodeURIComponent(document.getElementById("orderlink-labels").value); + var uses = decodeURIComponent(document.getElementById("orderlink-uses").value); + + var link = "https://" + document.location.host + "?delegator="+ delegator + "&delegatee="+ delegatee + "&label=" + labels + "&ordernum=" + orderNum + "&uses=" + uses + "&duration="+ duration; + $('.orderlink-feedback').empty().append(makeAlert({ type: 'success', message: ''+htmlspecialchars(link)+'
' }) ); + } function htmlspecialchars(s) { if (!isNaN(s)) { return s;