// VerifyClaim checks that the printer has been claimed. // If the printer is claimed, VerifyClaim returns no error. // If the printer is unclaimed, VerifyClaim retruns ErrUnclaimed. // It is possible for VerifyClaim to return other errors, such as // in the case of network problems. // // A side effect of verifying that claim is that Google creates // a synthetic account that is only useful in a future call to // NewServer, to manage just this one printer. // The information about that account can be retrieved // from the Auth, Printer, and Server methods after VerifyClaim // succeeds. func (p *OpenPrinter) VerifyClaim() error { if p.verify != nil { return nil } var resp verifyResponse if err := jsonRPC(&p.auth, "GET", p.register.PollingURL+p.auth.APIClientID, nil, &resp); err != nil { return fmt.Errorf("VerifyClaim: %v", err) } var tr oauth.Transport tr.Config = &oauth.Config{ ClientId: p.auth.APIClientID, ClientSecret: p.auth.APIClientSecret, Scope: "https://www.googleapis.com/auth/cloudprint https://www.googleapis.com/auth/googletalk", AuthURL: "https://accounts.google.com/o/oauth2/auth", TokenURL: "https://accounts.google.com/o/oauth2/token", RedirectURL: "oob", } tok, err := tr.Exchange(resp.AuthorizationCode) if err != nil { return fmt.Errorf("VerifyClaim: oauth exchange: %v", err) } p.auth.Token = *tok p.auth.TokenUser = resp.UserEmail p.auth.XMPPJID = resp.XMPPJID p.verify = &resp return nil }
func httpGET(auth *Auth, url string) ([]byte, error) { verb := "GET" req, err := http.NewRequest("GET", url, nil) if err != nil { return nil, err } if i := strings.Index(url, "?"); i >= 0 { url = url[:i] } req.Header.Set("X-CloudPrint-Proxy", auth.ProxyID) var client *http.Client if auth.Token.AccessToken != "" { var tr oauth.Transport tr.Config = &oauth.Config{ ClientId: auth.APIClientID, ClientSecret: auth.APIClientSecret, Scope: "https://www.googleapis.com/auth/cloudprint https://www.googleapis.com/auth/googletalk", AuthURL: "https://accounts.google.com/o/oauth2/auth", TokenURL: "https://accounts.google.com/o/oauth2/token", RedirectURL: "oob", } tr.Token = &auth.Token client = tr.Client() } else { client = http.DefaultClient } resp, err := client.Do(req) if err != nil { return nil, fmt.Errorf("%s %s: %v", verb, url, err) } defer resp.Body.Close() var buf bytes.Buffer _, err = io.Copy(&buf, resp.Body) if err != nil { return nil, fmt.Errorf("%s %s: reading HTTP response: %v", verb, url, err) } // TODO: Check 200 return buf.Bytes(), nil }
func jsonRPC(auth *Auth, verb, url string, mr *multipartRequest, dst interface{}) error { var reader io.Reader if mr != nil { if auth.ProxyID != "" { mr.WriteField("proxy", auth.ProxyID) } mr.Writer.Close() reader = &mr.buf } req, err := http.NewRequest(verb, url, reader) if err != nil { return err } if i := strings.Index(url, "?"); i >= 0 { url = url[:i] } if mr != nil { req.Header.Set("Content-Type", mr.FormDataContentType()) } if auth.ProxyID != "" { req.Header.Set("X-CloudPrint-Proxy", auth.ProxyID) } var client *http.Client if auth.Token.AccessToken != "" { var tr oauth.Transport tr.Config = &oauth.Config{ ClientId: auth.APIClientID, ClientSecret: auth.APIClientSecret, Scope: "https://www.googleapis.com/auth/cloudprint https://www.googleapis.com/auth/googletalk", AuthURL: "https://accounts.google.com/o/oauth2/auth", TokenURL: "https://accounts.google.com/o/oauth2/token", RedirectURL: "oob", } tr.Token = &auth.Token client = tr.Client() } else { client = http.DefaultClient } resp, err := client.Do(req) if err != nil { return fmt.Errorf("%s %s: %v", verb, url, err) } defer resp.Body.Close() var buf bytes.Buffer _, err = io.Copy(&buf, resp.Body) if err != nil { return fmt.Errorf("%s %s: reading HTTP response: %v", verb, url, err) } if resp.StatusCode != http.StatusOK { return fmt.Errorf("%s %s: %s\n%s", verb, url, resp.Status, buf.Bytes()) } fmt.Printf("%s\n", buf.Bytes()) var js jsonStatus if err := json.Unmarshal(buf.Bytes(), &js); err != nil { return fmt.Errorf("%s %s: invalid JSON response: %v", verb, url, err) } if !js.Success { suffix := "" if js.Message != "" { msg := js.Message if len(msg) > 2 && 'A' <= msg[0] && msg[0] <= 'Z' && 'a' <= msg[1] && msg[1] <= 'z' { msg = string(msg[0]+'a'-'A') + msg[1:] } suffix = ": " + msg } else { suffix = "\n" + buf.String() } return fmt.Errorf("%s %s: server rejected request%s", verb, url, suffix) } if dst != nil { if err := json.Unmarshal(buf.Bytes(), dst); err != nil { return fmt.Errorf("%s %s: invalid JSON response: %v", verb, url, err) } } return nil }