Some manipulations of the token to allow the reuse of a refresh token if available.
This commit is contained in:
parent
b838c8e2cb
commit
59a549c298
1 changed files with 119 additions and 133 deletions
252
main.go
252
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 = `<html><body>
|
||||
<a href="/login">Log in</a>
|
||||
</body></html>
|
||||
`
|
||||
|
||||
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
|
||||
}
|
||||
|
|
Reference in a new issue