veyron/services/wsprd/identity: URL-encode origin names in blessing.
Origins have the form: protocol://hosname:port, which is not a valid
blessing name because of the slashes, and potentially the colons. We
must URL-encode the origin to get a valid blessing name.
Change-Id: I27258cfd572f68eb22215f2cebe97705afc0042c
diff --git a/services/wsprd/identity/identity.go b/services/wsprd/identity/identity.go
index 96bc943..d3d1d4b 100644
--- a/services/wsprd/identity/identity.go
+++ b/services/wsprd/identity/identity.go
@@ -15,6 +15,7 @@
import (
"crypto/sha256"
"io"
+ "net/url"
"sync"
"time"
@@ -160,12 +161,11 @@
if !found {
return nil, OriginDoesNotExist
}
- // TODO(bjornick): Return a blessed identity, not the raw identity for the account.
- identity, found := i.state.Accounts[perm.Account]
- if !found {
- return nil, OriginDoesNotExist
+ blessedID, err := i.generateBlessedID(origin, perm.Account, perm.Caveats)
+ if err != nil {
+ return nil, err
}
- return identity, nil
+ return blessedID, nil
}
// AccountsMatching returns a list of accounts that match the given pattern.
@@ -221,12 +221,14 @@
return nil
}
-func (i *IDManager) generateBlessedID(name string, account string, caveats []security.ServiceCaveat) (security.PrivateID, error) {
+func (i *IDManager) generateBlessedID(origin string, account string, caveats []security.ServiceCaveat) (security.PrivateID, error) {
blessor := i.state.Accounts[account]
if blessor == nil {
return nil, verror.NotFoundf("unknown account %s", account)
}
- // The name here is irrelevant, since we'll only be storing the blessed name.
+ // Origins have the form protocol://hostname:port, which is not a valid
+ // blessing name. Hence we must url-encode.
+ name := url.QueryEscape(origin)
blessee, err := i.rt.NewIdentity(name)
if err != nil {
return nil, err
diff --git a/services/wsprd/identity/identity_test.go b/services/wsprd/identity/identity_test.go
index c35415d..8ca77c4 100644
--- a/services/wsprd/identity/identity_test.go
+++ b/services/wsprd/identity/identity_test.go
@@ -1,6 +1,7 @@
package identity
import (
+ "net/url"
"reflect"
"sort"
"strings"
@@ -42,17 +43,25 @@
if err != nil {
t.Fatalf("creating identity manager failed with: %v", err)
}
- manager.AddAccount("google/user1", createChain(r, "google/user1"))
- if err := manager.AddOrigin("sampleapp.com", "google/user1", nil); err != nil {
+ origin := "http://sampleapp.com:80"
+ account := "google/user1"
+ manager.AddAccount(account, createChain(r, account))
+ if err := manager.AddOrigin(origin, account, nil); err != nil {
t.Fatalf("failed to generate id: %v", err)
}
- if _, err := manager.Identity("sampleapp.com"); err != nil {
- t.Errorf("failed to get an identity for sampleapp.com: %v", err)
+ id, err := manager.Identity(origin)
+ if err != nil {
+ t.Errorf("failed to get an identity for %v: %v", origin, err)
+ }
+ want := []string{createChain(r, account).PublicID().Names()[0] + "/" + url.QueryEscape(origin)}
+ if got := id.PublicID().Names(); !reflect.DeepEqual(got, want) {
+ t.Errorf("unexpected identity name. got: %v, wanted: %v", got, want)
}
- if _, err := manager.Identity("unknown.com"); err != OriginDoesNotExist {
- t.Error("should not have found an identity for unknown.com")
+ unknownOrigin := "http://unknown.com:80"
+ if _, err := manager.Identity(unknownOrigin); err != OriginDoesNotExist {
+ t.Error("should not have found an identity for %v", unknownOrigin)
}
}
@@ -63,13 +72,16 @@
if err != nil {
t.Fatalf("creating identity manager failed with: %v", err)
}
- manager.AddAccount("google/user1", createChain(r, "google/user1"))
- manager.AddAccount("google/user2", createChain(r, "google/user2"))
- manager.AddAccount("facebook/user1", createChain(r, "facebook/user1"))
+ googleAccount1 := "google/user1"
+ googleAccount2 := "google/user2"
+ facebookAccount := "facebook/user1"
+ manager.AddAccount(googleAccount1, createChain(r, googleAccount1))
+ manager.AddAccount(googleAccount2, createChain(r, googleAccount2))
+ manager.AddAccount(facebookAccount, createChain(r, facebookAccount))
result := manager.AccountsMatching(security.PrincipalPattern(topLevelName + "/google/*"))
sort.StringSlice(result).Sort()
- expected := []string{"google/user1", "google/user2"}
+ expected := []string{googleAccount1, googleAccount2}
if !reflect.DeepEqual(result, expected) {
t.Errorf("unexpected result from AccountsMatching, expected :%v, got: %v", expected, result)
}
@@ -82,7 +94,7 @@
t.Fatalf("creating identity manager failed with: %v", err)
}
- err = manager.AddOrigin("sampleapp.com", "google/user1", nil)
+ err = manager.AddOrigin("http://sampleapp.com:80", "google/user1", nil)
if err == nil {
t.Errorf("should have failed to generated an id blessed by google/user1")
@@ -98,7 +110,9 @@
t.Fatalf("creating identity manager failed with: %v", err)
}
manager.AddAccount("google/user1", createChain(r, "google/user1"))
- if err = manager.AddOrigin("sampleapp.com", "google/user1", nil); err != nil {
+ origin1 := "https://sampleapp-1.com:443"
+ account := "google/user1"
+ if err = manager.AddOrigin(origin1, account, nil); err != nil {
t.Fatalf("failed to generate id: %v", err)
}
@@ -107,11 +121,17 @@
if err != nil {
t.Fatalf("failed to deserialize data: %v", err)
}
- if _, err := newManager.Identity("sampleapp.com"); err != nil {
- t.Errorf("can't find the sampleapp.com identity: %v", err)
+ id, err := newManager.Identity(origin1)
+ if err != nil {
+ t.Errorf("can't find the %v identity: %v", origin1, err)
+ }
+ want := []string{createChain(r, account).PublicID().Names()[0] + "/" + url.QueryEscape(origin1)}
+ if got := id.PublicID().Names(); !reflect.DeepEqual(got, want) {
+ t.Errorf("unexpected identity name. got: %v, wanted: %v", got, want)
}
- if err := newManager.AddOrigin("sampleapp2.com", "google/user1", nil); err != nil {
- t.Errorf("failed to create sampleapp2.com identity: %v", err)
+ origin2 := "https://sampleapp-2.com:443"
+ if err := newManager.AddOrigin(origin2, account, nil); err != nil {
+ t.Errorf("can't find the %v identity: %v", origin2, err)
}
}