diff --git a/main.go b/main.go index b36a3cc..0cfe3f8 100644 --- a/main.go +++ b/main.go @@ -3,7 +3,9 @@ package main import ( "encoding/json" + "golang.org/x/net/context" "golang.org/x/oauth2" + "io/ioutil" "net/http" @@ -16,10 +18,8 @@ import ( skillsclient "client/skills" httptransport "github.com/go-openapi/runtime/client" - - - "database/sql" - _ "github.com/mattn/go-sqlite3" + //"database/sql" + //_ "github.com/mattn/go-sqlite3" ) type Character struct { @@ -28,11 +28,6 @@ type Character struct { ExpiresOn string } -const htmlIndex = ` -Log in - -` - var ( googleOauthConfig = &oauth2.Config{ RedirectURL: "http://localhost:3000/callback", @@ -51,106 +46,87 @@ var ( oauthStateString = "random" ) +var ctx = context.Background() +var messages = make(chan *oauth2.Token) + func main() { + cToken := getDatabaseToken() - 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) + if cToken == nil { + cToken = getNewAuthorizationToken() } - 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) + client := googleOauthConfig.Client(oauth2.NoContext, cToken) - _, err = db.Exec("delete from foo") - if err != nil { - log.Fatal(err) - } + m := getCharacterInfo(client) + fmt.Printf("Character id is %d\n", m.CharacterID) - _, 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)) + getCharacterSkillQueue(client, m) } -func handleMain(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, htmlIndex) +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 handleGoogleLogin(w http.ResponseWriter, r *http.Request) { - url := googleOauthConfig.AuthCodeURL(oauthStateString) +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”. @@ -159,29 +135,27 @@ func handleGoogleLogin(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, url, http.StatusTemporaryRedirect) } -func handleGoogleCallback(w http.ResponseWriter, r *http.Request) { +func handleAuthenticationCallback(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) + 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 { - fmt.Printf("Code exchange failed with '%s'\n", err) + 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 } - //fmt.Println("Access token: " + token.AccessToken) - //fmt.Println("Refresh token: " + token.RefreshToken) - - client := &http.Client{} + client := googleOauthConfig.Client(oauth2.NoContext, token) 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() @@ -195,31 +169,43 @@ func handleGoogleCallback(w http.ResponseWriter, r *http.Request) { 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) + fmt.Fprintf(w, "Got token for character %s.\n", m.CharacterName) + fmt.Fprintf(w, "You can now close this navigator tab.\n") - 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) - } + 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 }