diff --git a/README.md b/README.md index 46be440..d42f37e 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,9 @@ go get github.com/click33/sa-token-go/integrations/chi@latest # Chi framework go get github.com/click33/sa-token-go/integrations/gf@latest # GoFrame framework # or go get github.com/click33/sa-token-go/integrations/kratos@latest # Kratos framework +# or +go get github.com/click33/sa-token-go/integrations/hertz@latest # Hertz framework +``` # Storage module (choose one) go get github.com/click33/sa-token-go/storage/memory@latest # Memory storage (dev) @@ -70,6 +73,7 @@ go get github.com/click33/sa-token-go/integrations/fiber@latest # Fiber framewor go get github.com/click33/sa-token-go/integrations/chi@latest # Chi framework go get github.com/click33/sa-token-go/integrations/gf@latest # GoFrame framework go get github.com/click33/sa-token-go/integrations/kratos@latest# Kratos framework +go get github.com/click33/sa-token-go/integrations/hertz@latest # Hertz framework ``` ### ⚡ Minimal Usage (One-line Initialization) @@ -378,6 +382,10 @@ r.Get("/user", sachi.CheckLogin(), handler) // Kratos import sakratos "github.com/click33/sa-token-go/integrations/kratos" // Use Plugin.Server() as middleware + +// Hertz +import sahertz "github.com/click33/sa-token-go/integrations/hertz" +h.GET("/user", sahertz.CheckLogin(), handler) ``` ## 🎨 Advanced Features diff --git a/README_zh.md b/README_zh.md index 4d7de6b..7410136 100644 --- a/README_zh.md +++ b/README_zh.md @@ -46,6 +46,8 @@ go get github.com/click33/sa-token-go/integrations/chi@latest # Chi框架 go get github.com/click33/sa-token-go/integrations/gf@latest # GoFrame框架 # 或 go get github.com/click33/sa-token-go/integrations/kratos@latest# Kratos框架 +# 或 +go get github.com/click33/sa-token-go/integrations/hertz@latest # Hertz框架 # 存储模块(选一个) go get github.com/click33/sa-token-go/storage/memory@latest # 内存存储(开发) @@ -70,6 +72,7 @@ go get github.com/click33/sa-token-go/integrations/fiber@latest # Fiber框架 go get github.com/click33/sa-token-go/integrations/chi@latest # Chi框架 go get github.com/click33/sa-token-go/integrations/gf@latest # GoFrame框架 go get github.com/click33/sa-token-go/integrations/kratos@latest# Kratos框架 +go get github.com/click33/sa-token-go/integrations/hertz@latest # Hertz框架 ``` ### ⚡ 超简洁使用(一行初始化) @@ -378,6 +381,10 @@ r.Get("/user", sachi.CheckLogin(), handler) // Kratos import sakratos "github.com/click33/sa-token-go/integrations/kratos" // 使用 Plugin.Server() 作为中间件 + +// Hertz +import sahertz "github.com/click33/sa-token-go/integrations/hertz" +h.GET("/user", sahertz.CheckLogin(), handler) ``` ## 🎨 高级特性 diff --git a/examples/gin/gin-example/go.sum b/examples/gin/gin-example/go.sum new file mode 100644 index 0000000..9a20c5a --- /dev/null +++ b/examples/gin/gin-example/go.sum @@ -0,0 +1,141 @@ +github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= +github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= +github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/click33/sa-token-go/stputil v0.1.7 h1:omAPMerECe8gBRFHLzjxnuNYFPipcHi/gd3U75r4gzg= +github.com/click33/sa-token-go/stputil v0.1.7/go.mod h1:YY4NzfwVMwPUQLDBk9C5eVLQ08oI3vNSFQhBuZBPtgY= +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= +github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8= +github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= +github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/panjf2000/ants/v2 v2.11.3 h1:AfI0ngBoXJmYOpDh9m516vjqoUu2sLrIVgppI9TZVpg= +github.com/panjf2000/ants/v2 v2.11.3/go.mod h1:8u92CYMUc6gyvTIw8Ru7Mt7+/ESnJahz5EVtqfrilek= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= +github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= +go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= +golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= +golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= +golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= +golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/examples/hertz/herz-example/.gitignore b/examples/hertz/herz-example/.gitignore new file mode 100644 index 0000000..101ea87 --- /dev/null +++ b/examples/hertz/herz-example/.gitignore @@ -0,0 +1,37 @@ +*.o +*.a +*.so +_obj +_test +*.[568vq] +[568vq].out +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* +_testmain.go +*.exe +*.exe~ +*.test +*.prof +*.rar +*.zip +*.gz +*.psd +*.bmd +*.cfg +*.pptx +*.log +*nohup.out +*settings.pyc +*.sublime-project +*.sublime-workspace +!.gitkeep +.DS_Store +/.idea +/.vscode +/output +*.local.yml +dumped_hertz_remote_config.json + \ No newline at end of file diff --git a/examples/hertz/herz-example/.hz b/examples/hertz/herz-example/.hz new file mode 100644 index 0000000..791041d --- /dev/null +++ b/examples/hertz/herz-example/.hz @@ -0,0 +1,6 @@ +// Code generated by hz. DO NOT EDIT. + +hz version: v0.9.7 +handlerDir: "" +modelDir: "" +routerDir: "" diff --git a/examples/hertz/herz-example/biz/handler/user/user_service.go b/examples/hertz/herz-example/biz/handler/user/user_service.go new file mode 100644 index 0000000..53e3d09 --- /dev/null +++ b/examples/hertz/herz-example/biz/handler/user/user_service.go @@ -0,0 +1,131 @@ +// Code generated by hertz generator. + +package user + +import ( + "context" + "time" + + user "github.com/click33/sa-token-go/examples/hertz/herz-example/biz/model/user" + "github.com/click33/sa-token-go/stputil" + "github.com/cloudwego/hertz/pkg/app" + "github.com/cloudwego/hertz/pkg/protocol/consts" +) + +// Login . +// @router /login [POST] +func Login(ctx context.Context, c *app.RequestContext) { + var err error + var req user.LoginReq + err = c.BindAndValidate(&req) + if err != nil { + c.String(consts.StatusBadRequest, err.Error()) + return + } + + token, err := stputil.Login(req.GetUserId()) + if err != nil { + c.String(consts.StatusBadRequest, err.Error()) + return + } + loginID, err := stputil.GetLoginID(token) + if err != nil { + c.String(consts.StatusBadRequest, err.Error()) + return + } + err = stputil.SetRoles(loginID, []string{"manager"}) + if err != nil { + c.String(consts.StatusBadRequest, err.Error()) + return + } + + resp := new(user.LoginResp) + resp.Token = token + + c.JSON(consts.StatusOK, resp) +} + +// Public . +// @router /public [GET] +func Public(ctx context.Context, c *app.RequestContext) { + + resp := new(user.MessageResp) + resp.Message = "public" + + c.JSON(consts.StatusOK, resp) +} + +// UserInfo . +// @router /user [GET] +func UserInfo(ctx context.Context, c *app.RequestContext) { + + resp := new(user.UserInfoResp) + loginID, err := stputil.GetLoginID(c.Request.Header.Get("satoken")) + if err != nil { + c.String(consts.StatusBadRequest, err.Error()) + return + } + roles, _ := stputil.GetRoles(loginID) + permissions, _ := stputil.GetPermissions(loginID) + + resp.LoginId = loginID + resp.Roles = roles + resp.Permissions = permissions + + c.JSON(consts.StatusOK, resp) +} + +// Admin . +// @router /admin [GET] +func Admin(ctx context.Context, c *app.RequestContext) { + + resp := new(user.MessageResp) + resp.Message = "admin" + + c.JSON(consts.StatusOK, resp) +} + +// Manager . +// @router /manager [GET] +func Manager(ctx context.Context, c *app.RequestContext) { + + resp := new(user.MessageResp) + resp.Message = "manager" + + c.JSON(consts.StatusOK, resp) +} + +// Sensitive . +// @router /sensitive [GET] +func Sensitive(ctx context.Context, c *app.RequestContext) { + + resp := new(user.SensitiveResp) + loginID, err := stputil.GetLoginID(c.Request.Header.Get("satoken")) + if err != nil { + c.String(consts.StatusBadRequest, err.Error()) + return + } + resp.Sensitive = stputil.IsDisable(loginID) + + c.JSON(consts.StatusOK, resp) +} + +// Disable . +// @router /disable [GET] +func Disable(ctx context.Context, c *app.RequestContext) { + var err error + + loginID, err := stputil.GetLoginID(c.Request.Header.Get("satoken")) + if err != nil { + c.String(consts.StatusBadRequest, err.Error()) + return + } + err = stputil.Disable(loginID, time.Hour) + if err != nil { + c.String(consts.StatusBadRequest, err.Error()) + return + } + resp := new(user.MessageResp) + + c.JSON(consts.StatusOK, resp) +} diff --git a/examples/hertz/herz-example/biz/model/user/user.go b/examples/hertz/herz-example/biz/model/user/user.go new file mode 100644 index 0000000..9cb30f1 --- /dev/null +++ b/examples/hertz/herz-example/biz/model/user/user.go @@ -0,0 +1,3004 @@ +// Code generated by thriftgo (0.4.3). DO NOT EDIT. + +package user + +import ( + "context" + "fmt" + "github.com/apache/thrift/lib/go/thrift" +) + +type LoginReq struct { + UserId string `thrift:"userId,1" json:"userId" query:"userId"` +} + +func NewLoginReq() *LoginReq { + return &LoginReq{} +} + +func (p *LoginReq) InitDefault() { +} + +func (p *LoginReq) GetUserId() (v string) { + return p.UserId +} + +var fieldIDToName_LoginReq = map[int16]string{ + 1: "userId", +} + +func (p *LoginReq) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.STRING { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_LoginReq[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *LoginReq) ReadField1(iprot thrift.TProtocol) error { + + var _field string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _field = v + } + p.UserId = _field + return nil +} + +func (p *LoginReq) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("LoginReq"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *LoginReq) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("userId", thrift.STRING, 1); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.UserId); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *LoginReq) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("LoginReq(%+v)", *p) + +} + +type LoginResp struct { + Token string `thrift:"token,1" form:"token" json:"token" query:"token"` +} + +func NewLoginResp() *LoginResp { + return &LoginResp{} +} + +func (p *LoginResp) InitDefault() { +} + +func (p *LoginResp) GetToken() (v string) { + return p.Token +} + +var fieldIDToName_LoginResp = map[int16]string{ + 1: "token", +} + +func (p *LoginResp) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.STRING { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_LoginResp[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *LoginResp) ReadField1(iprot thrift.TProtocol) error { + + var _field string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _field = v + } + p.Token = _field + return nil +} + +func (p *LoginResp) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("LoginResp"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *LoginResp) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("token", thrift.STRING, 1); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.Token); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *LoginResp) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("LoginResp(%+v)", *p) + +} + +type MessageResp struct { + Message string `thrift:"message,1" form:"message" json:"message" query:"message"` +} + +func NewMessageResp() *MessageResp { + return &MessageResp{} +} + +func (p *MessageResp) InitDefault() { +} + +func (p *MessageResp) GetMessage() (v string) { + return p.Message +} + +var fieldIDToName_MessageResp = map[int16]string{ + 1: "message", +} + +func (p *MessageResp) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.STRING { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_MessageResp[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *MessageResp) ReadField1(iprot thrift.TProtocol) error { + + var _field string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _field = v + } + p.Message = _field + return nil +} + +func (p *MessageResp) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("MessageResp"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *MessageResp) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("message", thrift.STRING, 1); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.Message); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *MessageResp) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("MessageResp(%+v)", *p) + +} + +type UserInfoResp struct { + LoginId string `thrift:"loginId,1" form:"loginId" json:"loginId" query:"loginId"` + Roles []string `thrift:"roles,2,default,list" form:"roles" json:"roles" query:"roles"` + Permissions []string `thrift:"permissions,3,default,list" form:"permissions" json:"permissions" query:"permissions"` +} + +func NewUserInfoResp() *UserInfoResp { + return &UserInfoResp{} +} + +func (p *UserInfoResp) InitDefault() { +} + +func (p *UserInfoResp) GetLoginId() (v string) { + return p.LoginId +} + +func (p *UserInfoResp) GetRoles() (v []string) { + return p.Roles +} + +func (p *UserInfoResp) GetPermissions() (v []string) { + return p.Permissions +} + +var fieldIDToName_UserInfoResp = map[int16]string{ + 1: "loginId", + 2: "roles", + 3: "permissions", +} + +func (p *UserInfoResp) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.STRING { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + case 2: + if fieldTypeId == thrift.LIST { + if err = p.ReadField2(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + case 3: + if fieldTypeId == thrift.LIST { + if err = p.ReadField3(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_UserInfoResp[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *UserInfoResp) ReadField1(iprot thrift.TProtocol) error { + + var _field string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _field = v + } + p.LoginId = _field + return nil +} +func (p *UserInfoResp) ReadField2(iprot thrift.TProtocol) error { + _, size, err := iprot.ReadListBegin() + if err != nil { + return err + } + _field := make([]string, 0, size) + for i := 0; i < size; i++ { + + var _elem string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _elem = v + } + + _field = append(_field, _elem) + } + if err := iprot.ReadListEnd(); err != nil { + return err + } + p.Roles = _field + return nil +} +func (p *UserInfoResp) ReadField3(iprot thrift.TProtocol) error { + _, size, err := iprot.ReadListBegin() + if err != nil { + return err + } + _field := make([]string, 0, size) + for i := 0; i < size; i++ { + + var _elem string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _elem = v + } + + _field = append(_field, _elem) + } + if err := iprot.ReadListEnd(); err != nil { + return err + } + p.Permissions = _field + return nil +} + +func (p *UserInfoResp) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("UserInfoResp"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + if err = p.writeField2(oprot); err != nil { + fieldId = 2 + goto WriteFieldError + } + if err = p.writeField3(oprot); err != nil { + fieldId = 3 + goto WriteFieldError + } + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *UserInfoResp) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("loginId", thrift.STRING, 1); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.LoginId); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *UserInfoResp) writeField2(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("roles", thrift.LIST, 2); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteListBegin(thrift.STRING, len(p.Roles)); err != nil { + return err + } + for _, v := range p.Roles { + if err := oprot.WriteString(v); err != nil { + return err + } + } + if err := oprot.WriteListEnd(); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err) +} + +func (p *UserInfoResp) writeField3(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("permissions", thrift.LIST, 3); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteListBegin(thrift.STRING, len(p.Permissions)); err != nil { + return err + } + for _, v := range p.Permissions { + if err := oprot.WriteString(v); err != nil { + return err + } + } + if err := oprot.WriteListEnd(); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 3 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 3 end error: ", p), err) +} + +func (p *UserInfoResp) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("UserInfoResp(%+v)", *p) + +} + +type SensitiveResp struct { + Sensitive bool `thrift:"sensitive,1" form:"sensitive" json:"sensitive" query:"sensitive"` +} + +func NewSensitiveResp() *SensitiveResp { + return &SensitiveResp{} +} + +func (p *SensitiveResp) InitDefault() { +} + +func (p *SensitiveResp) GetSensitive() (v bool) { + return p.Sensitive +} + +var fieldIDToName_SensitiveResp = map[int16]string{ + 1: "sensitive", +} + +func (p *SensitiveResp) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.BOOL { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_SensitiveResp[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *SensitiveResp) ReadField1(iprot thrift.TProtocol) error { + + var _field bool + if v, err := iprot.ReadBool(); err != nil { + return err + } else { + _field = v + } + p.Sensitive = _field + return nil +} + +func (p *SensitiveResp) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("SensitiveResp"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *SensitiveResp) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("sensitive", thrift.BOOL, 1); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteBool(p.Sensitive); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *SensitiveResp) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("SensitiveResp(%+v)", *p) + +} + +type UserService interface { + Login(ctx context.Context, request *LoginReq) (r *LoginResp, err error) + + Public(ctx context.Context) (r *MessageResp, err error) + + UserInfo(ctx context.Context) (r *UserInfoResp, err error) + + Admin(ctx context.Context) (r *MessageResp, err error) + + Manager(ctx context.Context) (r *MessageResp, err error) + + Disable(ctx context.Context) (r *MessageResp, err error) + + Sensitive(ctx context.Context) (r *SensitiveResp, err error) +} + +type UserServiceClient struct { + c thrift.TClient +} + +func NewUserServiceClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *UserServiceClient { + return &UserServiceClient{ + c: thrift.NewTStandardClient(f.GetProtocol(t), f.GetProtocol(t)), + } +} + +func NewUserServiceClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *UserServiceClient { + return &UserServiceClient{ + c: thrift.NewTStandardClient(iprot, oprot), + } +} + +func NewUserServiceClient(c thrift.TClient) *UserServiceClient { + return &UserServiceClient{ + c: c, + } +} + +func (p *UserServiceClient) Client_() thrift.TClient { + return p.c +} + +func (p *UserServiceClient) Login(ctx context.Context, request *LoginReq) (r *LoginResp, err error) { + var _args UserServiceLoginArgs + _args.Request = request + var _result UserServiceLoginResult + if err = p.Client_().Call(ctx, "Login", &_args, &_result); err != nil { + return + } + return _result.GetSuccess(), nil +} +func (p *UserServiceClient) Public(ctx context.Context) (r *MessageResp, err error) { + var _args UserServicePublicArgs + var _result UserServicePublicResult + if err = p.Client_().Call(ctx, "Public", &_args, &_result); err != nil { + return + } + return _result.GetSuccess(), nil +} +func (p *UserServiceClient) UserInfo(ctx context.Context) (r *UserInfoResp, err error) { + var _args UserServiceUserInfoArgs + var _result UserServiceUserInfoResult + if err = p.Client_().Call(ctx, "UserInfo", &_args, &_result); err != nil { + return + } + return _result.GetSuccess(), nil +} +func (p *UserServiceClient) Admin(ctx context.Context) (r *MessageResp, err error) { + var _args UserServiceAdminArgs + var _result UserServiceAdminResult + if err = p.Client_().Call(ctx, "Admin", &_args, &_result); err != nil { + return + } + return _result.GetSuccess(), nil +} +func (p *UserServiceClient) Manager(ctx context.Context) (r *MessageResp, err error) { + var _args UserServiceManagerArgs + var _result UserServiceManagerResult + if err = p.Client_().Call(ctx, "Manager", &_args, &_result); err != nil { + return + } + return _result.GetSuccess(), nil +} +func (p *UserServiceClient) Disable(ctx context.Context) (r *MessageResp, err error) { + var _args UserServiceDisableArgs + var _result UserServiceDisableResult + if err = p.Client_().Call(ctx, "Disable", &_args, &_result); err != nil { + return + } + return _result.GetSuccess(), nil +} +func (p *UserServiceClient) Sensitive(ctx context.Context) (r *SensitiveResp, err error) { + var _args UserServiceSensitiveArgs + var _result UserServiceSensitiveResult + if err = p.Client_().Call(ctx, "Sensitive", &_args, &_result); err != nil { + return + } + return _result.GetSuccess(), nil +} + +type UserServiceProcessor struct { + processorMap map[string]thrift.TProcessorFunction + handler UserService +} + +func (p *UserServiceProcessor) AddToProcessorMap(key string, processor thrift.TProcessorFunction) { + p.processorMap[key] = processor +} + +func (p *UserServiceProcessor) GetProcessorFunction(key string) (processor thrift.TProcessorFunction, ok bool) { + processor, ok = p.processorMap[key] + return processor, ok +} + +func (p *UserServiceProcessor) ProcessorMap() map[string]thrift.TProcessorFunction { + return p.processorMap +} + +func NewUserServiceProcessor(handler UserService) *UserServiceProcessor { + self := &UserServiceProcessor{handler: handler, processorMap: make(map[string]thrift.TProcessorFunction)} + self.AddToProcessorMap("Login", &userServiceProcessorLogin{handler: handler}) + self.AddToProcessorMap("Public", &userServiceProcessorPublic{handler: handler}) + self.AddToProcessorMap("UserInfo", &userServiceProcessorUserInfo{handler: handler}) + self.AddToProcessorMap("Admin", &userServiceProcessorAdmin{handler: handler}) + self.AddToProcessorMap("Manager", &userServiceProcessorManager{handler: handler}) + self.AddToProcessorMap("Disable", &userServiceProcessorDisable{handler: handler}) + self.AddToProcessorMap("Sensitive", &userServiceProcessorSensitive{handler: handler}) + return self +} +func (p *UserServiceProcessor) Process(ctx context.Context, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + name, _, seqId, err := iprot.ReadMessageBegin() + if err != nil { + return false, err + } + if processor, ok := p.GetProcessorFunction(name); ok { + return processor.Process(ctx, seqId, iprot, oprot) + } + iprot.Skip(thrift.STRUCT) + iprot.ReadMessageEnd() + x := thrift.NewTApplicationException(thrift.UNKNOWN_METHOD, "Unknown function "+name) + oprot.WriteMessageBegin(name, thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush(ctx) + return false, x +} + +type userServiceProcessorLogin struct { + handler UserService +} + +func (p *userServiceProcessorLogin) Process(ctx context.Context, seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + args := UserServiceLoginArgs{} + if err = args.Read(iprot); err != nil { + iprot.ReadMessageEnd() + x := thrift.NewTApplicationException(thrift.PROTOCOL_ERROR, err.Error()) + oprot.WriteMessageBegin("Login", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush(ctx) + return false, err + } + + iprot.ReadMessageEnd() + var err2 error + result := UserServiceLoginResult{} + var retval *LoginResp + if retval, err2 = p.handler.Login(ctx, args.Request); err2 != nil { + x := thrift.NewTApplicationException(thrift.INTERNAL_ERROR, "Internal error processing Login: "+err2.Error()) + oprot.WriteMessageBegin("Login", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush(ctx) + return true, err2 + } else { + result.Success = retval + } + if err2 = oprot.WriteMessageBegin("Login", thrift.REPLY, seqId); err2 != nil { + err = err2 + } + if err2 = result.Write(oprot); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.WriteMessageEnd(); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.Flush(ctx); err == nil && err2 != nil { + err = err2 + } + if err != nil { + return + } + return true, err +} + +type userServiceProcessorPublic struct { + handler UserService +} + +func (p *userServiceProcessorPublic) Process(ctx context.Context, seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + args := UserServicePublicArgs{} + if err = args.Read(iprot); err != nil { + iprot.ReadMessageEnd() + x := thrift.NewTApplicationException(thrift.PROTOCOL_ERROR, err.Error()) + oprot.WriteMessageBegin("Public", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush(ctx) + return false, err + } + + iprot.ReadMessageEnd() + var err2 error + result := UserServicePublicResult{} + var retval *MessageResp + if retval, err2 = p.handler.Public(ctx); err2 != nil { + x := thrift.NewTApplicationException(thrift.INTERNAL_ERROR, "Internal error processing Public: "+err2.Error()) + oprot.WriteMessageBegin("Public", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush(ctx) + return true, err2 + } else { + result.Success = retval + } + if err2 = oprot.WriteMessageBegin("Public", thrift.REPLY, seqId); err2 != nil { + err = err2 + } + if err2 = result.Write(oprot); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.WriteMessageEnd(); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.Flush(ctx); err == nil && err2 != nil { + err = err2 + } + if err != nil { + return + } + return true, err +} + +type userServiceProcessorUserInfo struct { + handler UserService +} + +func (p *userServiceProcessorUserInfo) Process(ctx context.Context, seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + args := UserServiceUserInfoArgs{} + if err = args.Read(iprot); err != nil { + iprot.ReadMessageEnd() + x := thrift.NewTApplicationException(thrift.PROTOCOL_ERROR, err.Error()) + oprot.WriteMessageBegin("UserInfo", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush(ctx) + return false, err + } + + iprot.ReadMessageEnd() + var err2 error + result := UserServiceUserInfoResult{} + var retval *UserInfoResp + if retval, err2 = p.handler.UserInfo(ctx); err2 != nil { + x := thrift.NewTApplicationException(thrift.INTERNAL_ERROR, "Internal error processing UserInfo: "+err2.Error()) + oprot.WriteMessageBegin("UserInfo", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush(ctx) + return true, err2 + } else { + result.Success = retval + } + if err2 = oprot.WriteMessageBegin("UserInfo", thrift.REPLY, seqId); err2 != nil { + err = err2 + } + if err2 = result.Write(oprot); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.WriteMessageEnd(); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.Flush(ctx); err == nil && err2 != nil { + err = err2 + } + if err != nil { + return + } + return true, err +} + +type userServiceProcessorAdmin struct { + handler UserService +} + +func (p *userServiceProcessorAdmin) Process(ctx context.Context, seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + args := UserServiceAdminArgs{} + if err = args.Read(iprot); err != nil { + iprot.ReadMessageEnd() + x := thrift.NewTApplicationException(thrift.PROTOCOL_ERROR, err.Error()) + oprot.WriteMessageBegin("Admin", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush(ctx) + return false, err + } + + iprot.ReadMessageEnd() + var err2 error + result := UserServiceAdminResult{} + var retval *MessageResp + if retval, err2 = p.handler.Admin(ctx); err2 != nil { + x := thrift.NewTApplicationException(thrift.INTERNAL_ERROR, "Internal error processing Admin: "+err2.Error()) + oprot.WriteMessageBegin("Admin", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush(ctx) + return true, err2 + } else { + result.Success = retval + } + if err2 = oprot.WriteMessageBegin("Admin", thrift.REPLY, seqId); err2 != nil { + err = err2 + } + if err2 = result.Write(oprot); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.WriteMessageEnd(); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.Flush(ctx); err == nil && err2 != nil { + err = err2 + } + if err != nil { + return + } + return true, err +} + +type userServiceProcessorManager struct { + handler UserService +} + +func (p *userServiceProcessorManager) Process(ctx context.Context, seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + args := UserServiceManagerArgs{} + if err = args.Read(iprot); err != nil { + iprot.ReadMessageEnd() + x := thrift.NewTApplicationException(thrift.PROTOCOL_ERROR, err.Error()) + oprot.WriteMessageBegin("Manager", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush(ctx) + return false, err + } + + iprot.ReadMessageEnd() + var err2 error + result := UserServiceManagerResult{} + var retval *MessageResp + if retval, err2 = p.handler.Manager(ctx); err2 != nil { + x := thrift.NewTApplicationException(thrift.INTERNAL_ERROR, "Internal error processing Manager: "+err2.Error()) + oprot.WriteMessageBegin("Manager", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush(ctx) + return true, err2 + } else { + result.Success = retval + } + if err2 = oprot.WriteMessageBegin("Manager", thrift.REPLY, seqId); err2 != nil { + err = err2 + } + if err2 = result.Write(oprot); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.WriteMessageEnd(); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.Flush(ctx); err == nil && err2 != nil { + err = err2 + } + if err != nil { + return + } + return true, err +} + +type userServiceProcessorDisable struct { + handler UserService +} + +func (p *userServiceProcessorDisable) Process(ctx context.Context, seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + args := UserServiceDisableArgs{} + if err = args.Read(iprot); err != nil { + iprot.ReadMessageEnd() + x := thrift.NewTApplicationException(thrift.PROTOCOL_ERROR, err.Error()) + oprot.WriteMessageBegin("Disable", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush(ctx) + return false, err + } + + iprot.ReadMessageEnd() + var err2 error + result := UserServiceDisableResult{} + var retval *MessageResp + if retval, err2 = p.handler.Disable(ctx); err2 != nil { + x := thrift.NewTApplicationException(thrift.INTERNAL_ERROR, "Internal error processing Disable: "+err2.Error()) + oprot.WriteMessageBegin("Disable", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush(ctx) + return true, err2 + } else { + result.Success = retval + } + if err2 = oprot.WriteMessageBegin("Disable", thrift.REPLY, seqId); err2 != nil { + err = err2 + } + if err2 = result.Write(oprot); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.WriteMessageEnd(); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.Flush(ctx); err == nil && err2 != nil { + err = err2 + } + if err != nil { + return + } + return true, err +} + +type userServiceProcessorSensitive struct { + handler UserService +} + +func (p *userServiceProcessorSensitive) Process(ctx context.Context, seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + args := UserServiceSensitiveArgs{} + if err = args.Read(iprot); err != nil { + iprot.ReadMessageEnd() + x := thrift.NewTApplicationException(thrift.PROTOCOL_ERROR, err.Error()) + oprot.WriteMessageBegin("Sensitive", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush(ctx) + return false, err + } + + iprot.ReadMessageEnd() + var err2 error + result := UserServiceSensitiveResult{} + var retval *SensitiveResp + if retval, err2 = p.handler.Sensitive(ctx); err2 != nil { + x := thrift.NewTApplicationException(thrift.INTERNAL_ERROR, "Internal error processing Sensitive: "+err2.Error()) + oprot.WriteMessageBegin("Sensitive", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush(ctx) + return true, err2 + } else { + result.Success = retval + } + if err2 = oprot.WriteMessageBegin("Sensitive", thrift.REPLY, seqId); err2 != nil { + err = err2 + } + if err2 = result.Write(oprot); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.WriteMessageEnd(); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.Flush(ctx); err == nil && err2 != nil { + err = err2 + } + if err != nil { + return + } + return true, err +} + +type UserServiceLoginArgs struct { + Request *LoginReq `thrift:"request,1"` +} + +func NewUserServiceLoginArgs() *UserServiceLoginArgs { + return &UserServiceLoginArgs{} +} + +func (p *UserServiceLoginArgs) InitDefault() { +} + +var UserServiceLoginArgs_Request_DEFAULT *LoginReq + +func (p *UserServiceLoginArgs) GetRequest() (v *LoginReq) { + if !p.IsSetRequest() { + return UserServiceLoginArgs_Request_DEFAULT + } + return p.Request +} + +var fieldIDToName_UserServiceLoginArgs = map[int16]string{ + 1: "request", +} + +func (p *UserServiceLoginArgs) IsSetRequest() bool { + return p.Request != nil +} + +func (p *UserServiceLoginArgs) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_UserServiceLoginArgs[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *UserServiceLoginArgs) ReadField1(iprot thrift.TProtocol) error { + _field := NewLoginReq() + if err := _field.Read(iprot); err != nil { + return err + } + p.Request = _field + return nil +} + +func (p *UserServiceLoginArgs) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("Login_args"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *UserServiceLoginArgs) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("request", thrift.STRUCT, 1); err != nil { + goto WriteFieldBeginError + } + if err := p.Request.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *UserServiceLoginArgs) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("UserServiceLoginArgs(%+v)", *p) + +} + +type UserServiceLoginResult struct { + Success *LoginResp `thrift:"success,0,optional"` +} + +func NewUserServiceLoginResult() *UserServiceLoginResult { + return &UserServiceLoginResult{} +} + +func (p *UserServiceLoginResult) InitDefault() { +} + +var UserServiceLoginResult_Success_DEFAULT *LoginResp + +func (p *UserServiceLoginResult) GetSuccess() (v *LoginResp) { + if !p.IsSetSuccess() { + return UserServiceLoginResult_Success_DEFAULT + } + return p.Success +} + +var fieldIDToName_UserServiceLoginResult = map[int16]string{ + 0: "success", +} + +func (p *UserServiceLoginResult) IsSetSuccess() bool { + return p.Success != nil +} + +func (p *UserServiceLoginResult) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 0: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField0(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_UserServiceLoginResult[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *UserServiceLoginResult) ReadField0(iprot thrift.TProtocol) error { + _field := NewLoginResp() + if err := _field.Read(iprot); err != nil { + return err + } + p.Success = _field + return nil +} + +func (p *UserServiceLoginResult) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("Login_result"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField0(oprot); err != nil { + fieldId = 0 + goto WriteFieldError + } + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *UserServiceLoginResult) writeField0(oprot thrift.TProtocol) (err error) { + if p.IsSetSuccess() { + if err = oprot.WriteFieldBegin("success", thrift.STRUCT, 0); err != nil { + goto WriteFieldBeginError + } + if err := p.Success.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 0 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 0 end error: ", p), err) +} + +func (p *UserServiceLoginResult) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("UserServiceLoginResult(%+v)", *p) + +} + +type UserServicePublicArgs struct { +} + +func NewUserServicePublicArgs() *UserServicePublicArgs { + return &UserServicePublicArgs{} +} + +func (p *UserServicePublicArgs) InitDefault() { +} + +var fieldIDToName_UserServicePublicArgs = map[int16]string{} + +func (p *UserServicePublicArgs) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldTypeError + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +SkipFieldTypeError: + return thrift.PrependError(fmt.Sprintf("%T skip field type %d error", p, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *UserServicePublicArgs) Write(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteStructBegin("Public_args"); err != nil { + goto WriteStructBeginError + } + if p != nil { + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *UserServicePublicArgs) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("UserServicePublicArgs(%+v)", *p) + +} + +type UserServicePublicResult struct { + Success *MessageResp `thrift:"success,0,optional"` +} + +func NewUserServicePublicResult() *UserServicePublicResult { + return &UserServicePublicResult{} +} + +func (p *UserServicePublicResult) InitDefault() { +} + +var UserServicePublicResult_Success_DEFAULT *MessageResp + +func (p *UserServicePublicResult) GetSuccess() (v *MessageResp) { + if !p.IsSetSuccess() { + return UserServicePublicResult_Success_DEFAULT + } + return p.Success +} + +var fieldIDToName_UserServicePublicResult = map[int16]string{ + 0: "success", +} + +func (p *UserServicePublicResult) IsSetSuccess() bool { + return p.Success != nil +} + +func (p *UserServicePublicResult) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 0: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField0(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_UserServicePublicResult[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *UserServicePublicResult) ReadField0(iprot thrift.TProtocol) error { + _field := NewMessageResp() + if err := _field.Read(iprot); err != nil { + return err + } + p.Success = _field + return nil +} + +func (p *UserServicePublicResult) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("Public_result"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField0(oprot); err != nil { + fieldId = 0 + goto WriteFieldError + } + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *UserServicePublicResult) writeField0(oprot thrift.TProtocol) (err error) { + if p.IsSetSuccess() { + if err = oprot.WriteFieldBegin("success", thrift.STRUCT, 0); err != nil { + goto WriteFieldBeginError + } + if err := p.Success.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 0 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 0 end error: ", p), err) +} + +func (p *UserServicePublicResult) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("UserServicePublicResult(%+v)", *p) + +} + +type UserServiceUserInfoArgs struct { +} + +func NewUserServiceUserInfoArgs() *UserServiceUserInfoArgs { + return &UserServiceUserInfoArgs{} +} + +func (p *UserServiceUserInfoArgs) InitDefault() { +} + +var fieldIDToName_UserServiceUserInfoArgs = map[int16]string{} + +func (p *UserServiceUserInfoArgs) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldTypeError + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +SkipFieldTypeError: + return thrift.PrependError(fmt.Sprintf("%T skip field type %d error", p, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *UserServiceUserInfoArgs) Write(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteStructBegin("UserInfo_args"); err != nil { + goto WriteStructBeginError + } + if p != nil { + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *UserServiceUserInfoArgs) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("UserServiceUserInfoArgs(%+v)", *p) + +} + +type UserServiceUserInfoResult struct { + Success *UserInfoResp `thrift:"success,0,optional"` +} + +func NewUserServiceUserInfoResult() *UserServiceUserInfoResult { + return &UserServiceUserInfoResult{} +} + +func (p *UserServiceUserInfoResult) InitDefault() { +} + +var UserServiceUserInfoResult_Success_DEFAULT *UserInfoResp + +func (p *UserServiceUserInfoResult) GetSuccess() (v *UserInfoResp) { + if !p.IsSetSuccess() { + return UserServiceUserInfoResult_Success_DEFAULT + } + return p.Success +} + +var fieldIDToName_UserServiceUserInfoResult = map[int16]string{ + 0: "success", +} + +func (p *UserServiceUserInfoResult) IsSetSuccess() bool { + return p.Success != nil +} + +func (p *UserServiceUserInfoResult) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 0: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField0(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_UserServiceUserInfoResult[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *UserServiceUserInfoResult) ReadField0(iprot thrift.TProtocol) error { + _field := NewUserInfoResp() + if err := _field.Read(iprot); err != nil { + return err + } + p.Success = _field + return nil +} + +func (p *UserServiceUserInfoResult) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("UserInfo_result"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField0(oprot); err != nil { + fieldId = 0 + goto WriteFieldError + } + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *UserServiceUserInfoResult) writeField0(oprot thrift.TProtocol) (err error) { + if p.IsSetSuccess() { + if err = oprot.WriteFieldBegin("success", thrift.STRUCT, 0); err != nil { + goto WriteFieldBeginError + } + if err := p.Success.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 0 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 0 end error: ", p), err) +} + +func (p *UserServiceUserInfoResult) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("UserServiceUserInfoResult(%+v)", *p) + +} + +type UserServiceAdminArgs struct { +} + +func NewUserServiceAdminArgs() *UserServiceAdminArgs { + return &UserServiceAdminArgs{} +} + +func (p *UserServiceAdminArgs) InitDefault() { +} + +var fieldIDToName_UserServiceAdminArgs = map[int16]string{} + +func (p *UserServiceAdminArgs) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldTypeError + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +SkipFieldTypeError: + return thrift.PrependError(fmt.Sprintf("%T skip field type %d error", p, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *UserServiceAdminArgs) Write(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteStructBegin("Admin_args"); err != nil { + goto WriteStructBeginError + } + if p != nil { + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *UserServiceAdminArgs) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("UserServiceAdminArgs(%+v)", *p) + +} + +type UserServiceAdminResult struct { + Success *MessageResp `thrift:"success,0,optional"` +} + +func NewUserServiceAdminResult() *UserServiceAdminResult { + return &UserServiceAdminResult{} +} + +func (p *UserServiceAdminResult) InitDefault() { +} + +var UserServiceAdminResult_Success_DEFAULT *MessageResp + +func (p *UserServiceAdminResult) GetSuccess() (v *MessageResp) { + if !p.IsSetSuccess() { + return UserServiceAdminResult_Success_DEFAULT + } + return p.Success +} + +var fieldIDToName_UserServiceAdminResult = map[int16]string{ + 0: "success", +} + +func (p *UserServiceAdminResult) IsSetSuccess() bool { + return p.Success != nil +} + +func (p *UserServiceAdminResult) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 0: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField0(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_UserServiceAdminResult[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *UserServiceAdminResult) ReadField0(iprot thrift.TProtocol) error { + _field := NewMessageResp() + if err := _field.Read(iprot); err != nil { + return err + } + p.Success = _field + return nil +} + +func (p *UserServiceAdminResult) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("Admin_result"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField0(oprot); err != nil { + fieldId = 0 + goto WriteFieldError + } + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *UserServiceAdminResult) writeField0(oprot thrift.TProtocol) (err error) { + if p.IsSetSuccess() { + if err = oprot.WriteFieldBegin("success", thrift.STRUCT, 0); err != nil { + goto WriteFieldBeginError + } + if err := p.Success.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 0 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 0 end error: ", p), err) +} + +func (p *UserServiceAdminResult) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("UserServiceAdminResult(%+v)", *p) + +} + +type UserServiceManagerArgs struct { +} + +func NewUserServiceManagerArgs() *UserServiceManagerArgs { + return &UserServiceManagerArgs{} +} + +func (p *UserServiceManagerArgs) InitDefault() { +} + +var fieldIDToName_UserServiceManagerArgs = map[int16]string{} + +func (p *UserServiceManagerArgs) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldTypeError + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +SkipFieldTypeError: + return thrift.PrependError(fmt.Sprintf("%T skip field type %d error", p, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *UserServiceManagerArgs) Write(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteStructBegin("Manager_args"); err != nil { + goto WriteStructBeginError + } + if p != nil { + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *UserServiceManagerArgs) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("UserServiceManagerArgs(%+v)", *p) + +} + +type UserServiceManagerResult struct { + Success *MessageResp `thrift:"success,0,optional"` +} + +func NewUserServiceManagerResult() *UserServiceManagerResult { + return &UserServiceManagerResult{} +} + +func (p *UserServiceManagerResult) InitDefault() { +} + +var UserServiceManagerResult_Success_DEFAULT *MessageResp + +func (p *UserServiceManagerResult) GetSuccess() (v *MessageResp) { + if !p.IsSetSuccess() { + return UserServiceManagerResult_Success_DEFAULT + } + return p.Success +} + +var fieldIDToName_UserServiceManagerResult = map[int16]string{ + 0: "success", +} + +func (p *UserServiceManagerResult) IsSetSuccess() bool { + return p.Success != nil +} + +func (p *UserServiceManagerResult) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 0: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField0(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_UserServiceManagerResult[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *UserServiceManagerResult) ReadField0(iprot thrift.TProtocol) error { + _field := NewMessageResp() + if err := _field.Read(iprot); err != nil { + return err + } + p.Success = _field + return nil +} + +func (p *UserServiceManagerResult) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("Manager_result"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField0(oprot); err != nil { + fieldId = 0 + goto WriteFieldError + } + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *UserServiceManagerResult) writeField0(oprot thrift.TProtocol) (err error) { + if p.IsSetSuccess() { + if err = oprot.WriteFieldBegin("success", thrift.STRUCT, 0); err != nil { + goto WriteFieldBeginError + } + if err := p.Success.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 0 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 0 end error: ", p), err) +} + +func (p *UserServiceManagerResult) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("UserServiceManagerResult(%+v)", *p) + +} + +type UserServiceDisableArgs struct { +} + +func NewUserServiceDisableArgs() *UserServiceDisableArgs { + return &UserServiceDisableArgs{} +} + +func (p *UserServiceDisableArgs) InitDefault() { +} + +var fieldIDToName_UserServiceDisableArgs = map[int16]string{} + +func (p *UserServiceDisableArgs) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldTypeError + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +SkipFieldTypeError: + return thrift.PrependError(fmt.Sprintf("%T skip field type %d error", p, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *UserServiceDisableArgs) Write(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteStructBegin("Disable_args"); err != nil { + goto WriteStructBeginError + } + if p != nil { + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *UserServiceDisableArgs) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("UserServiceDisableArgs(%+v)", *p) + +} + +type UserServiceDisableResult struct { + Success *MessageResp `thrift:"success,0,optional"` +} + +func NewUserServiceDisableResult() *UserServiceDisableResult { + return &UserServiceDisableResult{} +} + +func (p *UserServiceDisableResult) InitDefault() { +} + +var UserServiceDisableResult_Success_DEFAULT *MessageResp + +func (p *UserServiceDisableResult) GetSuccess() (v *MessageResp) { + if !p.IsSetSuccess() { + return UserServiceDisableResult_Success_DEFAULT + } + return p.Success +} + +var fieldIDToName_UserServiceDisableResult = map[int16]string{ + 0: "success", +} + +func (p *UserServiceDisableResult) IsSetSuccess() bool { + return p.Success != nil +} + +func (p *UserServiceDisableResult) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 0: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField0(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_UserServiceDisableResult[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *UserServiceDisableResult) ReadField0(iprot thrift.TProtocol) error { + _field := NewMessageResp() + if err := _field.Read(iprot); err != nil { + return err + } + p.Success = _field + return nil +} + +func (p *UserServiceDisableResult) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("Disable_result"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField0(oprot); err != nil { + fieldId = 0 + goto WriteFieldError + } + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *UserServiceDisableResult) writeField0(oprot thrift.TProtocol) (err error) { + if p.IsSetSuccess() { + if err = oprot.WriteFieldBegin("success", thrift.STRUCT, 0); err != nil { + goto WriteFieldBeginError + } + if err := p.Success.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 0 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 0 end error: ", p), err) +} + +func (p *UserServiceDisableResult) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("UserServiceDisableResult(%+v)", *p) + +} + +type UserServiceSensitiveArgs struct { +} + +func NewUserServiceSensitiveArgs() *UserServiceSensitiveArgs { + return &UserServiceSensitiveArgs{} +} + +func (p *UserServiceSensitiveArgs) InitDefault() { +} + +var fieldIDToName_UserServiceSensitiveArgs = map[int16]string{} + +func (p *UserServiceSensitiveArgs) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldTypeError + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +SkipFieldTypeError: + return thrift.PrependError(fmt.Sprintf("%T skip field type %d error", p, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *UserServiceSensitiveArgs) Write(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteStructBegin("Sensitive_args"); err != nil { + goto WriteStructBeginError + } + if p != nil { + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *UserServiceSensitiveArgs) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("UserServiceSensitiveArgs(%+v)", *p) + +} + +type UserServiceSensitiveResult struct { + Success *SensitiveResp `thrift:"success,0,optional"` +} + +func NewUserServiceSensitiveResult() *UserServiceSensitiveResult { + return &UserServiceSensitiveResult{} +} + +func (p *UserServiceSensitiveResult) InitDefault() { +} + +var UserServiceSensitiveResult_Success_DEFAULT *SensitiveResp + +func (p *UserServiceSensitiveResult) GetSuccess() (v *SensitiveResp) { + if !p.IsSetSuccess() { + return UserServiceSensitiveResult_Success_DEFAULT + } + return p.Success +} + +var fieldIDToName_UserServiceSensitiveResult = map[int16]string{ + 0: "success", +} + +func (p *UserServiceSensitiveResult) IsSetSuccess() bool { + return p.Success != nil +} + +func (p *UserServiceSensitiveResult) Read(iprot thrift.TProtocol) (err error) { + + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 0: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField0(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_UserServiceSensitiveResult[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *UserServiceSensitiveResult) ReadField0(iprot thrift.TProtocol) error { + _field := NewSensitiveResp() + if err := _field.Read(iprot); err != nil { + return err + } + p.Success = _field + return nil +} + +func (p *UserServiceSensitiveResult) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("Sensitive_result"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField0(oprot); err != nil { + fieldId = 0 + goto WriteFieldError + } + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *UserServiceSensitiveResult) writeField0(oprot thrift.TProtocol) (err error) { + if p.IsSetSuccess() { + if err = oprot.WriteFieldBegin("success", thrift.STRUCT, 0); err != nil { + goto WriteFieldBeginError + } + if err := p.Success.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 0 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 0 end error: ", p), err) +} + +func (p *UserServiceSensitiveResult) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("UserServiceSensitiveResult(%+v)", *p) + +} diff --git a/examples/hertz/herz-example/biz/router/register.go b/examples/hertz/herz-example/biz/router/register.go new file mode 100644 index 0000000..242cfd9 --- /dev/null +++ b/examples/hertz/herz-example/biz/router/register.go @@ -0,0 +1,15 @@ +// Code generated by hertz generator. DO NOT EDIT. + +package router + +import ( + user "github.com/click33/sa-token-go/examples/hertz/herz-example/biz/router/user" + "github.com/cloudwego/hertz/pkg/app/server" +) + +// GeneratedRegister registers routers generated by IDL. +func GeneratedRegister(r *server.Hertz) { + //INSERT_POINT: DO NOT DELETE THIS LINE! + user.Register(r) + +} diff --git a/examples/hertz/herz-example/biz/router/user/middleware.go b/examples/hertz/herz-example/biz/router/user/middleware.go new file mode 100644 index 0000000..da94324 --- /dev/null +++ b/examples/hertz/herz-example/biz/router/user/middleware.go @@ -0,0 +1,47 @@ +// Code generated by hertz generator. + +package user + +import ( + sahertz "github.com/click33/sa-token-go/integrations/hertz" + "github.com/cloudwego/hertz/pkg/app" +) + +func rootMw() []app.HandlerFunc { + // your code... + return nil +} + +func _adminMw() []app.HandlerFunc { + // your code... + return []app.HandlerFunc{sahertz.CheckPermission("admin:*")} +} + +func _loginMw() []app.HandlerFunc { + // your code... + return nil +} + +func _managerMw() []app.HandlerFunc { + // your code... + return []app.HandlerFunc{sahertz.CheckRole("manager")} +} + +func _publicMw() []app.HandlerFunc { + return []app.HandlerFunc{sahertz.Ignore()} +} + +func _sensitiveMw() []app.HandlerFunc { + // your code... + return []app.HandlerFunc{sahertz.CheckDisable()} +} + +func _userinfoMw() []app.HandlerFunc { + // your code... + return []app.HandlerFunc{sahertz.CheckLogin()} +} + +func _disableMw() []app.HandlerFunc { + // your code... + return nil +} diff --git a/examples/hertz/herz-example/biz/router/user/user.go b/examples/hertz/herz-example/biz/router/user/user.go new file mode 100644 index 0000000..04ddee4 --- /dev/null +++ b/examples/hertz/herz-example/biz/router/user/user.go @@ -0,0 +1,27 @@ +// Code generated by hertz generator. DO NOT EDIT. + +package user + +import ( + user "github.com/click33/sa-token-go/examples/hertz/herz-example/biz/handler/user" + "github.com/cloudwego/hertz/pkg/app/server" +) + +/* + This file will register all the routes of the services in the master idl. + And it will update automatically when you use the "update" command for the idl. + So don't modify the contents of the file, or your code will be deleted when it is updated. +*/ + +// Register register routes based on the IDL 'api.${HTTP Method}' annotation. +func Register(r *server.Hertz) { + + root := r.Group("/", rootMw()...) + root.GET("/admin", append(_adminMw(), user.Admin)...) + root.GET("/disable", append(_disableMw(), user.Disable)...) + root.GET("/login", append(_loginMw(), user.Login)...) + root.GET("/manager", append(_managerMw(), user.Manager)...) + root.GET("/public", append(_publicMw(), user.Public)...) + root.GET("/sensitive", append(_sensitiveMw(), user.Sensitive)...) + root.GET("/user", append(_userinfoMw(), user.UserInfo)...) +} diff --git a/examples/hertz/herz-example/build.sh b/examples/hertz/herz-example/build.sh new file mode 100755 index 0000000..f1ba589 --- /dev/null +++ b/examples/hertz/herz-example/build.sh @@ -0,0 +1,6 @@ +#!/bin/bash +RUN_NAME=hertz_service +mkdir -p output/bin +cp script/* output 2>/dev/null +chmod +x output/bootstrap.sh +go build -o output/bin/${RUN_NAME} \ No newline at end of file diff --git a/examples/hertz/herz-example/go.mod b/examples/hertz/herz-example/go.mod new file mode 100644 index 0000000..809fbba --- /dev/null +++ b/examples/hertz/herz-example/go.mod @@ -0,0 +1,28 @@ +module github.com/click33/sa-token-go/examples/hertz/herz-example + +go 1.25.4 + +require github.com/cloudwego/hertz v0.10.3 + +require ( + github.com/apache/thrift v0.22.0 // indirect + github.com/bytedance/gopkg v0.1.1 // indirect + github.com/bytedance/sonic v1.14.0 // indirect + github.com/bytedance/sonic/loader v0.3.0 // indirect + github.com/cloudwego/base64x v0.1.5 // indirect + github.com/cloudwego/gopkg v0.1.4 // indirect + github.com/cloudwego/netpoll v0.7.0 // indirect + github.com/fsnotify/fsnotify v1.5.4 // indirect + github.com/golang/protobuf v1.5.0 // indirect + github.com/klauspost/cpuid/v2 v2.0.9 // indirect + github.com/nyaruka/phonenumbers v1.0.55 // indirect + github.com/tidwall/gjson v1.14.4 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect + golang.org/x/sys v0.24.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect +) + +replace github.com/apache/thrift => github.com/apache/thrift v0.13.0 diff --git a/examples/hertz/herz-example/go.sum b/examples/hertz/herz-example/go.sum new file mode 100644 index 0000000..3921167 --- /dev/null +++ b/examples/hertz/herz-example/go.sum @@ -0,0 +1,119 @@ +github.com/apache/thrift v0.22.0 h1:r7mTJdj51TMDe6RtcmNdQxgn9XcyfGDOzegMDRg47uc= +github.com/apache/thrift v0.22.0/go.mod h1:1e7J/O1Ae6ZQMTYdy9xa3w9k+XHWPfRvdPyJeynQ+/g= +github.com/bytedance/gopkg v0.1.1 h1:3azzgSkiaw79u24a+w9arfH8OfnQQ4MHUt9lJFREEaE= +github.com/bytedance/gopkg v0.1.1/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM= +github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ= +github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= +github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= +github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/gopkg v0.1.4 h1:EoQiCG4sTonTPHxOGE0VlQs+sQR+Hsi2uN0qqwu8O50= +github.com/cloudwego/gopkg v0.1.4/go.mod h1:FQuXsRWRsSqJLsMVd5SYzp8/Z1y5gXKnVvRrWUOsCMI= +github.com/cloudwego/hertz v0.10.3 h1:NFcQAjouVJsod79XPLC/PaFfHgjMTYbiErmW+vGBi8A= +github.com/cloudwego/hertz v0.10.3/go.mod h1:W5dUFXZPZkyfjMMo3EQrMQbofuvTsctM9IxmhbkuT18= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/cloudwego/netpoll v0.7.0 h1:bDrxQaNfijRI1zyGgXHQoE/nYegL0nr+ijO1Norelc4= +github.com/cloudwego/netpoll v0.7.0/go.mod h1:PI+YrmyS7cIr0+SD4seJz3Eo3ckkXdu2ZVKBLhURLNU= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/nyaruka/phonenumbers v1.0.55 h1:bj0nTO88Y68KeUQ/n3Lo2KgK7lM1hF7L9NFuwcCl3yg= +github.com/nyaruka/phonenumbers v1.0.55/go.mod h1:sDaTZ/KPX5f8qyV9qN+hIm+4ZBARJrupC6LuhshJq1U= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= +github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= diff --git a/examples/hertz/herz-example/idl/user.thrift b/examples/hertz/herz-example/idl/user.thrift new file mode 100644 index 0000000..9559c23 --- /dev/null +++ b/examples/hertz/herz-example/idl/user.thrift @@ -0,0 +1,33 @@ +namespace go user + +struct LoginReq { + 1: string userId (api.query="userId"); +} + +struct LoginResp { + 1: string token; +} + +struct MessageResp { + 1: string message; +} + +struct UserInfoResp { + 1: string loginId; + 2: list roles; + 3: list permissions; +} + +struct SensitiveResp { + 1: bool sensitive; +} + +service UserService { + LoginResp Login(1: LoginReq request) (api.get="/login"); + MessageResp Public() (api.get="/public"); + UserInfoResp UserInfo() (api.get="/user"); + MessageResp Admin() (api.get="/admin"); + MessageResp Manager() (api.get="/manager"); + MessageResp Disable() (api.get="/disable"); + SensitiveResp Sensitive() (api.get="/sensitive"); +} \ No newline at end of file diff --git a/examples/hertz/herz-example/main.go b/examples/hertz/herz-example/main.go new file mode 100644 index 0000000..8eeb809 --- /dev/null +++ b/examples/hertz/herz-example/main.go @@ -0,0 +1,22 @@ +// Code generated by hertz generator. + +package main + +import ( + sahertz "github.com/click33/sa-token-go/integrations/hertz" // 只需这一个导入! + "github.com/click33/sa-token-go/storage/memory" + "github.com/cloudwego/hertz/pkg/app/server" +) + +func main() { + // 初始化(所有功能都在 sahertz 包中) + storage := memory.NewStorage() + config := sahertz.DefaultConfig() // 使用 sahertz.DefaultConfig + manager := sahertz.NewManager(storage, config) // 使用 sahertz.NewManager + sahertz.SetManager(manager) // 使用 sahertz.SetManager + + h := server.Default() + + register(h) + h.Spin() +} diff --git a/examples/hertz/herz-example/router.go b/examples/hertz/herz-example/router.go new file mode 100644 index 0000000..3b89cc7 --- /dev/null +++ b/examples/hertz/herz-example/router.go @@ -0,0 +1,14 @@ +// Code generated by hertz generator. + +package main + +import ( + "github.com/cloudwego/hertz/pkg/app/server" +) + +// customizeRegister registers customize routers. +func customizedRegister(r *server.Hertz) { + //r.GET("/ping", handler.Ping) + + // your code ... +} diff --git a/examples/hertz/herz-example/router_gen.go b/examples/hertz/herz-example/router_gen.go new file mode 100644 index 0000000..83a8d0c --- /dev/null +++ b/examples/hertz/herz-example/router_gen.go @@ -0,0 +1,16 @@ +// Code generated by hertz generator. DO NOT EDIT. + +package main + +import ( + router "github.com/click33/sa-token-go/examples/hertz/herz-example/biz/router" + "github.com/cloudwego/hertz/pkg/app/server" +) + +// register registers all routers. +func register(r *server.Hertz) { + + router.GeneratedRegister(r) + + customizedRegister(r) +} diff --git a/examples/hertz/herz-example/script/bootstrap.sh b/examples/hertz/herz-example/script/bootstrap.sh new file mode 100755 index 0000000..3f3fc1a --- /dev/null +++ b/examples/hertz/herz-example/script/bootstrap.sh @@ -0,0 +1,5 @@ +#!/bin/bash +CURDIR=$(cd $(dirname $0); pwd) +BinaryName=hertz_service +echo "$CURDIR/bin/${BinaryName}" +exec $CURDIR/bin/${BinaryName} \ No newline at end of file diff --git a/go.work b/go.work index e35b085..b8789bc 100644 --- a/go.work +++ b/go.work @@ -1,7 +1,8 @@ -go 1.25.3 +go 1.25.4 use ( ./core + ./examples/hertz/herz-example ./examples/kratos/kratos-example ./examples/multi-certification ./integrations/chi @@ -9,6 +10,7 @@ use ( ./integrations/fiber ./integrations/gf ./integrations/gin + ./integrations/hertz ./integrations/kratos ./storage/memory ./storage/redis diff --git a/go.work.sum b/go.work.sum index b77dd20..3b442f2 100644 --- a/go.work.sum +++ b/go.work.sum @@ -12,10 +12,11 @@ github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2 github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 h1:3c8yed4lgqTt+oTQ+JNMDo+F4xprBf+O/il4ZC0nRLw= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0/go.mod h1:obipzmGjfSjam60XLwGfqUkJsfiheAl+TUjG+4yzyPM= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/apache/thrift v0.13.0 h1:5hryIiq9gtn+MiLVn0wP37kb/uTeRZgN08WoCsAhIhI= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= -github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -23,9 +24,7 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= github.com/click33/sa-token-go/storage/memory v0.1.4/go.mod h1:nqyuEh23mNjcuG3aI/BqJFz71zkpsgjdStW1BC5lkB0= github.com/click33/sa-token-go/storage/memory v0.1.5/go.mod h1:HxN2NVLq7lx+sOmq5RmV0h8xJjEUJLm4Xt1Mq+9PV2s= -github.com/click33/sa-token-go/storage/memory v0.1.6/go.mod h1:YNojcgyLC/uFrmReZLePCDQ5WK2fo2WWGRjRMvXVH74= github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= -github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe h1:QQ3GSy+MqSHxm/d8nCtnAiZdYFd45cYZPs8vOOIYKfk= github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101 h1:7To3pQ+pZo0i3dsWEbinPNFs5gPSBOsJtx3wTT94VBY= @@ -33,9 +32,6 @@ github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3 h1:boJj011Hh+874zpIySeApCX4GeOjPl9qhRF3QuIZq+Q= github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.11.2-0.20230627204322-7d0032219fcb h1:kxNVXsNro/lpR5WD+P1FI/yUHn2G03Glber3k8cQL2Y= @@ -77,9 +73,6 @@ github.com/golang/glog v1.2.4 h1:CNNw5U8lSiiBk7druxtSHHTsRWcxKoac6kZKm2peBBc= github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -89,14 +82,10 @@ github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSAS github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/knz/go-libedit v1.10.1 h1:0pHpWtx9vcvC0xGZqEQlQdfSQs7WRlAjuPvk3fOZDCo= -github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/labstack/echo/v4 v4.11.4/go.mod h1:noh7EvLwqDsmh/X/HWKPUl1AjzJrhyptRyEbQJfxen8= github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= @@ -125,8 +114,6 @@ github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgc github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b h1:0LFwY6Q3gMACTjAbMZBjXAqTOzOwFaj2Ld6cjeQ7Rig= github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= @@ -142,26 +129,13 @@ github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFt github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0= github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw= github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= -github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/twmb/murmur3 v1.1.6 h1:mqrRot1BRxm+Yct+vavLMou2/iJt0tNVTTC0QoIjaZg= github.com/twmb/murmur3 v1.1.6/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= @@ -170,7 +144,6 @@ github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdI github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= @@ -189,11 +162,9 @@ go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42s go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg= golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ= golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= @@ -206,8 +177,8 @@ golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= @@ -222,11 +193,8 @@ golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0= golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20231212172506-995d672761c0 h1:YJ5pD9rF8o9Qtta0Cmy9rdBwkSjrTCT6XTiUQVOtIos= @@ -238,12 +206,9 @@ google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba/go. google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50= google.golang.org/genproto/googleapis/rpc v0.0.0-20251103181224-f26f9409b101/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= nullprogram.com/x/optparse v1.0.0 h1:xGFgVi5ZaWOnYdac2foDT3vg0ZZC9ErXFV57mr4OHrI= -nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/integrations/hertz/annotation.go b/integrations/hertz/annotation.go new file mode 100644 index 0000000..0283554 --- /dev/null +++ b/integrations/hertz/annotation.go @@ -0,0 +1,365 @@ +package hertz + +import ( + "context" + "fmt" + "reflect" + "strings" + + "github.com/click33/sa-token-go/core" + "github.com/click33/sa-token-go/stputil" + "github.com/cloudwego/hertz/pkg/app" +) + +// Annotation constants | 注解常量 +const ( + TagSaCheckLogin = "sa_check_login" + TagSaCheckRole = "sa_check_role" + TagSaCheckPermission = "sa_check_permission" + TagSaCheckDisable = "sa_check_disable" + TagSaIgnore = "sa_ignore" +) + +// Annotation annotation structure | 注解结构体 +type Annotation struct { + CheckLogin bool `json:"checkLogin"` + CheckRole []string `json:"checkRole"` + CheckPermission []string `json:"checkPermission"` + CheckDisable bool `json:"checkDisable"` + Ignore bool `json:"ignore"` +} + +// ParseTag parses struct tags | 解析结构体标签 +func ParseTag(tag string) *Annotation { + ann := &Annotation{} + + if tag == "" { + return ann + } + + parts := strings.Split(tag, ",") + for _, part := range parts { + part = strings.TrimSpace(part) + switch { + case part == TagSaCheckLogin || part == "login": + ann.CheckLogin = true + case strings.HasPrefix(part, TagSaCheckRole+"=") || strings.HasPrefix(part, "role="): + roles := strings.TrimPrefix(part, TagSaCheckRole+"=") + roles = strings.TrimPrefix(roles, "role=") + if roles != "" { + ann.CheckRole = strings.Split(roles, "|") + } + case strings.HasPrefix(part, TagSaCheckPermission+"=") || strings.HasPrefix(part, "permission="): + perms := strings.TrimPrefix(part, TagSaCheckPermission+"=") + perms = strings.TrimPrefix(perms, "permission=") + if perms != "" { + ann.CheckPermission = strings.Split(perms, "|") + } + case part == TagSaCheckDisable || part == "disable": + ann.CheckDisable = true + case part == TagSaIgnore || part == "ignore": + ann.Ignore = true + } + } + + return ann +} + +// Validate validates if annotation is valid | 验证注解是否有效 +func (a *Annotation) Validate() bool { + if a.Ignore { + return true // When ignore is true, other checks are invalid | 忽略认证时,其他检查无效 + } + + count := 0 + if a.CheckLogin { + count++ + } + if len(a.CheckRole) > 0 { + count++ + } + if len(a.CheckPermission) > 0 { + count++ + } + if a.CheckDisable { + count++ + } + + // At most one check type allowed | 最多只能有一个检查类型 + return count <= 1 +} + +// GetHandler gets handler with annotations | 获取带注解的处理器 +func GetHandler(handler interface{}, annotations ...*Annotation) app.HandlerFunc { + return func(ctx context.Context, c *app.RequestContext) { + if len(annotations) > 0 && annotations[0].Ignore { + if callHandler(handler, ctx, c) { + return + } + c.Next(ctx) + return + } + + hCtx := NewHertzContext(c) + saCtx := core.NewContext(hCtx, stputil.GetManager()) + token := saCtx.GetTokenValue() + + fmt.Printf("Debug Handler: token='%s', isLogin=%v, headers=%v\n", token, stputil.IsLogin(token), c.Request.Header.String()) + + if token == "" { + writeErrorResponse(c, core.NewNotLoginError()) + c.Abort() + return + } + + if !stputil.IsLogin(token) { + writeErrorResponse(c, core.NewNotLoginError()) + c.Abort() + return + } + + loginID, err := stputil.GetLoginID(token) + if err != nil { + writeErrorResponse(c, err) + c.Abort() + return + } + + // Check if account is disabled | 检查是否被封禁 + if len(annotations) > 0 && annotations[0].CheckDisable { + if stputil.IsDisable(loginID) { + writeErrorResponse(c, core.NewAccountDisabledError(loginID)) + c.Abort() + return + } + } + + // Check permission | 检查权限 + if len(annotations) > 0 && len(annotations[0].CheckPermission) > 0 { + hasPermission := false + for _, perm := range annotations[0].CheckPermission { + if stputil.HasPermission(loginID, strings.TrimSpace(perm)) { + hasPermission = true + break + } + } + if !hasPermission { + writeErrorResponse(c, core.NewPermissionDeniedError(strings.Join(annotations[0].CheckPermission, ","))) + c.Abort() + return + } + } + + // Check role | 检查角色 + if len(annotations) > 0 && len(annotations[0].CheckRole) > 0 { + hasRole := false + for _, role := range annotations[0].CheckRole { + if stputil.HasRole(loginID, strings.TrimSpace(role)) { + hasRole = true + break + } + } + if !hasRole { + writeErrorResponse(c, core.NewRoleDeniedError(strings.Join(annotations[0].CheckRole, ","))) + c.Abort() + return + } + } + + // All checks passed, execute original handler or continue | 所有检查通过,执行原函数或继续 + if callHandler(handler, ctx, c) { + return + } + c.Next(ctx) + } +} + +func callHandler(handler interface{}, ctx context.Context, c *app.RequestContext) bool { + if handler == nil { + return false + } + + switch h := handler.(type) { + case func(*app.RequestContext): + if h == nil { + return false + } + h(c) + return true + case app.HandlerFunc: + if h == nil { + return false + } + h(ctx, c) + return true + } + + hv := reflect.ValueOf(handler) + if hv.Kind() != reflect.Func || hv.IsNil() || hv.Type().NumIn() != 1 { + return false + } + + argType := hv.Type().In(0) + if !argType.AssignableTo(reflect.TypeOf(c)) { + return false + } + + hv.Call([]reflect.Value{reflect.ValueOf(c)}) + return true +} + +// Decorator functions | 装饰器函数 + +// CheckLogin decorator for login checking | 检查登录装饰器 +func CheckLogin() app.HandlerFunc { + return GetHandler(nil, &Annotation{CheckLogin: true}) +} + +// CheckRole decorator for role checking | 检查角色装饰器 +func CheckRole(roles ...string) app.HandlerFunc { + return GetHandler(nil, &Annotation{CheckRole: roles}) +} + +// CheckPermission decorator for permission checking | 检查权限装饰器 +func CheckPermission(perms ...string) app.HandlerFunc { + return GetHandler(nil, &Annotation{CheckPermission: perms}) +} + +// CheckDisable decorator for checking if account is disabled | 检查是否被封禁装饰器 +func CheckDisable() app.HandlerFunc { + return GetHandler(nil, &Annotation{CheckDisable: true}) +} + +// Ignore decorator to ignore authentication | 忽略认证装饰器 +func Ignore() app.HandlerFunc { + return GetHandler(nil, &Annotation{Ignore: true}) +} + +// WithAnnotation decorator with custom annotation | 使用自定义注解装饰器 +func WithAnnotation(ann *Annotation) app.HandlerFunc { + return GetHandler(nil, ann) +} + +// ProcessStructAnnotations processes annotations on struct tags | 处理结构体上的注解标签 +func ProcessStructAnnotations(handler interface{}) app.HandlerFunc { + handlerValue := reflect.ValueOf(handler) + handlerType := reflect.TypeOf(handler) + + // Find method name, usually the last path segment | 查找方法名,通常是最后一个路径段 + methodName := "unknown" + if handlerType.Kind() == reflect.Ptr { + handlerType = handlerType.Elem() + } + if handlerType.Kind() == reflect.Struct { + methodName = handlerType.Name() + } + + // Parse method annotations | 解析方法上的注解标签 + ann := parseMethodAnnotation(handlerType, methodName) + + return GetHandler(func(c *app.RequestContext) { + handlerValue.MethodByName("ServeHTTP").Call([]reflect.Value{reflect.ValueOf(c)}) + }, ann) +} + +// parseMethodAnnotation parses method annotations | 解析方法注解 +func parseMethodAnnotation(t reflect.Type, methodName string) *Annotation { + // Simplified implementation, returns empty annotation | 简化实现,直接返回空注解 + return &Annotation{} +} + +// HandlerWithAnnotations 带注解的处理器包装器 +type HandlerWithAnnotations struct { + Handler interface{} + Annotations []*Annotation +} + +// NewHandlerWithAnnotations 创建带注解的处理器 +func NewHandlerWithAnnotations(handler interface{}, annotations ...*Annotation) *HandlerWithAnnotations { + return &HandlerWithAnnotations{ + Handler: handler, + Annotations: annotations, + } +} + +// ToGinHandler 转换为Gin处理器 +func (h *HandlerWithAnnotations) ToGinHandler() app.HandlerFunc { + return GetHandler(h.Handler, h.Annotations...) +} + +// Middleware 创建中间件版本 +func Middleware(annotations ...*Annotation) app.HandlerFunc { + return func(ctx context.Context, c *app.RequestContext) { + if len(annotations) > 0 && annotations[0].Ignore { + c.Next(ctx) + return + } + + hCtx := NewHertzContext(c) + saCtx := core.NewContext(hCtx, stputil.GetManager()) + token := saCtx.GetTokenValue() + + if token == "" { + writeErrorResponse(c, core.NewNotLoginError()) + c.Abort() + return + } + + if !stputil.IsLogin(token) { + writeErrorResponse(c, core.NewNotLoginError()) + c.Abort() + return + } + + loginID, err := stputil.GetLoginID(token) + if err != nil { + writeErrorResponse(c, err) + c.Abort() + return + } + + // 检查是否被封禁 + if len(annotations) > 0 && annotations[0].CheckDisable { + if stputil.IsDisable(loginID) { + writeErrorResponse(c, core.NewAccountDisabledError(loginID)) + c.Abort() + return + } + } + + // 检查权限 + if len(annotations) > 0 && len(annotations[0].CheckPermission) > 0 { + hasPermission := false + for _, perm := range annotations[0].CheckPermission { + if stputil.HasPermission(loginID, strings.TrimSpace(perm)) { + hasPermission = true + break + } + } + if !hasPermission { + writeErrorResponse(c, core.NewPermissionDeniedError(strings.Join(annotations[0].CheckPermission, ","))) + c.Abort() + return + } + } + + // 检查角色 + if len(annotations) > 0 && len(annotations[0].CheckRole) > 0 { + hasRole := false + for _, role := range annotations[0].CheckRole { + if stputil.HasRole(loginID, strings.TrimSpace(role)) { + hasRole = true + break + } + } + if !hasRole { + writeErrorResponse(c, core.NewRoleDeniedError(strings.Join(annotations[0].CheckRole, ","))) + c.Abort() + return + } + } + + // 所有检查通过,继续下一个处理器 + c.Next(ctx) + } +} diff --git a/integrations/hertz/annotation_test.go b/integrations/hertz/annotation_test.go new file mode 100644 index 0000000..4a976e3 --- /dev/null +++ b/integrations/hertz/annotation_test.go @@ -0,0 +1,459 @@ +package hertz + +import ( + "context" + "fmt" + "net/http" + "testing" + + "github.com/click33/sa-token-go/core/config" + "github.com/click33/sa-token-go/core/manager" + "github.com/click33/sa-token-go/storage/memory" + "github.com/click33/sa-token-go/stputil" + "github.com/cloudwego/hertz/pkg/app" + "github.com/cloudwego/hertz/pkg/app/server" + "github.com/cloudwego/hertz/pkg/common/ut" + "github.com/cloudwego/hertz/pkg/common/utils" + "github.com/stretchr/testify/assert" +) + +// setupTestRouter 创建测试路由器和初始化 sa-token +func setupTestRouter() *server.Hertz { + router := server.Default() + + // 创建内存存储 + storage := memory.NewStorage() + + // 创建配置 + cfg := &config.Config{ + TokenName: "satoken", + Timeout: 2592000, // 30 天(秒) + IsConcurrent: true, + IsShare: true, + MaxLoginCount: -1, + } + + // 创建并设置全局 Manager + mgr := manager.NewManager(storage, cfg) + stputil.SetManager(mgr) + + return router +} + +// mockLogin 模拟用户登录并返回 token +func mockLogin(loginID interface{}) string { + token, _ := stputil.Login(loginID) + return token +} + +// mockLoginWithRole 模拟用户登录并设置角色 +func mockLoginWithRole(loginID interface{}, roles []string) string { + token, _ := stputil.Login(loginID) + stputil.SetRoles(loginID, roles) + return token +} + +// mockLoginWithPermission 模拟用户登录并设置权限 +func mockLoginWithPermission(loginID interface{}, permissions []string) string { + token, _ := stputil.Login(loginID) + stputil.SetPermissions(loginID, permissions) + return token +} + +// TestCheckRole_WithValidRole 测试具有有效角色的用户访问 +func TestCheckRole_WithValidRole(t *testing.T) { + router := setupTestRouter() + + // 设置路由 - 使用 CheckRole 作为中间件 + router.GET("/admin", CheckRole("Admin"), func(ctx context.Context, c *app.RequestContext) { + c.JSON(http.StatusOK, utils.H{"message": "success"}) + }) + + // 创建一个具有 Admin 角色的用户 + token := mockLoginWithRole("user123", []string{"Admin"}) + fmt.Println("Debug: Token generated:", token) + loginID, _ := stputil.GetLoginID(token) + fmt.Println("Debug: LoginID from storage:", loginID) + + // 发送请求 + w := ut.PerformRequest(router.Engine, "GET", "/admin", nil, + ut.Header{Key: "Authorization", Value: token}) + + // 断言 + assert.Equal(t, http.StatusOK, w.Code) + assert.Contains(t, w.Body.String(), "success") +} + +// TestCheckRole_WithInvalidRole 测试没有所需角色的用户访问 +func TestCheckRole_WithInvalidRole(t *testing.T) { + router := setupTestRouter() + + // 设置路由 + router.GET("/admin", CheckRole("Admin"), func(ctx context.Context, c *app.RequestContext) { + c.JSON(http.StatusOK, utils.H{"message": "success"}) + }) + + // 创建一个只有 User 角色的用户 + token := mockLoginWithRole("user456", []string{"User"}) + + // 发送请求 + w := ut.PerformRequest(router.Engine, "GET", "/admin", nil, + ut.Header{Key: "Authorization", Value: token}) + + // 断言 + assert.Equal(t, http.StatusForbidden, w.Code) + assert.Contains(t, w.Body.String(), "角色不足") +} + +// TestCheckRole_MultipleRoles 测试多个角色的情况(OR 逻辑) +func TestCheckRole_MultipleRoles(t *testing.T) { + router := setupTestRouter() + + // 设置路由 - 需要 Admin 或 SuperAdmin 角色 + router.GET("/manage", CheckRole("Admin", "SuperAdmin"), func(ctx context.Context, c *app.RequestContext) { + c.JSON(http.StatusOK, utils.H{"message": "success"}) + }) + + // 测试具有 SuperAdmin 角色的用户 + token := mockLoginWithRole("superuser", []string{"SuperAdmin"}) + + w := ut.PerformRequest(router.Engine, "GET", "/manage", nil, + ut.Header{Key: "Authorization", Value: token}) + + assert.Equal(t, http.StatusOK, w.Code) + assert.Contains(t, w.Body.String(), "success") +} + +// TestCheckRole_NoToken 测试未提供 token 的情况 +func TestCheckRole_NoToken(t *testing.T) { + router := setupTestRouter() + + router.GET("/admin", CheckRole("Admin"), func(ctx context.Context, c *app.RequestContext) { + c.JSON(http.StatusOK, utils.H{"message": "success"}) + }) + + w := ut.PerformRequest(router.Engine, "GET", "/admin", nil) + + assert.Equal(t, http.StatusUnauthorized, w.Code) + assert.Contains(t, w.Body.String(), "未登录") +} + +// TestCheckRole_InvalidToken 测试无效 token 的情况 +func TestCheckRole_InvalidToken(t *testing.T) { + router := setupTestRouter() + + router.GET("/admin", CheckRole("Admin"), func(ctx context.Context, c *app.RequestContext) { + c.JSON(http.StatusOK, utils.H{"message": "success"}) + }) + + w := ut.PerformRequest(router.Engine, "GET", "/admin", nil, + ut.Header{Key: "Authorization", Value: "invalid-token-12345"}) + + assert.Equal(t, http.StatusUnauthorized, w.Code) + assert.Contains(t, w.Body.String(), "未登录") +} + +// TestCheckPermission_WithValidPermission 测试具有有效权限的用户访问 +func TestCheckPermission_WithValidPermission(t *testing.T) { + router := setupTestRouter() + + router.GET("/users", CheckPermission("user.read"), func(ctx context.Context, c *app.RequestContext) { + c.JSON(http.StatusOK, utils.H{"message": "success"}) + }) + + token := mockLoginWithPermission("user789", []string{"user.read"}) + + w := ut.PerformRequest(router.Engine, "GET", "/users", nil, + ut.Header{Key: "Authorization", Value: token}) + + assert.Equal(t, http.StatusOK, w.Code) + assert.Contains(t, w.Body.String(), "success") +} + +// TestCheckPermission_WithInvalidPermission 测试没有所需权限的用户访问 +func TestCheckPermission_WithInvalidPermission(t *testing.T) { + router := setupTestRouter() + + router.GET("/users", CheckPermission("user.delete"), func(ctx context.Context, c *app.RequestContext) { + c.JSON(http.StatusOK, utils.H{"message": "success"}) + }) + + token := mockLoginWithPermission("user789", []string{"user.read"}) + + w := ut.PerformRequest(router.Engine, "GET", "/users", nil, + ut.Header{Key: "Authorization", Value: token}) + + assert.Equal(t, http.StatusForbidden, w.Code) + assert.Contains(t, w.Body.String(), "权限不足") +} + +// TestCheckLogin_Success 测试登录检查成功 +func TestCheckLogin_Success(t *testing.T) { + router := setupTestRouter() + + router.GET("/profile", CheckLogin(), func(ctx context.Context, c *app.RequestContext) { + c.JSON(http.StatusOK, utils.H{"message": "profile data"}) + }) + + token := mockLogin("user999") + + w := ut.PerformRequest(router.Engine, "GET", "/profile", nil, + ut.Header{Key: "Authorization", Value: token}) + + assert.Equal(t, http.StatusOK, w.Code) + assert.Contains(t, w.Body.String(), "profile data") +} + +// TestCheckLogin_Failed 测试登录检查失败 +func TestCheckLogin_Failed(t *testing.T) { + router := setupTestRouter() + + router.GET("/profile", CheckLogin(), func(ctx context.Context, c *app.RequestContext) { + c.JSON(http.StatusOK, utils.H{"message": "profile data"}) + }) + + w := ut.PerformRequest(router.Engine, "GET", "/profile", nil) + + assert.Equal(t, http.StatusUnauthorized, w.Code) + assert.Contains(t, w.Body.String(), "未登录") +} + +// TestCheckDisable_NotDisabled 测试账号未被封禁的情况 +func TestCheckDisable_NotDisabled(t *testing.T) { + router := setupTestRouter() + + router.GET("/resource", CheckDisable(), func(ctx context.Context, c *app.RequestContext) { + c.JSON(http.StatusOK, utils.H{"message": "resource data"}) + }) + + token := mockLogin("user101") + + w := ut.PerformRequest(router.Engine, "GET", "/resource", nil, + ut.Header{Key: "Authorization", Value: token}) + + assert.Equal(t, http.StatusOK, w.Code) + assert.Contains(t, w.Body.String(), "resource data") +} + +// TestCheckDisable_IsDisabled 测试账号被封禁的情况 +func TestCheckDisable_IsDisabled(t *testing.T) { + router := setupTestRouter() + + router.GET("/resource", CheckDisable(), func(ctx context.Context, c *app.RequestContext) { + c.JSON(http.StatusOK, utils.H{"message": "resource data"}) + }) + + loginID := "user102" + token := mockLogin(loginID) + + // 封禁账号 + stputil.Disable(loginID, 3600) // 封禁 1 小时 + + w := ut.PerformRequest(router.Engine, "GET", "/resource", nil, + ut.Header{Key: "Authorization", Value: token}) + + assert.Equal(t, http.StatusForbidden, w.Code) + assert.Contains(t, w.Body.String(), "账号已被封禁") +} + +// TestIgnore_SkipsAuthentication 测试忽略认证装饰器 +func TestIgnore_SkipsAuthentication(t *testing.T) { + router := setupTestRouter() + + router.GET("/public", Ignore(), func(ctx context.Context, c *app.RequestContext) { + c.JSON(http.StatusOK, utils.H{"message": "public data"}) + }) + + w := ut.PerformRequest(router.Engine, "GET", "/public", nil) + + assert.Equal(t, http.StatusOK, w.Code) + assert.Contains(t, w.Body.String(), "public data") +} + +// TestChainedMiddleware_CheckRoleAndHandler 测试链式中间件:CheckRole + 实际处理器 +func TestChainedMiddleware_CheckRoleAndHandler(t *testing.T) { + router := setupTestRouter() + + // 模拟用户示例代码的使用方式 + safeGroup := router.Group("/safe") + { + safeGroup.GET("", CheckRole("SuperAdmin"), func(ctx context.Context, c *app.RequestContext) { + c.JSON(http.StatusOK, utils.H{"message": "safe settings"}) + }) + } + + // 测试具有 SuperAdmin 角色的用户 + token := mockLoginWithRole("admin123", []string{"SuperAdmin"}) + + w := ut.PerformRequest(router.Engine, "GET", "/safe", nil, + ut.Header{Key: "Authorization", Value: token}) + + assert.Equal(t, http.StatusOK, w.Code) + assert.Contains(t, w.Body.String(), "safe settings") +} + +// TestChainedMiddleware_CheckRoleAndHandler_NoRole 测试链式中间件:无角色访问 +func TestChainedMiddleware_CheckRoleAndHandler_NoRole(t *testing.T) { + router := setupTestRouter() + + safeGroup := router.Group("/safe") + { + safeGroup.GET("", CheckRole("SuperAdmin"), func(ctx context.Context, c *app.RequestContext) { + c.JSON(http.StatusOK, utils.H{"message": "safe settings"}) + }) + } + + // 测试具有普通用户角色 + token := mockLoginWithRole("user123", []string{"User"}) + + w := ut.PerformRequest(router.Engine, "GET", "/safe", nil, + ut.Header{Key: "Authorization", Value: token}) + + assert.Equal(t, http.StatusForbidden, w.Code) + assert.Contains(t, w.Body.String(), "角色不足") +} + +// TestGetHandler_WithNilHandler 测试 GetHandler 在 handler 为 nil 时的行为 +func TestGetHandler_WithNilHandler(t *testing.T) { + router := setupTestRouter() + + // 直接使用 GetHandler 创建中间件 + middleware := GetHandler(nil, &Annotation{CheckRole: []string{"Admin"}}) + + router.GET("/test", middleware, func(ctx context.Context, c *app.RequestContext) { + c.JSON(http.StatusOK, utils.H{"message": "test passed"}) + }) + + token := mockLoginWithRole("testuser", []string{"Admin"}) + + w := ut.PerformRequest(router.Engine, "GET", "/test", nil, + ut.Header{Key: "Authorization", Value: token}) + + // 应该能够正常执行,不会 panic + assert.Equal(t, http.StatusOK, w.Code) + assert.Contains(t, w.Body.String(), "test passed") +} + +// TestMiddleware_CheckRole 测试 Middleware 函数的角色检查 +func TestMiddleware_CheckRole(t *testing.T) { + router := setupTestRouter() + + // 使用 Middleware 函数 + router.GET("/api/data", Middleware(&Annotation{CheckRole: []string{"Admin"}}), func(ctx context.Context, c *app.RequestContext) { + c.JSON(http.StatusOK, utils.H{"data": "sensitive data"}) + }) + + token := mockLoginWithRole("admin999", []string{"Admin"}) + + w := ut.PerformRequest(router.Engine, "GET", "/api/data", nil, + ut.Header{Key: "Authorization", Value: token}) + + assert.Equal(t, http.StatusOK, w.Code) + assert.Contains(t, w.Body.String(), "sensitive data") +} + +// TestParseTag 测试标签解析功能 +func TestParseTag(t *testing.T) { + tests := []struct { + name string + tag string + expected *Annotation + }{ + { + name: "解析登录检查标签", + tag: "sa_check_login", + expected: &Annotation{ + CheckLogin: true, + }, + }, + { + name: "解析角色检查标签", + tag: "sa_check_role=Admin|SuperAdmin", + expected: &Annotation{ + CheckRole: []string{"Admin", "SuperAdmin"}, + }, + }, + { + name: "解析权限检查标签", + tag: "sa_check_permission=user.read|user.write", + expected: &Annotation{ + CheckPermission: []string{"user.read", "user.write"}, + }, + }, + { + name: "解析忽略认证标签", + tag: "sa_ignore", + expected: &Annotation{ + Ignore: true, + }, + }, + { + name: "解析封禁检查标签", + tag: "sa_check_disable", + expected: &Annotation{ + CheckDisable: true, + }, + }, + { + name: "空标签", + tag: "", + expected: &Annotation{}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := ParseTag(tt.tag) + assert.Equal(t, tt.expected.CheckLogin, result.CheckLogin) + assert.Equal(t, tt.expected.CheckRole, result.CheckRole) + assert.Equal(t, tt.expected.CheckPermission, result.CheckPermission) + assert.Equal(t, tt.expected.CheckDisable, result.CheckDisable) + assert.Equal(t, tt.expected.Ignore, result.Ignore) + }) + } +} + +// TestAnnotationValidate 测试注解验证功能 +func TestAnnotationValidate(t *testing.T) { + tests := []struct { + name string + annotation *Annotation + valid bool + }{ + { + name: "有效的单一检查", + annotation: &Annotation{ + CheckLogin: true, + }, + valid: true, + }, + { + name: "有效的忽略标记", + annotation: &Annotation{ + Ignore: true, + CheckLogin: true, // 即使有其他标记,忽略时仍然有效 + }, + valid: true, + }, + { + name: "有效的空注解", + annotation: &Annotation{}, + valid: true, + }, + { + name: "无效的多重检查", + annotation: &Annotation{ + CheckLogin: true, + CheckRole: []string{"Admin"}, + }, + valid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := tt.annotation.Validate() + assert.Equal(t, tt.valid, result) + }) + } +} diff --git a/integrations/hertz/context.go b/integrations/hertz/context.go new file mode 100644 index 0000000..d9d2097 --- /dev/null +++ b/integrations/hertz/context.go @@ -0,0 +1,165 @@ +package hertz + +import ( + "github.com/click33/sa-token-go/core/adapter" + "github.com/cloudwego/hertz/pkg/app" + "github.com/cloudwego/hertz/pkg/protocol" +) + +// HertzContext Hertz request context adapter | Gin请求上下文适配器 +type HertzContext struct { + c *app.RequestContext + aborted bool +} + +// NewHertzContext creates a Hertz context adapter | 创建Hertz上下文适配器 +func NewHertzContext(c *app.RequestContext) adapter.RequestContext { + return &HertzContext{c: c} +} + +// GetHeader gets request header | 获取请求头 +func (h *HertzContext) GetHeader(key string) string { + return string(h.c.GetHeader(key)) +} + +// GetQuery gets query parameter | 获取查询参数 +func (h *HertzContext) GetQuery(key string) string { + return h.c.Query(key) +} + +// GetCookie gets cookie | 获取Cookie +func (h *HertzContext) GetCookie(key string) string { + cookie := h.c.Cookie(key) + return string(cookie) +} + +// SetHeader sets response header | 设置响应头 +func (h *HertzContext) SetHeader(key, value string) { + h.c.Header(key, value) +} + +// SetCookie sets cookie | 设置Cookie +func (h *HertzContext) SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool) { + h.c.SetCookie(name, value, maxAge, path, domain, protocol.CookieSameSiteLaxMode, secure, httpOnly) +} + +// GetClientIP gets client IP address | 获取客户端IP地址 +func (h *HertzContext) GetClientIP() string { + return h.c.ClientIP() +} + +// GetMethod gets request method | 获取请求方法 +func (h *HertzContext) GetMethod() string { + return string(h.c.Method()) +} + +// GetPath gets request path | 获取请求路径 +func (h *HertzContext) GetPath() string { + return string(h.c.Path()) +} + +// Set sets context value | 设置上下文值 +func (h *HertzContext) Set(key string, value interface{}) { + h.c.Set(key, value) +} + +// Get gets context value | 获取上下文值 +func (h *HertzContext) Get(key string) (interface{}, bool) { + return h.c.Get(key) +} + +// ============ Additional Required Methods | 额外必需的方法 ============ + +// GetHeaders implements adapter.RequestContext. +func (h *HertzContext) GetHeaders() map[string][]string { + headers := make(map[string][]string) + h.c.Request.Header.VisitAll(func(key, value []byte) { + headers[string(key)] = []string{string(value)} + }) + return headers +} + +// GetQueryAll implements adapter.RequestContext. +func (h *HertzContext) GetQueryAll() map[string][]string { + params := make(map[string][]string) + h.c.QueryArgs().VisitAll(func(key, value []byte) { + params[string(key)] = []string{string(value)} + }) + return params +} + +// GetPostForm implements adapter.RequestContext. +func (h *HertzContext) GetPostForm(key string) string { + return h.c.PostForm(key) +} + +// GetBody implements adapter.RequestContext. +func (h *HertzContext) GetBody() ([]byte, error) { + return h.c.GetRawData(), nil +} + +// GetURL implements adapter.RequestContext. +func (h *HertzContext) GetURL() string { + return string(h.c.Request.URI().RequestURI()) +} + +// GetUserAgent implements adapter.RequestContext. +func (h *HertzContext) GetUserAgent() string { + return string(h.c.UserAgent()) +} + +// SetCookieWithOptions implements adapter.RequestContext. +func (h *HertzContext) SetCookieWithOptions(options *adapter.CookieOptions) { + // Set SameSite attribute + var sameSite protocol.CookieSameSite + switch options.SameSite { + case "Strict": + sameSite = protocol.CookieSameSiteStrictMode + case "Lax": + sameSite = protocol.CookieSameSiteLaxMode + case "None": + sameSite = protocol.CookieSameSiteNoneMode + } + h.c.SetCookie( + options.Name, + options.Value, + options.MaxAge, + options.Path, + options.Domain, + sameSite, + options.Secure, + options.HttpOnly, + ) +} + +// GetString implements adapter.RequestContext. +func (h *HertzContext) GetString(key string) string { + value, exists := h.c.Get(key) + if !exists { + return "" + } + if str, ok := value.(string); ok { + return str + } + return "" +} + +// MustGet implements adapter.RequestContext. +func (h *HertzContext) MustGet(key string) any { + value, exists := h.c.Get(key) + if !exists { + panic("key not found: " + key) + } + return value +} + +// Abort implements adapter.RequestContext. +func (h *HertzContext) Abort() { + h.aborted = true + h.c.Abort() +} + +// IsAborted implements adapter.RequestContext. +func (h *HertzContext) IsAborted() bool { + return h.aborted +} diff --git a/integrations/hertz/export.go b/integrations/hertz/export.go new file mode 100644 index 0000000..ee2241a --- /dev/null +++ b/integrations/hertz/export.go @@ -0,0 +1,364 @@ +package hertz + +import ( + "time" + + "github.com/click33/sa-token-go/core" + "github.com/click33/sa-token-go/stputil" +) + +// ============ Re-export core types | 重新导出核心类型 ============ + +// Configuration related types | 配置相关类型 +type ( + Config = core.Config + CookieConfig = core.CookieConfig + TokenStyle = core.TokenStyle +) + +// Token style constants | Token风格常量 +const ( + TokenStyleUUID = core.TokenStyleUUID + TokenStyleSimple = core.TokenStyleSimple + TokenStyleRandom32 = core.TokenStyleRandom32 + TokenStyleRandom64 = core.TokenStyleRandom64 + TokenStyleRandom128 = core.TokenStyleRandom128 + TokenStyleJWT = core.TokenStyleJWT + TokenStyleHash = core.TokenStyleHash + TokenStyleTimestamp = core.TokenStyleTimestamp + TokenStyleTik = core.TokenStyleTik +) + +// Core types | 核心类型 +type ( + Manager = core.Manager + TokenInfo = core.TokenInfo + Session = core.Session + TokenGenerator = core.TokenGenerator + SaTokenContext = core.SaTokenContext + Builder = core.Builder + NonceManager = core.NonceManager + RefreshTokenInfo = core.RefreshTokenInfo + RefreshTokenManager = core.RefreshTokenManager + OAuth2Server = core.OAuth2Server + OAuth2Client = core.OAuth2Client + OAuth2AccessToken = core.OAuth2AccessToken + OAuth2GrantType = core.OAuth2GrantType +) + +// Adapter interfaces | 适配器接口 +type ( + Storage = core.Storage + RequestContext = core.RequestContext +) + +// Event related types | 事件相关类型 +type ( + EventListener = core.EventListener + EventManager = core.EventManager + EventData = core.EventData + Event = core.Event + ListenerFunc = core.ListenerFunc + ListenerConfig = core.ListenerConfig +) + +// Event constants | 事件常量 +const ( + EventLogin = core.EventLogin + EventLogout = core.EventLogout + EventKickout = core.EventKickout + EventDisable = core.EventDisable + EventUntie = core.EventUntie + EventRenew = core.EventRenew + EventCreateSession = core.EventCreateSession + EventDestroySession = core.EventDestroySession + EventPermissionCheck = core.EventPermissionCheck + EventRoleCheck = core.EventRoleCheck + EventAll = core.EventAll +) + +// OAuth2 grant type constants | OAuth2授权类型常量 +const ( + GrantTypeAuthorizationCode = core.GrantTypeAuthorizationCode + GrantTypeRefreshToken = core.GrantTypeRefreshToken + GrantTypeClientCredentials = core.GrantTypeClientCredentials + GrantTypePassword = core.GrantTypePassword +) + +// Utility functions | 工具函数 +var ( + RandomString = core.RandomString + IsEmpty = core.IsEmpty + IsNotEmpty = core.IsNotEmpty + DefaultString = core.DefaultString + ContainsString = core.ContainsString + RemoveString = core.RemoveString + UniqueStrings = core.UniqueStrings + MergeStrings = core.MergeStrings + MatchPattern = core.MatchPattern +) + +// ============ Core constructor functions | 核心构造函数 ============ + +// DefaultConfig returns default configuration | 返回默认配置 +func DefaultConfig() *Config { + return core.DefaultConfig() +} + +// NewManager creates a new authentication manager | 创建新的认证管理器 +func NewManager(storage Storage, cfg *Config) *Manager { + return core.NewManager(storage, cfg) +} + +// NewContext creates a new Sa-Token context | 创建新的Sa-Token上下文 +func NewContext(ctx RequestContext, mgr *Manager) *SaTokenContext { + return core.NewContext(ctx, mgr) +} + +// NewSession creates a new session | 创建新的Session +func NewSession(id string, storage Storage, prefix string) *Session { + return core.NewSession(id, storage, prefix) +} + +// LoadSession loads an existing session | 加载已存在的Session +func LoadSession(id string, storage Storage, prefix string) (*Session, error) { + return core.LoadSession(id, storage, prefix) +} + +// NewTokenGenerator creates a new token generator | 创建新的Token生成器 +func NewTokenGenerator(cfg *Config) *TokenGenerator { + return core.NewTokenGenerator(cfg) +} + +// NewEventManager creates a new event manager | 创建新的事件管理器 +func NewEventManager() *EventManager { + return core.NewEventManager() +} + +// NewBuilder creates a new builder for fluent configuration | 创建新的Builder构建器(用于流式配置) +func NewBuilder() *Builder { + return core.NewBuilder() +} + +// NewNonceManager creates a new nonce manager | 创建新的Nonce管理器 +func NewNonceManager(storage Storage, prefix string, ttl ...int64) *NonceManager { + return core.NewNonceManager(storage, prefix, ttl...) +} + +// NewRefreshTokenManager creates a new refresh token manager | 创建新的刷新令牌管理器 +func NewRefreshTokenManager(storage Storage, prefix string, cfg *Config) *RefreshTokenManager { + return core.NewRefreshTokenManager(storage, prefix, cfg) +} + +// NewOAuth2Server creates a new OAuth2 server | 创建新的OAuth2服务器 +func NewOAuth2Server(storage Storage, prefix string) *OAuth2Server { + return core.NewOAuth2Server(storage, prefix) +} + +// ============ Global StpUtil functions | 全局StpUtil函数 ============ + +// SetManager sets the global Manager (must be called first) | 设置全局Manager(必须先调用此方法) +func SetManager(mgr *Manager) { + stputil.SetManager(mgr) +} + +// GetManager gets the global Manager | 获取全局Manager +func GetManager() *Manager { + return stputil.GetManager() +} + +// ============ Authentication | 登录认证 ============ + +// Login performs user login | 用户登录 +func Login(loginID interface{}, device ...string) (string, error) { + return stputil.Login(loginID, device...) +} + +// LoginByToken performs login with specified token | 使用指定Token登录 +func LoginByToken(loginID interface{}, tokenValue string, device ...string) error { + return stputil.LoginByToken(loginID, tokenValue, device...) +} + +// Logout performs user logout | 用户登出 +func Logout(loginID interface{}, device ...string) error { + return stputil.Logout(loginID, device...) +} + +// LogoutByToken performs logout by token | 根据Token登出 +func LogoutByToken(tokenValue string) error { + return stputil.LogoutByToken(tokenValue) +} + +// IsLogin checks if the user is logged in | 检查用户是否已登录 +func IsLogin(tokenValue string) bool { + return stputil.IsLogin(tokenValue) +} + +// CheckLoginByToken checks login status (throws error if not logged in) | 检查登录状态(未登录抛出错误) +func CheckLoginByToken(tokenValue string) error { + return stputil.CheckLogin(tokenValue) +} + +// GetLoginID gets the login ID from token | 从Token获取登录ID +func GetLoginID(tokenValue string) (string, error) { + return stputil.GetLoginID(tokenValue) +} + +// GetLoginIDNotCheck gets login ID without checking | 获取登录ID(不检查) +func GetLoginIDNotCheck(tokenValue string) (string, error) { + return stputil.GetLoginIDNotCheck(tokenValue) +} + +// GetTokenValue gets the token value for a login ID | 获取登录ID对应的Token值 +func GetTokenValue(loginID interface{}, device ...string) (string, error) { + return stputil.GetTokenValue(loginID, device...) +} + +// GetTokenInfo gets token information | 获取Token信息 +func GetTokenInfo(tokenValue string) (*TokenInfo, error) { + return stputil.GetTokenInfo(tokenValue) +} + +// ============ Kickout | 踢人下线 ============ + +// Kickout kicks out a user session | 踢人下线 +func Kickout(loginID interface{}, device ...string) error { + return stputil.Kickout(loginID, device...) +} + +// ============ Account Disable | 账号封禁 ============ + +// Disable disables an account for specified duration | 封禁账号(指定时长) +func Disable(loginID interface{}, duration time.Duration) error { + return stputil.Disable(loginID, duration) +} + +// IsDisable checks if an account is disabled | 检查账号是否被封禁 +func IsDisable(loginID interface{}) bool { + return stputil.IsDisable(loginID) +} + +// CheckDisableByToken checks if account is disabled (throws error if disabled) | 检查Token对应账号是否被封禁(被封禁则抛出错误) +func CheckDisableByToken(tokenValue string) error { + return stputil.CheckDisable(tokenValue) +} + +// GetDisableTime gets remaining disabled time | 获取账号剩余封禁时间 +func GetDisableTime(loginID interface{}) (int64, error) { + return stputil.GetDisableTime(loginID) +} + +// Untie unties/unlocks an account | 解除账号封禁 +func Untie(loginID interface{}) error { + return stputil.Untie(loginID) +} + +// ============ Permission Check | 权限验证 ============ + +// CheckPermissionByToken checks if the token has specified permission | 检查Token是否拥有指定权限 +func CheckPermissionByToken(tokenValue string, permission string) error { + return stputil.CheckPermission(tokenValue, permission) +} + +// HasPermission checks if the account has specified permission (returns bool) | 检查账号是否拥有指定权限(返回布尔值) +func HasPermission(loginID interface{}, permission string) bool { + return stputil.HasPermission(loginID, permission) +} + +// CheckPermissionAndByToken checks if the token has all specified permissions (AND logic) | 检查Token是否拥有所有指定权限(AND逻辑) +func CheckPermissionAndByToken(tokenValue string, permissions []string) error { + return stputil.CheckPermissionAnd(tokenValue, permissions) +} + +// CheckPermissionOrByToken checks if the token has any of the specified permissions (OR logic) | 检查Token是否拥有指定权限中的任意一个(OR逻辑) +func CheckPermissionOrByToken(tokenValue string, permissions []string) error { + return stputil.CheckPermissionOr(tokenValue, permissions) +} + +// GetPermissionListByToken gets the permission list for a token | 获取Token的权限列表 +func GetPermissionListByToken(tokenValue string) ([]string, error) { + return stputil.GetPermissionList(tokenValue) +} + +// ============ Role Check | 角色验证 ============ + +// CheckRoleByToken checks if the token has specified role | 检查Token是否拥有指定角色 +func CheckRoleByToken(tokenValue string, role string) error { + return stputil.CheckRole(tokenValue, role) +} + +// HasRole checks if the account has specified role (returns bool) | 检查账号是否拥有指定角色(返回布尔值) +func HasRole(loginID interface{}, role string) bool { + return stputil.HasRole(loginID, role) +} + +// CheckRoleAndByToken checks if the token has all specified roles (AND logic) | 检查Token是否拥有所有指定角色(AND逻辑) +func CheckRoleAndByToken(tokenValue string, roles []string) error { + return stputil.CheckRoleAnd(tokenValue, roles) +} + +// CheckRoleOrByToken checks if the token has any of the specified roles (OR logic) | 检查Token是否拥有指定角色中的任意一个(OR逻辑) +func CheckRoleOrByToken(tokenValue string, roles []string) error { + return stputil.CheckRoleOr(tokenValue, roles) +} + +// GetRoleListByToken gets the role list for a token | 获取Token的角色列表 +func GetRoleListByToken(tokenValue string) ([]string, error) { + return stputil.GetRoleList(tokenValue) +} + +// ============ Session Management | Session管理 ============ + +// GetSession gets the session for a login ID | 获取登录ID的Session +func GetSession(loginID interface{}) (*Session, error) { + return stputil.GetSession(loginID) +} + +// GetSessionByToken gets the session by token | 根据Token获取Session +func GetSessionByToken(tokenValue string) (*Session, error) { + return stputil.GetSessionByToken(tokenValue) +} + +// GetTokenSession gets the token session | 获取Token的Session +func GetTokenSession(tokenValue string) (*Session, error) { + return stputil.GetTokenSession(tokenValue) +} + +// ============ Token Renewal | Token续期 ============ +// Note: Token auto-renewal is handled automatically by the manager +// 注意:Token自动续期由管理器自动处理 + +// ============ Security Features | 安全特性 ============ + +// GenerateNonce generates a new nonce token | 生成新的Nonce令牌 +func GenerateNonce() (string, error) { + return stputil.GenerateNonce() +} + +// VerifyNonce verifies a nonce token | 验证Nonce令牌 +func VerifyNonce(nonce string) bool { + return stputil.VerifyNonce(nonce) +} + +// LoginWithRefreshToken performs login and returns refresh token info | 登录并返回刷新令牌信息 +func LoginWithRefreshToken(loginID interface{}, device ...string) (*RefreshTokenInfo, error) { + return stputil.LoginWithRefreshToken(loginID, device...) +} + +// RefreshAccessToken refreshes the access token using a refresh token | 使用刷新令牌刷新访问令牌 +func RefreshAccessToken(refreshToken string) (*RefreshTokenInfo, error) { + return stputil.RefreshAccessToken(refreshToken) +} + +// RevokeRefreshToken revokes a refresh token | 撤销刷新令牌 +func RevokeRefreshToken(refreshToken string) error { + return stputil.RevokeRefreshToken(refreshToken) +} + +// GetOAuth2Server gets the OAuth2 server instance | 获取OAuth2服务器实例 +func GetOAuth2Server() *OAuth2Server { + return stputil.GetOAuth2Server() +} + +// Version Sa-Token-Go version | Sa-Token-Go版本 +const Version = core.Version diff --git a/integrations/hertz/go.mod b/integrations/hertz/go.mod new file mode 100644 index 0000000..557d36e --- /dev/null +++ b/integrations/hertz/go.mod @@ -0,0 +1,12 @@ +module github.com/click33/sa-token-go/integrations/hertz + +go 1.25 + +toolchain go1.24.1 + +require ( + github.com/click33/sa-token-go/core v0.1.7 // indirect + github.com/click33/sa-token-go/stputil v0.1.7 // indirect + github.com/cloudwego/hertz v0.10.3 // indirect + github.com/stretchr/testify v1.11.1 // indirect +) diff --git a/integrations/hertz/go.sum b/integrations/hertz/go.sum new file mode 100644 index 0000000..34b4104 --- /dev/null +++ b/integrations/hertz/go.sum @@ -0,0 +1,4 @@ +github.com/click33/sa-token-go/core v0.1.7/go.mod h1:mb3AQAJIXqx9WdULyn5qjufK1j/u+kgB0q+tafHVhgk= +github.com/click33/sa-token-go/stputil v0.1.7/go.mod h1:YY4NzfwVMwPUQLDBk9C5eVLQ08oI3vNSFQhBuZBPtgY= +github.com/cloudwego/hertz v0.10.3/go.mod h1:W5dUFXZPZkyfjMMo3EQrMQbofuvTsctM9IxmhbkuT18= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= diff --git a/integrations/hertz/plugin.go b/integrations/hertz/plugin.go new file mode 100644 index 0000000..6a9a55e --- /dev/null +++ b/integrations/hertz/plugin.go @@ -0,0 +1,287 @@ +package hertz + +import ( + "context" + "errors" + "net/http" + + "github.com/click33/sa-token-go/core" + "github.com/cloudwego/hertz/pkg/app" + "github.com/cloudwego/hertz/pkg/common/utils" + "github.com/cloudwego/hertz/pkg/protocol" +) + +// Plugin Hertz plugin for Sa-Token | Hertz插件 +type Plugin struct { + manager *core.Manager +} + +// NewPlugin creates a Hertz plugin | 创建Hertz插件 +func NewPlugin(manager *core.Manager) *Plugin { + return &Plugin{ + manager: manager, + } +} + +// AuthMiddleware authentication middleware | 认证中间件 +func (p *Plugin) AuthMiddleware() app.HandlerFunc { + return func(ctx context.Context, c *app.RequestContext) { + hCtx := NewHertzContext(c) + saCtx := core.NewContext(hCtx, p.manager) + + // Check login | 检查登录 + if err := saCtx.CheckLogin(); err != nil { + writeErrorResponse(c, err) + c.Abort() + return + } + + // Store Sa-Token context in Hertz context | 将Sa-Token上下文存储到Hertz上下文 + c.Set("satoken", saCtx) + c.Next(ctx) + } +} + +// PathAuthMiddleware path-based authentication middleware | 基于路径的鉴权中间件 +func (p *Plugin) PathAuthMiddleware(config *core.PathAuthConfig) app.HandlerFunc { + return func(ctx context.Context, c *app.RequestContext) { + path := string(c.Path()) + token := string(c.GetHeader(p.manager.GetConfig().TokenName)) + if token == "" { + token = string(c.Cookie(p.manager.GetConfig().TokenName)) + } + + result := core.ProcessAuth(path, token, config, p.manager) + + if result.ShouldReject() { + writeErrorResponse(c, core.NewPathAuthRequiredError(path)) + c.Abort() + return + } + + if result.IsValid && result.TokenInfo != nil { + hCtx := NewHertzContext(c) + saCtx := core.NewContext(hCtx, p.manager) + c.Set("satoken", saCtx) + c.Set("loginID", result.LoginID()) + } + + c.Next(ctx) + } +} + +// PermissionRequired permission validation middleware | 权限验证中间件 +func (p *Plugin) PermissionRequired(permission string) app.HandlerFunc { + return func(ctx context.Context, c *app.RequestContext) { + hCtx := NewHertzContext(c) + saCtx := core.NewContext(hCtx, p.manager) + + // Check login | 检查登录 + if err := saCtx.CheckLogin(); err != nil { + writeErrorResponse(c, err) + c.Abort() + return + } + + // Check permission | 检查权限 + if !saCtx.HasPermission(permission) { + writeErrorResponse(c, core.NewPermissionDeniedError(permission)) + c.Abort() + return + } + + c.Set("satoken", saCtx) + c.Next(ctx) + } +} + +// RoleRequired role validation middleware | 角色验证中间件 +func (p *Plugin) RoleRequired(role string) app.HandlerFunc { + return func(ctx context.Context, c *app.RequestContext) { + hCtx := NewHertzContext(c) + saCtx := core.NewContext(hCtx, p.manager) + + // Check login | 检查登录 + if err := saCtx.CheckLogin(); err != nil { + writeErrorResponse(c, err) + c.Abort() + return + } + + // Check role | 检查角色 + if !saCtx.HasRole(role) { + writeErrorResponse(c, core.NewRoleDeniedError(role)) + c.Abort() + return + } + + c.Set("satoken", saCtx) + c.Next(ctx) + } +} + +// LoginHandler login handler example | 登录处理器示例 +func (p *Plugin) LoginHandler(c *app.RequestContext) { + var req struct { + Username string `json:"username" binding:"required"` + Password string `json:"password" binding:"required"` + Device string `json:"device"` + } + + if err := c.BindJSON(&req); err != nil { + writeErrorResponse(c, core.NewError(core.CodeBadRequest, "invalid request parameters", err)) + return + } + + // Login | 登录 + device := req.Device + if device == "" { + device = "default" + } + + token, err := p.manager.Login(req.Username, device) + if err != nil { + writeErrorResponse(c, core.NewError(core.CodeServerError, "login failed", err)) + return + } + + // Set cookie (optional) | 设置Cookie(可选) + cfg := p.manager.GetConfig() + if cfg.IsReadCookie { + maxAge := int(cfg.Timeout) + if maxAge < 0 { + maxAge = 0 + } + var sameSite protocol.CookieSameSite + switch cfg.CookieConfig.SameSite { + case "Strict": + sameSite = protocol.CookieSameSiteStrictMode + case "Lax": + sameSite = protocol.CookieSameSiteLaxMode + case "None": + sameSite = protocol.CookieSameSiteNoneMode + } + c.SetCookie( + cfg.TokenName, + token, + maxAge, + cfg.CookieConfig.Path, + cfg.CookieConfig.Domain, + sameSite, + cfg.CookieConfig.Secure, + cfg.CookieConfig.HttpOnly, + ) + } + + writeSuccessResponse(c, utils.H{ + "token": token, + }) +} + +// LogoutHandler logout handler | 登出处理器 +func (p *Plugin) LogoutHandler(c *app.RequestContext) { + hCtx := NewHertzContext(c) + saCtx := core.NewContext(hCtx, p.manager) + + loginID, err := saCtx.GetLoginID() + if err != nil { + writeErrorResponse(c, err) + return + } + + if err := p.manager.Logout(loginID); err != nil { + writeErrorResponse(c, core.NewError(core.CodeServerError, "logout failed", err)) + return + } + + writeSuccessResponse(c, utils.H{ + "message": "logout successful", + }) +} + +// UserInfoHandler user info handler example | 获取用户信息处理器示例 +func (p *Plugin) UserInfoHandler(c *app.RequestContext) { + hCtx := NewHertzContext(c) + saCtx := core.NewContext(hCtx, p.manager) + + loginID, err := saCtx.GetLoginID() + if err != nil { + writeErrorResponse(c, err) + return + } + + // Get user permissions and roles | 获取用户权限和角色 + permissions, _ := p.manager.GetPermissions(loginID) + roles, _ := p.manager.GetRoles(loginID) + + writeSuccessResponse(c, utils.H{ + "loginId": loginID, + "permissions": permissions, + "roles": roles, + }) +} + +// GetSaToken gets Sa-Token context from Hertz context | 从Hertz上下文获取Sa-Token上下文 +func GetSaToken(c *app.RequestContext) (*core.SaTokenContext, bool) { + satoken, exists := c.Get("satoken") + if !exists { + return nil, false + } + ctx, ok := satoken.(*core.SaTokenContext) + return ctx, ok +} + +// ============ Error Handling Helpers | 错误处理辅助函数 ============ + +// writeErrorResponse writes a standardized error response | 写入标准化的错误响应 +func writeErrorResponse(c *app.RequestContext, err error) { + var saErr *core.SaTokenError + var code int + var message string + var httpStatus int + + // Check if it's a SaTokenError | 检查是否为SaTokenError + if errors.As(err, &saErr) { + code = saErr.Code + message = saErr.Message + httpStatus = getHTTPStatusFromCode(code) + } else { + // Handle standard errors | 处理标准错误 + code = core.CodeServerError + message = err.Error() + httpStatus = http.StatusInternalServerError + } + + c.JSON(httpStatus, utils.H{ + "code": code, + "message": message, + "error": err.Error(), + }) +} + +// writeSuccessResponse writes a standardized success response | 写入标准化的成功响应 +func writeSuccessResponse(c *app.RequestContext, data interface{}) { + c.JSON(http.StatusOK, utils.H{ + "code": core.CodeSuccess, + "message": "success", + "data": data, + }) +} + +// getHTTPStatusFromCode converts Sa-Token error code to HTTP status | 将Sa-Token错误码转换为HTTP状态码 +func getHTTPStatusFromCode(code int) int { + switch code { + case core.CodeNotLogin: + return http.StatusUnauthorized + case core.CodePermissionDenied: + return http.StatusForbidden + case core.CodeBadRequest: + return http.StatusBadRequest + case core.CodeNotFound: + return http.StatusNotFound + case core.CodeServerError: + return http.StatusInternalServerError + default: + return http.StatusInternalServerError + } +}