mirror of
https://github.com/drakkan/sftpgo.git
synced 2025-12-07 06:40:54 +03:00
OpenAPI: add users API
These new APIs match the web client features. I'm aware that some API do not follow REST best practises. I want to avoid things likes "/user/folders/<path>" where "path" must be encoded and making it optional create issues, so I defined resources as query parameters instead of path parameters
This commit is contained in:
@@ -36,9 +36,11 @@ func validateJWTToken(w http.ResponseWriter, r *http.Request, audience tokenAudi
|
||||
redirectPath = webClientLoginPath
|
||||
}
|
||||
|
||||
isAPIToken := (audience == tokenAudienceAPI || audience == tokenAudienceAPIUser)
|
||||
|
||||
if err != nil || token == nil {
|
||||
logger.Debug(logSender, "", "error getting jwt token: %v", err)
|
||||
if audience == tokenAudienceAPI {
|
||||
if isAPIToken {
|
||||
sendAPIResponse(w, r, err, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
||||
} else {
|
||||
http.Redirect(w, r, redirectPath, http.StatusFound)
|
||||
@@ -49,7 +51,7 @@ func validateJWTToken(w http.ResponseWriter, r *http.Request, audience tokenAudi
|
||||
err = jwt.Validate(token)
|
||||
if err != nil {
|
||||
logger.Debug(logSender, "", "error validating jwt token: %v", err)
|
||||
if audience == tokenAudienceAPI {
|
||||
if isAPIToken {
|
||||
sendAPIResponse(w, r, err, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
||||
} else {
|
||||
http.Redirect(w, r, redirectPath, http.StatusFound)
|
||||
@@ -58,7 +60,7 @@ func validateJWTToken(w http.ResponseWriter, r *http.Request, audience tokenAudi
|
||||
}
|
||||
if !utils.IsStringInSlice(audience, token.Audience()) {
|
||||
logger.Debug(logSender, "", "the token is not valid for audience %#v", audience)
|
||||
if audience == tokenAudienceAPI {
|
||||
if isAPIToken {
|
||||
sendAPIResponse(w, r, nil, "Your token audience is not valid", http.StatusUnauthorized)
|
||||
} else {
|
||||
http.Redirect(w, r, redirectPath, http.StatusFound)
|
||||
@@ -67,7 +69,7 @@ func validateJWTToken(w http.ResponseWriter, r *http.Request, audience tokenAudi
|
||||
}
|
||||
if isTokenInvalidated(r) {
|
||||
logger.Debug(logSender, "", "the token has been invalidated")
|
||||
if audience == tokenAudienceAPI {
|
||||
if isAPIToken {
|
||||
sendAPIResponse(w, r, nil, "Your token is no longer valid", http.StatusUnauthorized)
|
||||
} else {
|
||||
http.Redirect(w, r, redirectPath, http.StatusFound)
|
||||
@@ -88,6 +90,17 @@ func jwtAuthenticatorAPI(next http.Handler) http.Handler {
|
||||
})
|
||||
}
|
||||
|
||||
func jwtAuthenticatorAPIUser(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if err := validateJWTToken(w, r, tokenAudienceAPIUser); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Token is authenticated, pass it through
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
func jwtAuthenticatorWebAdmin(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if err := validateJWTToken(w, r, tokenAudienceWebAdmin); err != nil {
|
||||
@@ -110,19 +123,28 @@ func jwtAuthenticatorWebClient(next http.Handler) http.Handler {
|
||||
})
|
||||
}
|
||||
|
||||
func checkClientPerm(perm string) func(next http.Handler) http.Handler {
|
||||
//nolint:unparam
|
||||
func checkHTTPUserPerm(perm string) func(next http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
_, claims, err := jwtauth.FromContext(r.Context())
|
||||
if err != nil {
|
||||
renderClientBadRequestPage(w, r, err)
|
||||
if isWebRequest(r) {
|
||||
renderClientBadRequestPage(w, r, err)
|
||||
} else {
|
||||
sendAPIResponse(w, r, err, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
|
||||
}
|
||||
return
|
||||
}
|
||||
tokenClaims := jwtTokenClaims{}
|
||||
tokenClaims.Decode(claims)
|
||||
// for web client perms are negated and not granted
|
||||
if tokenClaims.hasPerm(perm) {
|
||||
renderClientForbiddenPage(w, r, "You don't have permission for this action")
|
||||
if isWebRequest(r) {
|
||||
renderClientForbiddenPage(w, r, "You don't have permission for this action")
|
||||
} else {
|
||||
sendAPIResponse(w, r, nil, http.StatusText(http.StatusForbidden), http.StatusForbidden)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user