forked from portainer/portainer
/
logout_oauth.go
83 lines (71 loc) · 2.44 KB
/
logout_oauth.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package auth
import (
"fmt"
"github.com/cloudogu/portainer-ce/api/dataservices"
portError "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/response"
"io"
"mime"
"net/http"
"net/url"
"strings"
)
type verifyResponse struct {
Valid bool `json:"valid"`
}
func (handler *Handler) invalidateOAuthSession(w http.ResponseWriter, r *http.Request) *portError.HandlerError {
defer r.Body.Close()
body, err := io.ReadAll(r.Body)
if err != nil {
return &portError.HandlerError{http.StatusInternalServerError, "Unable to block token: ", err}
}
content, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
if err != nil {
return &portError.HandlerError{http.StatusInternalServerError, "Unable to find content-type ", err}
}
if content == "application/x-www-form-urlencoded" || content == "text/plain" {
values, err := url.ParseQuery(string(body))
if err != nil {
return &portError.HandlerError{http.StatusInternalServerError, "Cannot parse body ", err}
}
token := values.Get("logoutRequest")
jwtBlocklist, ok := handler.JWTService.(dataservices.BlocklistedJWTService)
fmt.Printf("###### token: %s and service could be casted: %t", token, ok)
if ok {
jwtBlocklist.AddTokenToBlocklist(token)
}
return nil
} else {
return &portError.HandlerError{
StatusCode: http.StatusInternalServerError,
Message: fmt.Sprintf("Invalid content type %s. Expected \"application/x-www-form-urlencoded\" or \"text/plain\"", content),
}
}
}
func (handler *Handler) isJWTTokenNotBlocked(w http.ResponseWriter, r *http.Request) *portError.HandlerError {
token, handlerErr := handler.retrieveAuthTokenFromRequest(r)
if handlerErr != nil {
return handlerErr
}
var err error
_, err = handler.JWTService.ParseAndVerifyToken(token)
if err != nil {
return response.JSON(w, &verifyResponse{Valid: false})
}
return response.JSON(w, &verifyResponse{Valid: true})
}
func (handler *Handler) retrieveAuthTokenFromRequest(r *http.Request) (string, *portError.HandlerError) {
// Optionally, token might be set via the "token" query parameter.
// For example, in websocket requests
token := r.URL.Query().Get("token")
// Get token from the Authorization header
tokens, ok := r.Header["Authorization"]
if ok && len(tokens) >= 1 {
token = tokens[0]
token = strings.TrimPrefix(token, "Bearer ")
}
if token == "" {
return "", &portError.HandlerError{StatusCode: http.StatusBadRequest, Message: "Missing token"}
}
return token, nil
}