blob: 15ad0fe58d7dd862eaa04010e4fe1074026de05d [file] [log] [blame]
Nicolas LaCassec7cdf422015-01-08 14:11:29 -08001package core
2
3import (
4 "flag"
5 "fmt"
6 "io"
7 "net"
8 "strconv"
9 "time"
10
11 "v.io/core/veyron2/rt"
12
13 "v.io/core/veyron/lib/flags"
14 "v.io/core/veyron/lib/modules"
15
16 "v.io/core/veyron/services/identity/auditor"
17 "v.io/core/veyron/services/identity/blesser"
18 "v.io/core/veyron/services/identity/caveats"
19 "v.io/core/veyron/services/identity/oauth"
20 "v.io/core/veyron/services/identity/revocation"
21 "v.io/core/veyron/services/identity/server"
22 "v.io/core/veyron/services/identity/util"
23)
24
25var (
26 ifs *flag.FlagSet = flag.NewFlagSet("test_identityd", flag.ContinueOnError)
27
28 googleDomain = ifs.String("google_domain", "", "An optional domain name. When set, only email addresses from this domain are allowed to authenticate via Google OAuth")
29 host = ifs.String("host", "localhost", "Hostname the HTTP server listens on. This can be the name of the host running the webserver, but if running behind a NAT or load balancer, this should be the host name that clients will connect to. For example, if set to 'x.com', Veyron identities will have the IssuerName set to 'x.com' and clients can expect to find the root name and public key of the signer at 'x.com/blessing-root'.")
30 httpaddr = ifs.String("httpaddr", "localhost:0", "Address on which the HTTP server listens on.")
31 tlsconfig = ifs.String("tlsconfig", "", "Comma-separated list of TLS certificate and private key files. This must be provided.")
32
33 ifl *flags.Flags = flags.CreateAndRegister(ifs, flags.Listen)
34)
35
36func init() {
37 modules.RegisterChild(TestIdentitydCommand, usage(ifs), startTestIdentityd)
38}
39
40func startTestIdentityd(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
41 if err := parseFlags(ifl, args); err != nil {
42 return fmt.Errorf("failed to parse args: %s", err)
43 }
44
45 // Duration to use for tls cert and blessing duration.
46 duration := 365 * 24 * time.Hour
47
48 // If no tlsconfig has been provided, generate new cert and key and use them.
49 if ifs.Lookup("tlsconfig").Value.String() == "" {
50 certFile, keyFile, err := util.WriteCertAndKey(*host, duration)
51 if err != nil {
52 return fmt.Errorf("Could not write cert and key: %v", err)
53 }
54 if err := ifs.Set("tlsconfig", certFile+","+keyFile); err != nil {
55 return fmt.Errorf("Could not set tlsconfig: %v", err)
56 }
57 }
58
59 // Pick a free port if httpaddr flag is not set.
60 // We can't use :0 here, because the identity server calles
61 // http.ListenAndServeTLS, which block, leaving us with no way to tell
62 // what port the server is running on. Hence, we must pass in an
63 // actual port so we know where the server is running.
64 if ifs.Lookup("httpaddr").Value.String() == ifs.Lookup("httpaddr").DefValue {
65 if err := ifs.Set("httpaddr", "localhost:"+freePort()); err != nil {
66 return fmt.Errorf("Could not set httpaddr: %v", err)
67 }
68 }
69
70 auditor, reader := auditor.NewMockBlessingAuditor()
71 revocationManager := revocation.NewMockRevocationManager()
Ankur123a5c72015-01-12 16:03:43 -080072 oauthProvider := oauth.NewMockOAuth()
Nicolas LaCassec7cdf422015-01-08 14:11:29 -080073
Ankur123a5c72015-01-12 16:03:43 -080074 params := blesser.OAuthBlesserParams{
75 OAuthProvider: oauthProvider,
Nicolas LaCassec7cdf422015-01-08 14:11:29 -080076 BlessingDuration: duration,
77 DomainRestriction: *googleDomain,
78 RevocationManager: revocationManager,
79 }
80
81 s := server.NewIdentityServer(
Ankur123a5c72015-01-12 16:03:43 -080082 oauthProvider,
Nicolas LaCassec7cdf422015-01-08 14:11:29 -080083 auditor,
84 reader,
85 revocationManager,
Ankur123a5c72015-01-12 16:03:43 -080086 params,
Nicolas LaCassec7cdf422015-01-08 14:11:29 -080087 caveats.NewMockCaveatSelector())
88
89 l := initListenSpec(ifl)
90 r, err := rt.New()
91 if err != nil {
92 return fmt.Errorf("rt.New() failed: %v", err)
93 }
94 defer r.Cleanup()
Matt Rosencrantzf1c3b442015-01-12 17:53:08 -080095 ctx := r.NewContext()
Nicolas LaCassec7cdf422015-01-08 14:11:29 -080096
Matt Rosencrantzf1c3b442015-01-12 17:53:08 -080097 _, veyronEPs, externalHttpaddress := s.Listen(ctx, &l, *host, *httpaddr, *tlsconfig)
Nicolas LaCassec7cdf422015-01-08 14:11:29 -080098
99 fmt.Fprintf(stdout, "TEST_IDENTITYD_ADDR=%s\n", veyronEPs[0])
100 fmt.Fprintf(stdout, "TEST_IDENTITYD_HTTP_ADDR=%s\n", externalHttpaddress)
101
102 modules.WaitForEOF(stdin)
103 return nil
104}
105
106func freePort() string {
107 l, _ := net.Listen("tcp", ":0")
108 defer l.Close()
109 return strconv.Itoa(l.Addr().(*net.TCPAddr).Port)
110}