feat: implement precise token logout
This commit is contained in:
+31
-4
@@ -6677,14 +6677,19 @@ func authenticateIMHTTPBearer(wrt http.ResponseWriter, req *http.Request) (*imPr
|
||||
}
|
||||
|
||||
func resolveIMHTTPBearer(req *http.Request) (*imPrincipal, error) {
|
||||
principal, _, _, err := resolveIMHTTPBearerToken(req)
|
||||
return principal, err
|
||||
}
|
||||
|
||||
func resolveIMHTTPBearerToken(req *http.Request) (*imPrincipal, []byte, time.Duration, error) {
|
||||
authz := strings.TrimSpace(req.Header.Get("Authorization"))
|
||||
token, ok := strings.CutPrefix(authz, "Bearer ")
|
||||
if !ok || strings.TrimSpace(token) == "" || store.Store == nil {
|
||||
return nil, types.ErrPermissionDenied
|
||||
return nil, nil, 0, types.ErrPermissionDenied
|
||||
}
|
||||
handler := store.Store.GetLogicalAuthHandler("token")
|
||||
if handler == nil || !handler.IsInitialized() {
|
||||
return nil, types.ErrUnsupported
|
||||
return nil, nil, 0, types.ErrUnsupported
|
||||
}
|
||||
secret := []byte(strings.TrimSpace(token))
|
||||
if decoded, err := base64.StdEncoding.DecodeString(strings.TrimSpace(token)); err == nil {
|
||||
@@ -6692,9 +6697,31 @@ func resolveIMHTTPBearer(req *http.Request) (*imPrincipal, error) {
|
||||
}
|
||||
rec, _, err := handler.Authenticate(auth.AuthContext{}, secret)
|
||||
if err != nil || rec == nil || rec.TenantID.IsZero() || rec.Uid.IsZero() {
|
||||
return nil, types.ErrPermissionDenied
|
||||
return nil, nil, 0, types.ErrPermissionDenied
|
||||
}
|
||||
return &imPrincipal{TenantID: rec.TenantID, Uid: rec.Uid}, nil
|
||||
return &imPrincipal{TenantID: rec.TenantID, Uid: rec.Uid}, secret, time.Duration(rec.Lifetime), nil
|
||||
}
|
||||
|
||||
func serveIMAuthLogout(wrt http.ResponseWriter, req *http.Request) {
|
||||
if req.Method != http.MethodPost {
|
||||
writeIMError(wrt, req, http.StatusMethodNotAllowed, 30000, imReasonMethodNotAllowed, "method not allowed", nil)
|
||||
return
|
||||
}
|
||||
principal, token, ttl, err := resolveIMHTTPBearerToken(req)
|
||||
if err != nil {
|
||||
writeIMError(wrt, req, http.StatusUnauthorized, 30043, imReasonAuthRequired, "authentication required", nil)
|
||||
return
|
||||
}
|
||||
if ttl < time.Second {
|
||||
ttl = time.Second
|
||||
}
|
||||
enabled, err := store.RevokeLoginToken(principal.TenantID, token, ttl)
|
||||
if err != nil || !enabled {
|
||||
logs.Warn.Println("im logout: token revocation failed", principal.TenantID, principal.Uid, err)
|
||||
writeIMError(wrt, req, http.StatusInternalServerError, 90000, imReasonInternal, "internal error", nil)
|
||||
return
|
||||
}
|
||||
writeIMSuccess(wrt, req, map[string]any{"status": "ok"})
|
||||
}
|
||||
|
||||
func currentUserPhone(tenantID types.TenantID, uid types.Uid) (string, error) {
|
||||
|
||||
Reference in New Issue
Block a user