package main import ( "encoding/json" "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 } const htmlIndex = ` Log in ` 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" ) func main() { db, err := sql.Open("sqlite3", "./foo.db") if err != nil { log.Fatal(err) } defer db.Close() _, _ = db.Exec("CREATE TABLE IF NOT EXISTS properties (id integer NOT NULL PRIMARY KEY, name TEXT);") tx, err := db.Begin() if err != nil { log.Fatal(err) } stmt, err := tx.Prepare("insert into foo(id, name) values(?, ?)") if err != nil { log.Fatal(err) } defer stmt.Close() for i := 0; i < 100; i++ { _, err = stmt.Exec(i, fmt.Sprintf("こんにちわ世界%03d", i)) if err != nil { log.Fatal(err) } } tx.Commit() rows, err := db.Query("select id, name from foo") if err != nil { log.Fatal(err) } defer rows.Close() for rows.Next() { var id int var name string err = rows.Scan(&id, &name) if err != nil { log.Fatal(err) } fmt.Println(id, name) } err = rows.Err() if err != nil { log.Fatal(err) } stmt, err = db.Prepare("select name from foo where id = ?") if err != nil { log.Fatal(err) } defer stmt.Close() var name string err = stmt.QueryRow("3").Scan(&name) if err != nil { log.Fatal(err) } fmt.Println(name) _, err = db.Exec("delete from foo") if err != nil { log.Fatal(err) } _, err = db.Exec("insert into foo(id, name) values(1, 'foo'), (2, 'bar'), (3, 'baz')") if err != nil { log.Fatal(err) } rows, err = db.Query("select id, name from foo") if err != nil { log.Fatal(err) } defer rows.Close() for rows.Next() { var id int var name string err = rows.Scan(&id, &name) if err != nil { log.Fatal(err) } fmt.Println(id, name) } err = rows.Err() if err != nil { log.Fatal(err) } http.HandleFunc("/", handleMain) http.HandleFunc("/login", handleGoogleLogin) http.HandleFunc("/callback", handleGoogleCallback) fmt.Println(http.ListenAndServe(":3000", nil)) } func handleMain(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, htmlIndex) } func handleGoogleLogin(w http.ResponseWriter, r *http.Request) { url := googleOauthConfig.AuthCodeURL(oauthStateString) // 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 handleGoogleCallback(w http.ResponseWriter, r *http.Request) { state := r.FormValue("state") if state != oauthStateString { fmt.Printf("invalid oauth state, expected '%s', got '%s'\n", oauthStateString, state) http.Redirect(w, r, "/", http.StatusTemporaryRedirect) return } code := r.FormValue("code") token, err := googleOauthConfig.Exchange(oauth2.NoContext, code) if err != nil { fmt.Printf("Code exchange failed with '%s'\n", err) http.Redirect(w, r, "/", http.StatusTemporaryRedirect) return } //fmt.Println("Access token: " + token.AccessToken) //fmt.Println("Refresh token: " + token.RefreshToken) client := &http.Client{} req, err := http.NewRequest("GET", "https://login.eveonline.com/oauth/verify", nil) req.Header.Add("Authorization", "Bearer "+token.AccessToken) 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, "Name: %s\n", m.CharacterName) fmt.Fprintf(w, "Id: %d\n", m.CharacterID) fmt.Fprintf(w, "Token: %s\n\n", token.AccessToken) bearerToken := httptransport.BearerToken(token.AccessToken) // create the transport transport := httptransport.New("esi.tech.ccp.is", "/latest", []string{"https"}) // create the API client, with the transport swaggerclient := apiclient.New(transport, strfmt.Default) charIDSkilqueue := skillsclient.NewGetCharactersCharacterIDSkillqueueParams().WithCharacterID(m.CharacterID) skillqueueresp, _ := swaggerclient.Skills.GetCharactersCharacterIDSkillqueue(charIDSkilqueue, bearerToken) 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.Fprintf(w, "%s: %d\n %d - %s to %s\n\n", name, id, level, startDate, endDate) } }