All Projects → antihax → goesi

antihax / goesi

Licence: MIT License
Go client for EVE Online ESI and SSO using versioned endpoints

Programming Languages

go
31211 projects - #10 most used programming language
shell
77523 projects

Projects that are alternatives of or similar to goesi

eve online
EveOnline ESI API
Stars: ✭ 23 (-61.02%)
Mutual labels:  eve-online, esi
evedata
EVE Data Website
Stars: ✭ 25 (-57.63%)
Mutual labels:  eve-online, esi
esiJS
A simple Node module for EVE Onlines' ESI.
Stars: ✭ 17 (-71.19%)
Mutual labels:  eve-online, esi
LazyBlacksmith
EVE Online Industry app written in python (flask) for backend, html / css / js for frontend
Stars: ✭ 44 (-25.42%)
Mutual labels:  eve-online, esi
jeveassets
jEveAssets is an out-of-game asset manager for Eve-Online, written in Java
Stars: ✭ 98 (+66.1%)
Mutual labels:  eve-online, esi
New Eden Social
🌌 New Eden Social 🚀
Stars: ✭ 136 (+130.51%)
Mutual labels:  eve-online
Priceall
Easy appraisal checking.
Stars: ✭ 16 (-72.88%)
Mutual labels:  eve-online
Allianceauth
An auth system for EVE Online to help in-game organizations manage online service access.
Stars: ✭ 133 (+125.42%)
Mutual labels:  eve-online
eve-abyssal-market
An abyssal module marketplace for EVE Online.
Stars: ✭ 21 (-64.41%)
Mutual labels:  eve-online
Osmium
Online collaborative fitting tool.
Stars: ✭ 74 (+25.42%)
Mutual labels:  eve-online
EEG-Motor-Imagery-Classification-CNNs-TensorFlow
EEG Motor Imagery Tasks Classification (by Channels) via Convolutional Neural Networks (CNNs) based on TensorFlow
Stars: ✭ 125 (+111.86%)
Mutual labels:  esi
Z S Overview Pack
Overview Pack for EVE Online
Stars: ✭ 247 (+318.64%)
Mutual labels:  eve-online
Sanderling
APIs and libraries to read information directly from the EVE Online game client.
Stars: ✭ 169 (+186.44%)
Mutual labels:  eve-online
bots
Programming bots to play video games
Stars: ✭ 106 (+79.66%)
Mutual labels:  eve-online
Gesi
Google Sheets ESI Add-on
Stars: ✭ 135 (+128.81%)
Mutual labels:  eve-online
Pyfa
Python fitting assistant, cross-platform fitting tool for EVE Online
Stars: ✭ 1,204 (+1940.68%)
Mutual labels:  eve-online
esi-test-server-docker
A dockerized version of Akamai's Edge Side Includes Test Server (ETS).
Stars: ✭ 30 (-49.15%)
Mutual labels:  esi
Zkillboard
Easy does it
Stars: ✭ 212 (+259.32%)
Mutual labels:  eve-online
elinor-reloaded
Trading tool for Eve Online
Stars: ✭ 29 (-50.85%)
Mutual labels:  eve-online
PyEveLiveDPS
PyEveLiveDPS (PELD) is a live DPS calculator and grapher for EVE Online
Stars: ✭ 127 (+115.25%)
Mutual labels:  eve-online

GoESI "Go Easy" API client for esi

ko-fi

An OpenAPI for EVE Online ESI API

A module to allow access to CCP's EVE Online ESI API. This module offers:

  • Versioned Endpoints
  • OAuth2 authentication to login.eveonline.com
  • Handle many tokens, with different scopes.
  • 100% ESI API coverage.
  • context.Context passthrough (for httptrace, logging, etc).

Installation

    go get github.com/antihax/goesi

New Client

client := goesi.NewAPIClient(&http.Client, "MyApp ([email protected] dude on slack)")

One client should be created that will serve as an agent for all requests. This allows http2 multiplexing and keep-alive be used to optimize connections. It is also good manners to provide a user-agent describing the point of use of the API, allowing CCP to contact you in case of emergencies.

Example:

client := goesi.NewAPIClient(&http.Client, "my esi client http://mysite.com contact <SomeDude> ingame")
result, response, err := client.V#.Endpoint.Operation(requestContext, requiredParam, &esi.OperationOpts{
																	Optional1: optional.NewString("someValue"),
																	Optional2: optional.NewFloat64(1234.56),
																})

Etiquette

Obeying the Cache Times

Caching is not implimented by the client and thus it is required to utilize a caching http client. It is highly recommended to utilize a client capable of caching the entire cluster of API clients.

An example using gregjones/httpcache and memcache:

import (
	"github.com/bradfitz/gomemcache/memcache"
	"github.com/gregjones/httpcache"
	httpmemcache "github.com/gregjones/httpcache/memcache"
)

func main() {
	// Connect to the memcache server
	cache := memcache.New(MemcachedAddresses...)

	// Create a memcached http client for the CCP APIs.
	transport := httpcache.NewTransport(httpmemcache.NewWithClient(cache))
	transport.Transport = &http.Transport{Proxy: http.ProxyFromEnvironment}
	client = &http.Client{Transport: transport}

	// Get our API Client.
	eve := goesi.NewAPIClient(client, "My user agent, contact somewhere@nowhere")
}

