neowolves/auth-server/server.go

99 lines
2.7 KiB
Go

package main
import (
"context"
"github.com/go-oauth2/oauth2/v4"
"github.com/go-oauth2/oauth2/v4/errors"
"github.com/go-oauth2/oauth2/v4/manage"
"github.com/go-oauth2/oauth2/v4/models"
"github.com/go-oauth2/oauth2/v4/server"
"github.com/go-oauth2/oauth2/v4/store"
"log"
"log/slog"
"net/http"
)
type BlockchainStorage interface {
GetByID(ctx context.Context, id string) (oauth2.ClientInfo, error) // read
Set(id string, cli oauth2.ClientInfo) (err error) // create and update
Delete(id string) (err error) // delete
}
func main() {
manager := manage.NewDefaultManager()
manager.SetAuthorizeCodeTokenCfg(manage.DefaultAuthorizeCodeTokenCfg)
// token memory store
// todo: Implement blockchain store
manager.MustTokenStorage(store.NewMemoryTokenStore())
// client memory store
// todo: Implement blockchain store
clientStore := store.NewClientStore()
manager.MapClientStorage(clientStore)
srv := server.NewDefaultServer(manager)
srv.SetAllowGetAccessRequest(true)
srv.SetClientInfoHandler(server.ClientFormHandler)
manager.SetRefreshTokenCfg(manage.DefaultRefreshTokenCfg)
srv.SetInternalErrorHandler(func(err error) (re *errors.Response) {
log.Println("Internal Error:", err.Error())
return
})
srv.SetResponseErrorHandler(func(re *errors.Response) {
log.Println("Response Error:", re.Error.Error())
})
http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
srv.HandleTokenRequest(w, r)
})
http.HandleFunc("/register", func(writer http.ResponseWriter, request *http.Request) {
id := request.Header.Get("client_id")
secret := request.Header.Get("client_secret")
// check whether client exists
_, err := clientStore.GetByID(context.Background(), id)
if err == nil {
slog.Warn("Client with id " + id + "already exists.")
writer.WriteHeader(http.StatusBadRequest)
return
}
// add client's credentials to blockchain
err = clientStore.Set(id, &models.Client{
ID: id,
Secret: secret,
})
if err != nil {
slog.Error("Failed to register user with id "+id+".", err)
writer.WriteHeader(http.StatusInternalServerError)
return
}
writer.WriteHeader(http.StatusOK)
})
// for tests
http.HandleFunc("/protected", validateToken(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, I'm protected"))
}, srv))
log.Fatal(http.ListenAndServe(":9096", nil))
}
func validateToken(f http.HandlerFunc, srv *server.Server) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, err := srv.ValidationBearerToken(r)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
f.ServeHTTP(w, r)
})
}