11package main
22
33import (
4+ "bytes"
5+ "encoding/json"
6+ "fmt"
7+ "io"
48 "log"
9+ "net/http"
10+ "net/url"
11+ "os"
12+ "strings"
513
614 "github.com/gofiber/fiber/v2"
715 "github.com/gofiber/template/html/v2"
816)
917
18+ type TokenResponse struct {
19+ AccessToken string `json:"access_token"`
20+ TokenType string `json:"token_type"`
21+ ExpiresIn int `json:"expires_in"`
22+ }
23+
24+ type RegistrationResponse struct {
25+ ClientID string `json:"client_id"`
26+ Name string `json:"name"`
27+ Description string `json:"description"`
28+ Domain string `json:"domain"`
29+ CA interface {} `json:"ca"`
30+ CreatedAt string `json:"created_at"`
31+ UpdatedAt string `json:"updated_at"`
32+ EnterpriseTier string `json:"enterprise_tier"`
33+ PublicKey string `json:"public_key"`
34+ }
35+
36+ func generateToken () (* TokenResponse , error ) {
37+ data := url.Values {}
38+ data .Set ("grant_type" , "client_credentials" )
39+ data .Set ("client_id" , strings .TrimSpace (string (clientID )))
40+ data .Set ("client_secret" , strings .TrimSpace (string (clientSecret )))
41+ data .Set ("scope" , "openid vehicle_device_data vehicle_cmds vehicle_charging_cmds" )
42+ data .Set ("audience" , "https://fleet-api.prd.na.vn.cloud.tesla.com" )
43+
44+ resp , err := http .PostForm ("https://auth.tesla.com/oauth2/v3/token" , data )
45+ if err != nil {
46+ return nil , err
47+ }
48+ defer resp .Body .Close ()
49+
50+ var tokenResp TokenResponse
51+ if err := json .NewDecoder (resp .Body ).Decode (& tokenResp ); err != nil {
52+ return nil , err
53+ }
54+
55+ return & tokenResp , nil
56+ }
57+
58+ func registerPartnerAccount (token string ) (* RegistrationResponse , error ) {
59+ domain := strings .TrimSpace (string (domainName ))
60+ payload := map [string ]string {
61+ "domain" : domain ,
62+ }
63+
64+ jsonPayload , err := json .Marshal (payload )
65+ if err != nil {
66+ return nil , fmt .Errorf ("error marshaling payload: %v" , err )
67+ }
68+
69+ req , err := http .NewRequest ("POST" ,
70+ "https://fleet-api.prd.na.vn.cloud.tesla.com/api/1/partner_accounts" ,
71+ bytes .NewBuffer (jsonPayload ))
72+ if err != nil {
73+ return nil , fmt .Errorf ("error creating request: %v" , err )
74+ }
75+
76+ req .Header .Set ("Content-Type" , "application/json" )
77+ req .Header .Set ("Authorization" , "Bearer " + token )
78+
79+ client := & http.Client {}
80+ resp , err := client .Do (req )
81+ if err != nil {
82+ return nil , fmt .Errorf ("error making request: %v" , err )
83+ }
84+ defer resp .Body .Close ()
85+
86+ body , err := io .ReadAll (resp .Body )
87+ if err != nil {
88+ return nil , fmt .Errorf ("error reading response: %v" , err )
89+ }
90+
91+ if resp .StatusCode != http .StatusOK {
92+ return nil , fmt .Errorf ("registration failed with status %d: %s" , resp .StatusCode , string (body ))
93+ }
94+
95+ var regResp RegistrationResponse
96+ if err := json .Unmarshal (body , & regResp ); err != nil {
97+ return nil , fmt .Errorf ("error parsing response: %v" , err )
98+ }
99+
100+ return & regResp , nil
101+ }
102+
103+ var (
104+ clientID []byte
105+ clientSecret []byte
106+ domainName []byte
107+ )
108+
10109func main () {
110+ var err error
111+ // Read credentials
112+ clientID , err = os .ReadFile ("static/CLIENT_ID" )
113+ if err != nil {
114+ log .Fatal ("Error reading CLIENT_ID:" , err )
115+ }
116+ clientSecret , err = os .ReadFile ("static/CLIENT_SECRET" )
117+ if err != nil {
118+ log .Fatal ("Error reading CLIENT_SECRET:" , err )
119+ }
120+ domainName , err = os .ReadFile ("static/DOMAIN" )
121+ if err != nil {
122+ log .Fatal ("Error reading DOMAIN:" , err )
123+ }
124+
11125 // Create a new engine
12126 engine := html .New ("./views" , ".html" )
13127
@@ -24,6 +138,30 @@ func main() {
24138 return c .SendFile ("./static/public-key.pem" )
25139 })
26140
141+ // Generate token and register partner account endpoint
142+ app .Post ("/generate-token" , func (c * fiber.Ctx ) error {
143+ token , err := generateToken ()
144+ if err != nil {
145+ return c .Status (500 ).JSON (fiber.Map {
146+ "error" : "Token generation failed: " + err .Error (),
147+ })
148+ }
149+
150+ // Register partner account using the token
151+ regResp , err := registerPartnerAccount (token .AccessToken )
152+ if err != nil {
153+ return c .Status (500 ).JSON (fiber.Map {
154+ "error" : "Registration failed: " + err .Error (),
155+ "token" : token ,
156+ })
157+ }
158+
159+ return c .JSON (fiber.Map {
160+ "token" : token ,
161+ "registration" : regResp ,
162+ })
163+ })
164+
27165 // Serve the main page
28166 app .Get ("/" , func (c * fiber.Ctx ) error {
29167 return c .Render ("index" , fiber.Map {
0 commit comments