ETags

You should support using ETags if you are requesting data that is frequently not changed. IF you are using httpcache, it supports etags already. If you are not using a cache middleware, you will want to create your own middleware like this.

package myetagpackage
type contextKey string

func (c contextKey) String() string {
	return "mylib " + string(c)
}

// ContextETag is the context to pass etags to the transport
var (
	ContextETag = contextKey("etag")
)

// Custom transport to chain into the HTTPClient to gather statistics.
type ETagTransport struct {
	Next *http.Transport
}

// RoundTrip wraps http.DefaultTransport.RoundTrip to provide stats and handle error rates.
func (t *ETagTransport) RoundTrip(req *http.Request) (*http.Response, error) {
	if etag, ok := req.Context().Value(ContextETag).(string); ok {
		req.Header.Set("if-none-match", etag)
	}

	// Run the request.
	return t.Next.RoundTrip(req)
}

This is then looped in the transport, and passed through a context like so:

func main() {
	// Loop in our middleware
	client := &http.Client{Transport: &ETagTransport{Next: &http.Transport{}}}

	// Make a new client with the middleware
	esiClient := goesi.NewAPIClient(client, "MyApp ([email protected] dude on slack)")

	// Make a request with the context
	ctx := context.WithValue(context.Background(), myetagpackage.ContextETag, "etag goes here")
	regions, _, err := esiClient.UniverseApi.GetUniverseRegions(ctx, nil)
	if err != nil {
		return err
	}
}

Authenticating

Register your application at https://developers.eveonline.com/ to get your secretKey, clientID, and scopes.

Obtaining tokens for client requires two HTTP handlers. One to generate and redirect to the SSO URL, and one to receive the response.

It is mandatory to create a random state and compare this state on return to prevent token injection attacks on the application.

pseudocode example:

func main() {
var err error
ctx := appContext.AppContext{}
ctx.ESI = goesi.NewAPIClient(httpClient, "My App, contact someone@nowhere")
ctx.SSOAuthenticator = goesi.NewSSOAuthenticator(httpClient, clientID, secretKey, scopes)
}

func eveSSO(c *appContext.AppContext, w http.ResponseWriter, r *http.Request,
	s *sessions.Session) (int, error) {

	// Generate a random state string
	b := make([]byte, 16)
	rand.Read(b)
	state := base64.URLEncoding.EncodeToString(b)

	// Save the state on the session
	s.Values["state"] = state
	err := s.Save(r, w)
	if err != nil {
		return http.StatusInternalServerError, err
	}

	// Generate the SSO URL with the state string
	url := c.SSOAuthenticator.AuthorizeURL(state, true)

	// Send the user to the URL
	http.Redirect(w, r, url, 302)
	return http.StatusMovedPermanently, nil
}

func eveSSOAnswer(c *appContext.AppContext, w http.ResponseWriter, r *http.Request,
	s *sessions.Session) (int, error) {

	// get our code and state
	code := r.FormValue("code")
	state := r.FormValue("state")

	// Verify the state matches our randomly generated string from earlier.
	if s.Values["state"] != state {
		return http.StatusInternalServerError, errors.New("Invalid State.")
	}

	// Exchange the code for an Access and Refresh token.
	token, err := c.SSOAuthenticator.TokenExchange(code)
	if err != nil {
		return http.StatusInternalServerError, err
	}

	// Obtain a token source (automaticlly pulls refresh as needed)
	tokSrc, err := c.SSOAuthenticator.TokenSource(tok)
	if err != nil {
		return http.StatusInternalServerError, err
	}

	// Assign an auth context to the calls
	auth := context.WithValue(context.TODO(), goesi.ContextOAuth2, tokSrc.Token)

	// Verify the client (returns clientID)
	v, err := c.SSOAuthenticator.Verify(auth)
	if err != nil {
		return http.StatusInternalServerError, err
	}

	if err != nil {
		return http.StatusInternalServerError, err
	}

	// Save the verification structure on the session for quick access.
	s.Values["character"] = v
	err = s.Save(r, w)
	if err != nil {
		return http.StatusInternalServerError, err
	}

	// Redirect to the account page.
	http.Redirect(w, r, "/account", 302)
	return http.StatusMovedPermanently, nil
}

Passing Tokens

OAuth2 tokens are passed to endpoints via contexts. Example:

	ctx := context.WithValue(context.Background(), goesi.ContextOAuth2, ESIPublicToken)
	struc, response, err := client.V1.UniverseApi.GetUniverseStructuresStructureId(ctx, structureID, nil)

This is done here rather than at the client so you can use one client for many tokens, saving connections.

Testing

If you would rather not rely on public ESI for testing, a mock ESI server is available for local and CI use. Information here: https://github.com/antihax/mock-esi

What about the other stuff?

If you need bleeding edge access, add the endpoint to the generator and rebuild this module. Generator is here: https://github.com/antihax/swagger-esi-goclient

Documentation for API Endpoints

ESI Endpoints

Author

antihax on #devfleet slack

Credits

https://github.com/go-resty/resty (MIT license) Copyright © 2015-2016 Jeevanandam M ([email protected])

  • Uses modified setBody and detectContentType

https://github.com/gregjones/httpcache (MIT license) Copyright © 2012 Greg Jones ([email protected])

  • Uses parseCacheControl and CacheExpires as a helper function
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].