-
Notifications
You must be signed in to change notification settings - Fork 29
/
main.go
96 lines (89 loc) · 2.55 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// login is a simple tool that can be used to test the Ubuntu SSO
// discharge login protocol.
package main
import (
"context"
"flag"
"fmt"
"log"
"time"
errgo "gopkg.in/errgo.v1"
"gopkg.in/httprequest.v1"
"gopkg.in/macaroon-bakery.v2/bakery"
"gopkg.in/macaroon-bakery.v2/bakery/checkers"
"gopkg.in/macaroon-bakery.v2/bakery/identchecker"
"gopkg.in/macaroon-bakery.v2/httpbakery"
"gopkg.in/macaroon.v2"
"github.com/canonical/candid/candidclient"
"github.com/canonical/candid/candidclient/ussodischarge"
)
var (
email = flag.String("email", "", "email")
insecure = flag.Bool("insecure", false, "get public key over insecure connections")
password = flag.String("password", "", "password")
otp = flag.String("otp", "", "verification code")
url = flag.String("url", "https://api.jujucharms.com/identity", "identity url")
)
func main() {
ctx := context.Background()
log.SetFlags(log.Flags() | log.Llongfile)
flag.Parse()
tpl := httpbakery.NewThirdPartyLocator(nil, nil)
if *insecure {
tpl.AllowInsecure()
}
client := httpbakery.NewClient()
iclient, err := candidclient.New(candidclient.NewParams{
BaseURL: *url,
Client: client,
})
if err != nil {
log.Fatal(err)
}
key, err := bakery.GenerateKey()
if err != nil {
log.Fatal(err)
}
b := identchecker.NewBakery(identchecker.BakeryParams{
Location: "test",
Locator: tpl,
Key: key,
IdentityClient: iclient,
})
m, err := b.Oven.NewMacaroon(ctx, bakery.LatestVersion, []checkers.Caveat{{
Condition: "is-authenticated-user",
Location: *url,
}, checkers.TimeBeforeCaveat(time.Now().Add(time.Minute))}, identchecker.LoginOp)
if err != nil {
log.Fatalf("cannot make macaroon: %s", err)
}
client.AddInteractor(ussodischarge.NewInteractor(func(client *httpbakery.Client, url string) (macaroon.Slice, error) {
return login(ctx, client, url)
}))
ms, err := client.DischargeAll(ctx, m)
if err != nil {
log.Fatalf("cannot discharge macaroon: %s", err)
}
authInfo, err := b.Checker.Auth(ms).Allow(ctx, identchecker.LoginOp)
if err != nil {
log.Fatalf("invalid macaroon discharge: %s", err)
}
fmt.Printf("success as %v\n", authInfo.Identity.Id())
}
func login(ctx context.Context, doer httprequest.Doer, url string) (macaroon.Slice, error) {
m, err := ussodischarge.Macaroon(ctx, doer, url)
if err != nil {
return nil, errgo.Mask(err)
}
d := &ussodischarge.Discharger{
Email: *email,
Password: *password,
OTP: *otp,
Doer: doer,
}
ms, err := d.DischargeAll(ctx, m)
if err != nil {
return nil, errgo.Mask(err)
}
return ms, nil
}