129 lines
2.6 KiB
Go
129 lines
2.6 KiB
Go
package server
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
|
|
"somehole.com/common/oauth2/session"
|
|
)
|
|
|
|
const TokenEndpoint = "/token"
|
|
|
|
type TokenError uint32
|
|
|
|
const (
|
|
TokenOk TokenError = iota
|
|
TokenErrorUnimplemented
|
|
TokenErrorUnauthorized
|
|
TokenErrorServerError
|
|
TokenErrorSlowDown
|
|
TokenErrorPending
|
|
)
|
|
|
|
func (te TokenError) Ok() bool {
|
|
return te == TokenOk
|
|
}
|
|
|
|
func (te TokenError) HttpStatus() (code int) {
|
|
switch te {
|
|
case TokenOk:
|
|
code = http.StatusOK
|
|
case TokenErrorUnimplemented:
|
|
code = http.StatusInternalServerError
|
|
case TokenErrorUnauthorized:
|
|
code = http.StatusUnauthorized
|
|
case TokenErrorServerError:
|
|
code = http.StatusInternalServerError
|
|
case TokenErrorSlowDown:
|
|
code = http.StatusBadRequest
|
|
case TokenErrorPending:
|
|
code = http.StatusBadRequest
|
|
}
|
|
return
|
|
}
|
|
|
|
func (te TokenError) String() (out string) {
|
|
switch te {
|
|
case TokenOk:
|
|
out = "authenticated"
|
|
case TokenErrorUnimplemented:
|
|
out = "token server unimplemented"
|
|
case TokenErrorUnauthorized:
|
|
out = "user unauthorized"
|
|
case TokenErrorServerError:
|
|
out = "internal server error"
|
|
case TokenErrorSlowDown:
|
|
out = "slow down"
|
|
case TokenErrorPending:
|
|
out = "authorization pending"
|
|
}
|
|
return
|
|
}
|
|
|
|
func (te TokenError) ErrorResponse() []byte {
|
|
var msg string
|
|
switch te {
|
|
case TokenErrorSlowDown:
|
|
msg = "slow_down"
|
|
case TokenErrorPending:
|
|
msg = "authorization_pending"
|
|
default:
|
|
msg = "internal_server_error"
|
|
}
|
|
return mustMarshalJson(struct {
|
|
Error string `json:"error"`
|
|
}{
|
|
Error: msg,
|
|
})
|
|
}
|
|
|
|
type TokenRequest struct {
|
|
State session.State
|
|
Code session.Code
|
|
}
|
|
|
|
func (tr *TokenRequest) Parse(data *url.Values) (err error) {
|
|
if !data.Has("code") {
|
|
err = fmt.Errorf("missing code paramater")
|
|
return
|
|
}
|
|
if !data.Has("state") {
|
|
err = fmt.Errorf("missing state parameter")
|
|
return
|
|
}
|
|
tr.State = session.State(data.Get("state"))
|
|
tr.Code = session.Code(data.Get("code"))
|
|
return
|
|
}
|
|
|
|
type TokenResponse struct {
|
|
Status int `json:"-"`
|
|
VerificationUri string `json:"verification_uri"`
|
|
UserCode session.Code `json:"user_code"`
|
|
DeviceCode session.Code `json:"device_code"`
|
|
Interval uint8 `json:"interval"`
|
|
}
|
|
|
|
func (tr *TokenResponse) HttpStatus() (code int) {
|
|
return tr.Status
|
|
}
|
|
|
|
func (tr *TokenResponse) Response() []byte {
|
|
return mustMarshalJson(tr)
|
|
}
|
|
|
|
type UnimplementedTokenServer struct{}
|
|
|
|
func (u UnimplementedTokenServer) mustEmbedUnimplementedTokenServer() {}
|
|
|
|
func (u UnimplementedTokenServer) Token(req *TokenRequest) (res *TokenResponse, errRes ErrorResponse) {
|
|
errRes = TokenErrorUnimplemented
|
|
return
|
|
}
|
|
|
|
type TokenServer interface {
|
|
mustEmbedUnimplementedTokenServer()
|
|
Token(*TokenRequest) (*TokenResponse, ErrorResponse)
|
|
}
|