baisc structure and server begin server impl

This commit is contained in:
Livio Amstutz 2019-11-18 15:37:48 +01:00
parent 26bd873f4e
commit f6ba7ab75e
17 changed files with 575 additions and 0 deletions

16
pkg/server/authrequest.go Normal file
View file

@ -0,0 +1,16 @@
package server
import (
"errors"
"net/http"
"github.com/caos/oidc/pkg/oidc"
)
func ParseAuthRequest(w http.ResponseWriter, r *http.Request) (*oidc.AuthRequest, error) {
return nil, errors.New("Unimplemented") //TODO: impl
}
func ValidateAuthRequest(authRequest *oidc.AuthRequest) error {
return errors.New("Unimplemented") //TODO: impl https://openid.net/specs/openid-connect-core-1_0.html#rfc.section.3.1.2.2
}

9
pkg/server/config.go Normal file
View file

@ -0,0 +1,9 @@
package server
type Configuration interface {
Issuer() string
AuthorizationEndpoint() string
TokenEndpoint() string
UserinfoEndpoint() string
Port() string
}

View file

@ -0,0 +1,101 @@
package server
import (
"net/http"
"github.com/caos/oidc/pkg/utils"
"github.com/caos/oidc/pkg/oidc"
)
type DefaultHandler struct {
config *Config
discoveryConfig *oidc.DiscoveryConfiguration
storage Storage
http *http.Server
}
type Config struct {
Issuer string
AuthorizationEndpoint string
TokenEndpoint string
UserinfoEndpoint string
Port string
}
func (c *Config) OIDC() *oidc.DiscoveryConfiguration {
return &oidc.DiscoveryConfiguration{}
}
func NewDefaultHandler(config *Config, storage Storage) Handler {
h := &DefaultHandler{
config: config,
discoveryConfig: config.OIDC(),
storage: storage,
}
router := CreateRouter(h)
h.http = &http.Server{
Addr: config.Port,
Handler: router,
}
return h
}
func (h *DefaultHandler) Issuer() string {
return h.config.Issuer
}
func (h *DefaultHandler) AuthorizationEndpoint() string {
return h.config.AuthorizationEndpoint
}
func (h *DefaultHandler) TokenEndpoint() string {
return h.config.TokenEndpoint
}
func (h *DefaultHandler) UserinfoEndpoint() string {
return h.config.UserinfoEndpoint
}
func (h *DefaultHandler) Port() string {
return h.config.Port
}
func (h *DefaultHandler) HttpHandler() *http.Server {
return h.http
}
func (h *DefaultHandler) HandleDiscovery(w http.ResponseWriter, r *http.Request) {
utils.MarshalJSON(w, h.discoveryConfig)
}
func (h *DefaultHandler) HandleAuthorize(w http.ResponseWriter, r *http.Request) {
authRequest, err := ParseAuthRequest(w, r)
if err != nil {
//TODO: return err
}
err = ValidateAuthRequest(authRequest)
if err != nil {
//TODO: return err
}
if NeedsExistingSession(authRequest) {
// session, err := h.storage.CheckSession(authRequest)
// if err != nil {
// //TODO: return err
// }
}
err = h.storage.CreateAuthRequest(authRequest)
if err != nil {
//TODO: return err
}
//TODO: redirect?
}
func (h *DefaultHandler) HandleExchange(w http.ResponseWriter, r *http.Request) {
}
func (h *DefaultHandler) HandleUserinfo(w http.ResponseWriter, r *http.Request) {
}

View file

@ -0,0 +1,47 @@
package server
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/require"
"github.com/caos/oidc/pkg/oidc"
)
func TestDefaultHandler_HandleDiscovery(t *testing.T) {
type fields struct {
config *Config
discoveryConfig *oidc.DiscoveryConfiguration
storage Storage
http *http.Server
}
type args struct {
w http.ResponseWriter
r *http.Request
}
tests := []struct {
name string
fields fields
args args
want string
wantCode int
}{
{"OK", fields{config: nil, discoveryConfig: &oidc.DiscoveryConfiguration{Issuer: "test"}}, args{httptest.NewRecorder(), nil}, `{"issuer":"test"}`, 200},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
h := &DefaultHandler{
config: tt.fields.config,
discoveryConfig: tt.fields.discoveryConfig,
storage: tt.fields.storage,
http: tt.fields.http,
}
h.HandleDiscovery(tt.args.w, tt.args.r)
rec := tt.args.w.(*httptest.ResponseRecorder)
require.Equal(t, tt.want, rec.Body.String())
require.Equal(t, tt.wantCode, rec.Code)
})
}
}

44
pkg/server/handler.go Normal file
View file

@ -0,0 +1,44 @@
package server
import (
"context"
"net/http"
"github.com/gorilla/mux"
"github.com/caos/oidc/pkg/oidc"
"github.com/caos/utils/logging"
)
type Handler interface {
Configuration
// Storage() Storage
HandleDiscovery(w http.ResponseWriter, r *http.Request)
HandleAuthorize(w http.ResponseWriter, r *http.Request)
HandleExchange(w http.ResponseWriter, r *http.Request)
HandleUserinfo(w http.ResponseWriter, r *http.Request)
HttpHandler() *http.Server
}
func CreateRouter(h Handler) *mux.Router {
router := mux.NewRouter()
router.HandleFunc(oidc.DiscoveryEndpoint, h.HandleDiscovery)
router.HandleFunc(h.AuthorizationEndpoint(), h.HandleAuthorize)
router.HandleFunc(h.TokenEndpoint(), h.HandleExchange)
router.HandleFunc(h.UserinfoEndpoint(), h.HandleUserinfo)
return router
}
func Start(ctx context.Context, h Handler) {
go func() {
<-ctx.Done()
err := h.HttpHandler().Shutdown(ctx)
logging.Log("SERVE-REqwpM").OnError(err).Error("graceful shutdown of oidc server failed")
}()
go func() {
err := h.HttpHandler().ListenAndServe()
logging.Log("SERVE-4YNIwG").OnError(err).Panic("oidc server serve failed")
}()
logging.LogWithFields("SERVE-koAFMs", "port", h.Port()).Info("oidc server is listening")
}

7
pkg/server/session.go Normal file
View file

@ -0,0 +1,7 @@
package server
import "github.com/caos/oidc/pkg/oidc"
func NeedsExistingSession(authRequest *oidc.AuthRequest) bool {
return authRequest.IDTokenHint != "" //TODO: impl: https://openid.net/specs/openid-connect-core-1_0.html#rfc.section.3.1.2.2
}

7
pkg/server/storage.go Normal file
View file

@ -0,0 +1,7 @@
package server
import "github.com/caos/oidc/pkg/oidc"
type Storage interface {
CreateAuthRequest(*oidc.AuthRequest) error
}