diff --git a/main.go b/main.go index 6ff3d06..b36a3cc 100644 --- a/main.go +++ b/main.go @@ -1,39 +1,225 @@ 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 - client := apiclient.New(transport, strfmt.Default) + swaggerclient := apiclient.New(transport, strfmt.Default) - // to override the host for the default client - // apiclient.Default.SetTransport(transport) + charIDSkilqueue := skillsclient.NewGetCharactersCharacterIDSkillqueueParams().WithCharacterID(m.CharacterID) + skillqueueresp, _ := swaggerclient.Skills.GetCharactersCharacterIDSkillqueue(charIDSkilqueue, bearerToken) - // make the request to get all items - resp, err := client.Universe.GetUniverseRaces(nil) - if err != nil { - log.Fatal(err) + 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) } - - races := resp.Payload - - for _,race := range races { - // element is the element from someSlice for where we are - name := race.Name - description := race.Description - - fmt.Printf("%s:\n%s\n\n", *name, *description) - } }