2022-11-18 13:05:40 +01:00
|
|
|
package authorization
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"strings"
|
|
|
|
|
2022-11-18 17:18:46 +01:00
|
|
|
"github.com/notherealmarco/WASAPhoto/service/api/reqcontext"
|
2022-11-18 13:05:40 +01:00
|
|
|
"github.com/notherealmarco/WASAPhoto/service/database"
|
|
|
|
)
|
|
|
|
|
2023-01-10 01:21:53 +01:00
|
|
|
// BearerAuth is the authentication provider that authorizes users by Bearer tokens
|
|
|
|
// In this case, a token is the unique identifier for a user.
|
2022-11-18 13:05:40 +01:00
|
|
|
type BearerAuth struct {
|
|
|
|
token string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *BearerAuth) GetType() string {
|
|
|
|
return "Bearer"
|
|
|
|
}
|
|
|
|
|
2023-01-10 01:21:53 +01:00
|
|
|
// Given the content of the Authorization header, returns a BearerAuth instance for the user
|
|
|
|
// Returns an error if the header is not valid
|
2022-11-18 13:05:40 +01:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2023-01-10 01:21:53 +01:00
|
|
|
// Returns the user ID of the user that is currently logged in
|
2022-11-20 19:21:26 +01:00
|
|
|
func (b *BearerAuth) GetUserID() string {
|
2022-11-18 13:05:40 +01:00
|
|
|
return b.token
|
|
|
|
}
|
|
|
|
|
2023-01-10 01:21:53 +01:00
|
|
|
// Checks if the token is valid
|
2022-11-18 18:58:12 +01:00
|
|
|
func (b *BearerAuth) Authorized(db database.AppDatabase) (reqcontext.AuthStatus, error) {
|
2022-11-18 13:05:40 +01:00
|
|
|
// this is the way we manage authorization, the bearer token is the user id
|
|
|
|
state, err := db.UserExists(b.token)
|
|
|
|
|
|
|
|
if err != nil {
|
2022-11-18 18:58:12 +01:00
|
|
|
return reqcontext.UNAUTHORIZED, err
|
2022-11-18 13:05:40 +01:00
|
|
|
}
|
2022-11-18 18:58:12 +01:00
|
|
|
|
|
|
|
if state {
|
|
|
|
return reqcontext.AUTHORIZED, nil
|
|
|
|
}
|
|
|
|
return reqcontext.UNAUTHORIZED, nil
|
2022-11-18 13:05:40 +01:00
|
|
|
}
|
|
|
|
|
2023-01-10 01:21:53 +01:00
|
|
|
// Checks if the given user and the currently logged in user are the same user
|
2022-11-18 17:18:46 +01:00
|
|
|
func (b *BearerAuth) UserAuthorized(db database.AppDatabase, uid string) (reqcontext.AuthStatus, error) {
|
2022-11-18 18:58:12 +01:00
|
|
|
|
|
|
|
// If uid is not a valid user, return USER_NOT_FOUND
|
|
|
|
user_exists, err := db.UserExists(uid)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return reqcontext.UNAUTHORIZED, err
|
|
|
|
}
|
|
|
|
if !user_exists {
|
|
|
|
return reqcontext.USER_NOT_FOUND, nil
|
|
|
|
}
|
|
|
|
|
2022-11-18 13:05:40 +01:00
|
|
|
if b.token == uid {
|
2023-01-10 01:21:53 +01:00
|
|
|
// If the user is the same as the one in the token, check if the user does actually exist in the database
|
2022-11-18 17:18:46 +01:00
|
|
|
auth, err := b.Authorized(db)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return -1, err
|
|
|
|
}
|
|
|
|
|
2022-11-18 18:58:12 +01:00
|
|
|
return auth, nil
|
2022-11-18 13:05:40 +01:00
|
|
|
}
|
2023-01-10 01:21:53 +01:00
|
|
|
// If the user is not the same as the one in the token, return FORBIDDEN
|
2022-11-18 17:18:46 +01:00
|
|
|
return reqcontext.FORBIDDEN, nil
|
2022-11-18 13:05:40 +01:00
|
|
|
}
|