package main import ( "encoding/json" "golang.org/x/net/context" "golang.org/x/oauth2" "io/ioutil" "net/http" "fmt" "log" "github.com/go-openapi/strfmt" apiclient "client" skillsclient "client/skills" httptransport "github.com/go-openapi/runtime/client" //"database/sql" //_ "github.com/mattn/go-sqlite3" ) type Character struct { CharacterID int32 CharacterName string ExpiresOn string } var ( googleOauthConfig = &oauth2.Config{ RedirectURL: "http://localhost:3000/callback", ClientID: "CLIENTKEY", ClientSecret: "SECRETKEY", Scopes: []string{ "esi-skills.read_skillqueue.v1", "esi-skills.read_skills.v1", }, Endpoint: oauth2.Endpoint{ AuthURL: "https://login.eveonline.com/oauth/authorize/", TokenURL: "https://login.eveonline.com/oauth/token/", }, } // Some random string, random for each request oauthStateString = "random" ) var ctx = context.Background() var messages = make(chan *oauth2.Token) func main() { cToken := getDatabaseToken() if cToken == nil { cToken = getNewAuthorizationToken() } client := googleOauthConfig.Client(oauth2.NoContext, cToken) m := getCharacterInfo(client) fmt.Printf("Character id is %d\n", m.CharacterID) getCharacterSkillQueue(client, m) } func getCharacterInfo(client *http.Client) *Character { req, _ := http.NewRequest("GET", "https://login.eveonline.com/oauth/verify", nil) response, errDo := client.Do(req) if errDo != nil { fmt.Printf("Request error '%s'\n", errDo) return nil } defer response.Body.Close() contents, _ := ioutil.ReadAll(response.Body) var m Character errJson := json.Unmarshal(contents, &m) if errJson != nil { fmt.Printf("JSON read error with '%s'\n", errJson) return nil } fmt.Printf("Name: %s\n", m.CharacterName) fmt.Printf("Id: %d\n", m.CharacterID) return &m } func getCharacterSkillQueue(client *http.Client, m *Character) { // create the transport transport := httptransport.NewWithClient("esi.tech.ccp.is", "/latest", []string{"https"}, client) // create the API client, with the transport swaggerclient := apiclient.New(transport, strfmt.Default) charIDSkilqueue := skillsclient.NewGetCharactersCharacterIDSkillqueueParams().WithCharacterID(m.CharacterID) skillqueueresp, _ := swaggerclient.Skills.GetCharactersCharacterIDSkillqueue(charIDSkilqueue, nil) skillqueue := skillqueueresp.Payload for _, skill := range skillqueue { // element is the element from someSlice for where we are name := "UNK" level := skill.FinishedLevel id := skill.SkillID startDate := skill.StartDate endDate := skill.FinishDate fmt.Printf(" %s: %d\n %d - %s to %s\n\n", name, id, level, startDate, endDate) } } func getNewAuthorizationToken() *oauth2.Token { http.HandleFunc("/", handleLogin) http.HandleFunc("/callback", handleAuthenticationCallback) go func() { log.Println("No available token. Please visit http://localhost:3000 to renew.") http.ListenAndServe(":3000", nil) }() return <-messages } func handleLogin(w http.ResponseWriter, r *http.Request) { url := googleOauthConfig.AuthCodeURL(oauthStateString, oauth2.AccessTypeOffline) // https://eveonline-third-party-documentation.readthedocs.io/en/latest/sso/authentication.html // response_type: Must be set to “code”. url = url + "&response_type=code" http.Redirect(w, r, url, http.StatusTemporaryRedirect) } func handleAuthenticationCallback(w http.ResponseWriter, r *http.Request) { state := r.FormValue("state") if state != oauthStateString { log.Printf("invalid oauth state, expected '%s', got '%s'\n", oauthStateString, state) http.Redirect(w, r, "/", http.StatusTemporaryRedirect) // No token to pass, we will get one on the second pass return } code := r.FormValue("code") token, err := googleOauthConfig.Exchange(oauth2.NoContext, code) if err != nil { log.Printf("Code exchange failed with '%s'\n", err) http.Redirect(w, r, "/", http.StatusTemporaryRedirect) // No token to pass, we will get one on the second pass return } client := googleOauthConfig.Client(oauth2.NoContext, token) req, err := http.NewRequest("GET", "https://login.eveonline.com/oauth/verify", nil) response, _ := client.Do(req) defer response.Body.Close() contents, _ := ioutil.ReadAll(response.Body) var m Character errJson := json.Unmarshal(contents, &m) if errJson != nil { fmt.Printf("JSON read error with '%s'\n", errJson) http.Redirect(w, r, "/", http.StatusTemporaryRedirect) return } fmt.Fprintf(w, "Got token for character %s.\n", m.CharacterName) fmt.Fprintf(w, "You can now close this navigator tab.\n") messages <- token } func getDatabaseToken() *oauth2.Token { /* db, err := sql.Open("sqlite3", "./foo.db") defer db.Close() _, err = db.Exec("CREATE TABLE IF NOT EXISTS properties (id text NOT NULL PRIMARY KEY, value TEXT);") if err != nil { log.Fatal(err) } stmt, err := db.Prepare("SELECT value FROM properties WHERE id = ?") if err != nil { log.Fatal(err) } defer stmt.Close() var refreshToken string err = stmt.QueryRow("refreshToken").Scan(&refreshToken) if err != nil { refreshToken = "" } fmt.Println("Found token :" + refreshToken) return refreshToken */ log.Print("Using hardcoded refresh token") token := new(oauth2.Token) token.RefreshToken = "RZVPAbQpDq4qjwGwWNEHRssnfIEiD789B9nWWyZAZXcuQ2FhulkokZt21uNuRe7D0" token.TokenType = "Bearer" return token }