support Nextcloud OAuth 2.0 authentication

This commit is contained in:
MaysWind
2025-10-21 01:52:28 +08:00
parent 600ae2bd58
commit 53a8ad71c6
74 changed files with 2046 additions and 241 deletions
+21 -57
View File
@@ -2,6 +2,7 @@ package utils
import (
"encoding/json"
"errors"
"net/http"
"reflect"
@@ -11,6 +12,22 @@ import (
"github.com/mayswind/ezbookkeeping/pkg/errs"
)
// GetDisplayErrorMessage returns the display error message for given error
func GetDisplayErrorMessage(err *errs.Error) string {
if err.Code() == errs.ErrIncompleteOrIncorrectSubmission.Code() && len(err.BaseError) > 0 {
var validationErrors validator.ValidationErrors
ok := errors.As(err.BaseError[0], &validationErrors)
if ok {
for _, err := range validationErrors {
return getValidationErrorText(err)
}
}
}
return err.Error()
}
// PrintJsonSuccessResult writes success response in json format to current http context
func PrintJsonSuccessResult(c *core.WebContext, result any) {
c.JSON(http.StatusOK, core.O{
@@ -32,23 +49,10 @@ func PrintDataSuccessResult(c *core.WebContext, contentType string, fileName str
func PrintJsonErrorResult(c *core.WebContext, err *errs.Error) {
c.SetResponseError(err)
errorMessage := err.Error()
if err.Code() == errs.ErrIncompleteOrIncorrectSubmission.Code() && len(err.BaseError) > 0 {
validationErrors, ok := err.BaseError[0].(validator.ValidationErrors)
if ok {
for _, err := range validationErrors {
errorMessage = getValidationErrorText(err)
break
}
}
}
result := core.O{
"success": false,
"errorCode": err.Code(),
"errorMessage": errorMessage,
"errorMessage": GetDisplayErrorMessage(err),
"path": c.Request.URL.Path,
}
@@ -68,19 +72,6 @@ func PrintJSONRPCSuccessResult(c *core.WebContext, jsonRPCRequest *core.JSONRPCR
func PrintJSONRPCErrorResult(c *core.WebContext, jsonRPCRequest *core.JSONRPCRequest, err *errs.Error) {
c.SetResponseError(err)
errorMessage := err.Error()
if err.Code() == errs.ErrIncompleteOrIncorrectSubmission.Code() && len(err.BaseError) > 0 {
validationErrors, ok := err.BaseError[0].(validator.ValidationErrors)
if ok {
for _, err := range validationErrors {
errorMessage = getValidationErrorText(err)
break
}
}
}
var id any
if jsonRPCRequest != nil {
@@ -97,27 +88,13 @@ func PrintJSONRPCErrorResult(c *core.WebContext, jsonRPCRequest *core.JSONRPCReq
jsonRPCError = core.JSONRPCInvalidParamsError
}
c.AbortWithStatusJSON(err.HttpStatusCode, core.NewJSONRPCErrorResponseWithCause(id, jsonRPCError, errorMessage))
c.AbortWithStatusJSON(err.HttpStatusCode, core.NewJSONRPCErrorResponseWithCause(id, jsonRPCError, GetDisplayErrorMessage(err)))
}
// PrintDataErrorResult writes error response in custom content type to current http context
func PrintDataErrorResult(c *core.WebContext, contentType string, err *errs.Error) {
c.SetResponseError(err)
errorMessage := err.Error()
if err.Code() == errs.ErrIncompleteOrIncorrectSubmission.Code() && len(err.BaseError) > 0 {
validationErrors, ok := err.BaseError[0].(validator.ValidationErrors)
if ok {
for _, err := range validationErrors {
errorMessage = getValidationErrorText(err)
break
}
}
}
c.Data(err.HttpStatusCode, contentType, []byte(errorMessage))
c.Data(err.HttpStatusCode, contentType, []byte(GetDisplayErrorMessage(err)))
c.Abort()
}
@@ -149,23 +126,10 @@ func WriteEventStreamJsonSuccessResult(c *core.WebContext, result any) {
func WriteEventStreamJsonErrorResult(c *core.WebContext, originalErr *errs.Error) {
c.SetResponseError(originalErr)
errorMessage := originalErr.Error()
if originalErr.Code() == errs.ErrIncompleteOrIncorrectSubmission.Code() && len(originalErr.BaseError) > 0 {
validationErrors, ok := originalErr.BaseError[0].(validator.ValidationErrors)
if ok {
for _, err := range validationErrors {
errorMessage = getValidationErrorText(err)
break
}
}
}
result := core.O{
"success": false,
"errorCode": originalErr.Code(),
"errorMessage": errorMessage,
"errorMessage": GetDisplayErrorMessage(originalErr),
"path": c.Request.URL.Path,
}
+37
View File
@@ -1,10 +1,47 @@
package utils
import (
"crypto/tls"
"net/http"
"net/url"
"time"
)
type defaultTransport struct {
defaultUserAgent string
baseTransport http.RoundTripper
}
func (t *defaultTransport) RoundTrip(req *http.Request) (*http.Response, error) {
if len(req.Header.Values("User-Agent")) < 1 {
req.Header.Set("User-Agent", t.defaultUserAgent)
} else if req.Header.Get("User-Agent") == "" {
req.Header.Del("User-Agent")
}
return t.baseTransport.RoundTrip(req)
}
// NewHttpClient creates and returns a new http client with specified settings
func NewHttpClient(requestTimeout uint32, proxy string, skipTLSVerify bool, defaultUserAgent string) *http.Client {
baseTransport := http.DefaultTransport.(*http.Transport).Clone()
SetProxyUrl(baseTransport, proxy)
if skipTLSVerify {
baseTransport.TLSClientConfig = &tls.Config{
InsecureSkipVerify: true,
}
}
return &http.Client{
Transport: &defaultTransport{
defaultUserAgent: defaultUserAgent,
baseTransport: baseTransport,
},
Timeout: time.Duration(requestTimeout) * time.Millisecond,
}
}
// SetProxyUrl sets proxy url to http transport according to specified proxy setting
func SetProxyUrl(transport *http.Transport, proxy string) {
if proxy == "none" {