func (fe *FrontEnd) replyAdminAccept(req *http.Request) *http.Response { args, err := http.ParseQuery(req.URL.RawQuery) if err != nil { return buildResp("Invalid accept link") } // Read SignatureKey s, ok := args["sk"] if !ok || s == nil || len(s) != 1 { return buildResp("Invalid accept link") } sigkeyText := s[0] _, err = sys.ParseSigPubKey(sigkeyText) if err != nil { return buildResp("Invalid accept link") } // Read DialKey d, ok := args["dk"] if !ok || d == nil || len(d) != 1 { return buildResp("Invalid accept link") } dialkeyText := d[0] dialkey, err := sys.ParseDialKey(dialkeyText) if err != nil { return buildResp("Invalid accept link") } // Read AcceptKey (optional) a, ok := args["ak"] var acceptkey *sys.DialKey if ok && a != nil && len(a) == 1 { acceptkey, err = sys.ParseDialKey(a[0]) if err != nil { return buildResp("Invalid accept link") } } // Read Name var name string n, ok := args["na"] if ok && n != nil && len(n) == 1 { name = n[0] } // Read Email var email string e, ok := args["em"] if ok && e != nil && len(e) == 1 { email = e[0] } // Read Addr var addr string ad, ok := args["ad"] if ok && ad != nil && len(ad) == 1 { addr = ad[0] } // Reconcile with local database var v sys.View if acceptkey != nil { v, err = fe.bank.GetByAcceptKey(acceptkey) if err != nil { v = nil } } if v == nil { v, err = fe.bank.GetByDialKey(dialkey) if err != nil { v = nil } } if v != nil { if v.GetName() != "" { name = v.GetName() } if v.GetEmail() != "" { email = v.GetEmail() } if v.GetAddr() != "" { addr = v.GetAddr() } } var slotText string if v != nil { slotText = strconv.Itoa(v.GetSlot()) } // prepare content data := acceptData{ Name: name, Email: email, Addr: addr, Slot: slotText, DialKey: dialkeyText, SigKey: sigkeyText, AdminURL: fe.adminURL, } var w bytes.Buffer err = fe.tmplAccept.Execute(&data, &w) if err != nil { return newRespServiceUnavailable() } // prepare page pdata := pageData{ Title: sys.Name + " — Accept invitation?", CSSLinks: []string{"accept.css"}, JSLinks: []string{"accept.js"}, GridLayout: "", Content: w.String(), } var w2 bytes.Buffer err = fe.tmplPage.Execute(&pdata, &w2) if err != nil { return newRespServiceUnavailable() } return buildResp(w2.String()) }
func (fe *FrontEnd) replyAPIAccept(args map[string][]string) *http.Response { // name and email args na, ok := args["na"] if !ok || na == nil || len(na) != 1 { return newRespBadRequest() } em, ok := args["em"] if !ok || em == nil || len(em) != 1 { return newRespBadRequest() } ad, ok := args["ad"] if !ok || ad == nil || len(ad) != 1 { return newRespBadRequest() } sl, ok := args["sl"] if !ok || sl == nil || len(sl) != 1 { return newRespBadRequest() } dk, ok := args["dk"] if !ok || dk == nil || len(dk) != 1 { return newRespBadRequest() } dialkey, err := sys.ParseDialKey(dk[0]) if err != nil { return newRespBadRequest() } sk, ok := args["sk"] if !ok || sk == nil || len(sk) != 1 { return newRespBadRequest() } sigkey, err := sys.ParseSigPubKey(sk[0]) if err != nil { return newRespBadRequest() } // Logic result := &apiAcceptResult{} s, err := strconv.Atoi(sl[0]) var v sys.View adding := false if err == nil { v, err = fe.bank.GetBySlot(s) if err != nil { v = nil } } if v == nil { v, err = fe.bank.GetByDialKey(dialkey) if err != nil { v = nil } } if v == nil { v = fe.bank.Reserve() s = v.GetSlot() adding = true } if na[0] != "" { fe.bank.Write(s, "Name", na[0]) } if em[0] != "" { fe.bank.Write(s, "Email", em[0]) } if ad[0] != "" { fe.bank.Write(s, "Addr", ad[0]) } _, err = fe.bank.Write(s, "SignatureKey", sigkey) if err != nil { result.ErrMsg = "This friend's invite has already been accepted." } _, err = fe.bank.Write(s, "DialKey", dialkey) if err != nil { result.ErrMsg = "This friend's invite has already been accepted." } if adding { result.InviteMsg = fe.makeInvite(v) } fe.bank.Sync(s) fe.bank.Save() jb, err := json.Marshal(&result) if err != nil { return newRespServiceUnavailable() } return buildResp(string(jb)) }
func ReadFriendDb(path string) (*buttress, os.Error) { // Read contents bytes, err := ioutil.ReadFile(path) if err != nil { log.Stderrf("Cannot read from friends file \"%s\"\n", path) return nil, &Error{ErrLoad, err} } // Unmarshal json book := jsonDb{} if err := json.Unmarshal(bytes, &book); err != nil { log.Stderrf("Error decoding friends file [%s] json. "+ "Offending token [%s].\n", path, err) return nil, &Error{ErrDecode, err} } db := &buttress{me: &sys.Me{}, recs: make(map[int]*friend), path: path} // Deep parse me-data db.me = &sys.Me{ Name: book.Me.Name, Addr: book.Me.Addr, ExtAddr: book.Me.ExtAddr, Email: book.Me.Email, } id, err := sys.ParseId(book.Me.Id) if err != nil { log.Stderrf("Error [%v] decoding my ID [%s]\n", err, book.Me.Id) return nil, &Error{ErrDecode, book.Me.Id} } db.me.Id = id pk, err := sys.ParseSigKey(book.Me.SigKey) if err != nil { log.Stderrf("Error [%v] decoding my signature key [%s]\n", err, book.Me.SigKey) return nil, &Error{ErrDecode, book.Me.SigKey} } db.me.SignatureKey = pk // Deep parse friends if book.Friends != nil { for i := 0; i < len(book.Friends); i++ { // slot slot, err := strconv.Atoi(book.Friends[i].Slot) if err != nil || slot < 0 { log.Stderrf("db, invalid slot number, skipping friends") continue } // id id1, err := sys.ParseId(book.Friends[i].Id) var id *sys.Id if err == nil { id = &id1 } // dial key dkey, _ := sys.ParseDialKey(book.Friends[i].DialKey) // accept key akey, _ := sys.ParseDialKey(book.Friends[i].AcceptKey) // sig key sigk, err := sys.ParseSigPubKey(book.Friends[i].SigKey) // hello key hellok, err := sys.ParseHelloKey(book.Friends[i].HelloKey) // make fr := &friend{ Friend: sys.Friend{ Slot: slot, Id: id, SignatureKey: sigk, HelloKey: hellok, DialKey: dkey, AcceptKey: akey, Name: book.Friends[i].Name, Email: book.Friends[i].Email, Addr: book.Friends[i].Addr, Rest: book.Friends[i].Rest, }, online: false, } _, present := db.recs[fr.Slot] if present { log.Stderrf("Duplicate friend, using latest\n") } db.recs[fr.Slot] = fr } // for } return db, nil }