mirror of
https://github.com/notherealmarco/WASAPhoto.git
synced 2025-05-05 12:22:35 +02:00
identity providers and bearerauth
This commit is contained in:
parent
5f3d4df33a
commit
626b7fa3e9
32 changed files with 1317 additions and 12 deletions
|
@ -1,11 +1,13 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"github.com/notherealmarco/WASAPhoto/service/api/reqcontext"
|
||||
"net/http"
|
||||
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"github.com/notherealmarco/WASAPhoto/service/api/authorization"
|
||||
"github.com/notherealmarco/WASAPhoto/service/api/reqcontext"
|
||||
"github.com/sirupsen/logrus"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// httpRouterHandler is the signature for functions that accepts a reqcontext.RequestContext in addition to those
|
||||
|
@ -21,8 +23,18 @@ func (rt *_router) wrap(fn httpRouterHandler) func(http.ResponseWriter, *http.Re
|
|||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
auth, err := authorization.BuildAuth(r.Header.Get("Authorization"))
|
||||
|
||||
if err != nil {
|
||||
rt.baseLogger.WithError(err).Info("User not authorized")
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
var ctx = reqcontext.RequestContext{
|
||||
ReqUUID: reqUUID,
|
||||
Auth: auth,
|
||||
}
|
||||
|
||||
// Create a request-specific logger
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
// Handler returns an instance of httprouter.Router that handle APIs registered here
|
||||
func (rt *_router) Handler() http.Handler {
|
||||
// Register routes
|
||||
rt.router.POST("/session", rt.wrap(rt.PostSession))
|
||||
rt.router.GET("/", rt.getHelloWorld)
|
||||
rt.router.GET("/context", rt.wrap(rt.getContextReply))
|
||||
|
||||
|
|
50
service/api/authorization/auth-bearer.go
Normal file
50
service/api/authorization/auth-bearer.go
Normal file
|
@ -0,0 +1,50 @@
|
|||
package authorization
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/notherealmarco/WASAPhoto/service/database"
|
||||
)
|
||||
|
||||
type BearerAuth struct {
|
||||
token string
|
||||
}
|
||||
|
||||
func (b *BearerAuth) GetType() string {
|
||||
return "Bearer"
|
||||
}
|
||||
|
||||
func BuildBearer(header string) (*BearerAuth, error) {
|
||||
if header == "" {
|
||||
return nil, errors.New("missing authorization header")
|
||||
}
|
||||
if header == "Bearer" {
|
||||
return nil, errors.New("missing token")
|
||||
}
|
||||
if !strings.HasPrefix(header, "Bearer ") {
|
||||
return nil, errors.New("invalid authorization header")
|
||||
}
|
||||
return &BearerAuth{token: header[7:]}, nil
|
||||
}
|
||||
|
||||
func (b *BearerAuth) GetToken() string {
|
||||
return b.token
|
||||
}
|
||||
|
||||
func (b *BearerAuth) Authorized(db database.AppDatabase) (bool, error) {
|
||||
// this is the way we manage authorization, the bearer token is the user id
|
||||
state, err := db.UserExists(b.token)
|
||||
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return state, nil
|
||||
}
|
||||
|
||||
func (b *BearerAuth) UserAuthorized(db database.AppDatabase, uid string) (bool, error) {
|
||||
if b.token == uid {
|
||||
return b.Authorized(db)
|
||||
}
|
||||
return false, nil
|
||||
}
|
18
service/api/authorization/auth-manager.go
Normal file
18
service/api/authorization/auth-manager.go
Normal file
|
@ -0,0 +1,18 @@
|
|||
package authorization
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/notherealmarco/WASAPhoto/service/api/reqcontext"
|
||||
)
|
||||
|
||||
func BuildAuth(header string) (reqcontext.Authorization, error) {
|
||||
auth, err := BuildBearer(header)
|
||||
if err != nil {
|
||||
if err.Error() == "invalid authorization header" {
|
||||
return nil, errors.New("method not supported") // todo: better error description
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return auth, nil
|
||||
}
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"github.com/notherealmarco/WASAPhoto/service/api/reqcontext"
|
||||
"github.com/notherealmarco/WASAPhoto/service/database/db_errors"
|
||||
)
|
||||
|
||||
type _reqbody struct {
|
||||
|
@ -21,15 +22,26 @@ type _respbody struct {
|
|||
func (rt *_router) PostSession(w http.ResponseWriter, r *http.Request, ps httprouter.Params, ctx reqcontext.RequestContext) {
|
||||
|
||||
var request _reqbody
|
||||
json.NewDecoder(r.Body).Decode(&request) //todo: capire se serve close
|
||||
err := json.NewDecoder(r.Body).Decode(&request) //todo: capire se serve close
|
||||
|
||||
uid, err := rt.db.GetUserID(request.Name)
|
||||
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
var uid string
|
||||
if err == nil { // test if user exists
|
||||
uid, err = rt.db.GetUserID(request.Name)
|
||||
}
|
||||
if db_errors.EmptySet(err) { // user does not exist
|
||||
err = nil
|
||||
uid, err = rt.db.CreateUser(request.Name)
|
||||
}
|
||||
if err != nil { // handle any other error
|
||||
w.WriteHeader(http.StatusInternalServerError) // todo: is not ok
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("content-type", "application/json")
|
||||
json.NewEncoder(w).Encode(_respbody{UID: uid})
|
||||
err = json.NewEncoder(w).Encode(_respbody{UID: uid})
|
||||
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError) // todo: is not ok
|
||||
return
|
||||
}
|
||||
}
|
14
service/api/put-updateusername.go
Normal file
14
service/api/put-updateusername.go
Normal file
|
@ -0,0 +1,14 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"github.com/notherealmarco/WASAPhoto/service/api/reqcontext"
|
||||
)
|
||||
|
||||
func (rt *_router) UpdateUsername(w http.ResponseWriter, r *http.Request, ps httprouter.Params, ctx reqcontext.RequestContext) {
|
||||
|
||||
auth, err := ctx.Auth.UserAuthorized(rt.db, r.URL.Path // todo: prendere il coso giusto dal path)
|
||||
|
||||
}
|
|
@ -8,6 +8,7 @@ package reqcontext
|
|||
|
||||
import (
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/notherealmarco/WASAPhoto/service/database"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
|
@ -18,4 +19,12 @@ type RequestContext struct {
|
|||
|
||||
// Logger is a custom field logger for the request
|
||||
Logger logrus.FieldLogger
|
||||
|
||||
Auth Authorization
|
||||
}
|
||||
|
||||
type Authorization interface {
|
||||
GetType() string
|
||||
Authorized(db database.AppDatabase) (bool, error)
|
||||
UserAuthorized(db database.AppDatabase, uid string) (bool, error)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue