From 28b9015f29ad03e00c1e78be3e2a8a4bda8178bf Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 22 Apr 2023 00:46:18 -0400 Subject: [PATCH] use formal JWT validation (#35) --- go.mod | 30 +++++++++++------------ go.sum | 62 ++++++++++++++++++++++++------------------------ main.go | 37 +++++++++++++++++++++++++---- route/v1.go | 11 +++++++-- route/v1/user.go | 56 +++++++++++++++++++++++++++++++++++-------- route/v2.go | 12 +++++++--- service/user.go | 38 +++++++++++++++++++++++++---- 7 files changed, 177 insertions(+), 69 deletions(-) diff --git a/go.mod b/go.mod index f90e248..f21d2c8 100644 --- a/go.mod +++ b/go.mod @@ -3,31 +3,31 @@ module github.com/IceWhaleTech/CasaOS-UserService go 1.20 require ( - github.com/IceWhaleTech/CasaOS-Common v0.4.3 + github.com/IceWhaleTech/CasaOS-Common v0.4.4-alpha2 github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf github.com/deepmap/oapi-codegen v1.12.4 - github.com/getkin/kin-openapi v0.115.0 + github.com/getkin/kin-openapi v0.116.0 github.com/gin-contrib/gzip v0.0.6 github.com/gin-gonic/gin v1.9.0 - github.com/glebarez/sqlite v1.7.0 + github.com/glebarez/sqlite v1.8.0 github.com/labstack/echo/v4 v4.10.2 github.com/satori/go.uuid v1.2.0 github.com/tidwall/gjson v1.14.4 go.uber.org/zap v1.24.0 - golang.org/x/net v0.8.0 + golang.org/x/net v0.9.0 gopkg.in/ini.v1 v1.67.0 - gorm.io/gorm v1.24.6 + gorm.io/gorm v1.25.0 ) require ( github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect - github.com/benbjohnson/clock v1.3.0 // indirect - github.com/bytedance/sonic v1.8.6 // indirect + github.com/benbjohnson/clock v1.3.1 // indirect + github.com/bytedance/sonic v1.8.7 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/gin-contrib/sse v0.1.0 // indirect - github.com/glebarez/go-sqlite v1.21.0 // indirect + github.com/glebarez/go-sqlite v1.21.1 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/swag v0.22.3 // indirect github.com/go-playground/locales v0.14.1 // indirect @@ -46,7 +46,7 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/labstack/gommon v0.4.0 // indirect - github.com/leodido/go-urn v1.2.2 // indirect + github.com/leodido/go-urn v1.2.3 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.18 // indirect @@ -63,17 +63,17 @@ require ( github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect go.uber.org/atomic v1.10.0 // indirect - go.uber.org/multierr v1.10.0 // indirect + go.uber.org/multierr v1.11.0 // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.7.0 // indirect - golang.org/x/sys v0.6.0 // indirect - golang.org/x/text v0.8.0 // indirect + golang.org/x/crypto v0.8.0 // indirect + golang.org/x/sys v0.7.0 // indirect + golang.org/x/text v0.9.0 // indirect golang.org/x/time v0.3.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - modernc.org/libc v1.22.3 // indirect + modernc.org/libc v1.22.4 // indirect modernc.org/mathutil v1.5.0 // indirect modernc.org/memory v1.5.0 // indirect - modernc.org/sqlite v1.21.0 // indirect + modernc.org/sqlite v1.21.2 // indirect ) diff --git a/go.sum b/go.sum index 221b689..789dca7 100644 --- a/go.sum +++ b/go.sum @@ -1,14 +1,14 @@ -github.com/IceWhaleTech/CasaOS-Common v0.4.3 h1:sYsWYhP5EyksH6D0BDv8secIRGAKUZZDTIKqACdFZQ4= -github.com/IceWhaleTech/CasaOS-Common v0.4.3/go.mod h1:zLzM1RhoBRDdW7DFlEoPq18OhbJYsvc8yFodW0bm/QI= +github.com/IceWhaleTech/CasaOS-Common v0.4.4-alpha2 h1:EIuQbVpuU2QZVui+ApYCEt27qGCUaQhgHCdOeHmgAwc= +github.com/IceWhaleTech/CasaOS-Common v0.4.4-alpha2/go.mod h1:iv6fJJs7IKv1tSrsbyA3Fq9xfeKNoaxhqA6IQUBeg9Q= github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.1 h1:Heo0FGXzOxUHquZbraxt+tT7UXVDhesUQH5ISbsOkCQ= +github.com/benbjohnson/clock v1.3.1/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.8.6 h1:aUgO9S8gvdN6SyW2EhIpAw5E4ChworywIEndZCkCVXk= -github.com/bytedance/sonic v1.8.6/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= +github.com/bytedance/sonic v1.8.7 h1:d3sry5vGgVq/OpgozRUNP6xBsSo0mtNdwliApw+SAMQ= +github.com/bytedance/sonic v1.8.7/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= @@ -24,8 +24,8 @@ github.com/deepmap/oapi-codegen v1.12.4 h1:pPmn6qI9MuOtCz82WY2Xaw46EQjgvxednXXrP github.com/deepmap/oapi-codegen v1.12.4/go.mod h1:3lgHGMu6myQ2vqbbTXH2H1o4eXFTGnFiDaOaKKl5yas= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/getkin/kin-openapi v0.115.0 h1:c8WHRLVY3G8m9jQTy0/DnIuljgRwTCB5twZytQS4JyU= -github.com/getkin/kin-openapi v0.115.0/go.mod h1:l5e9PaFUo9fyLJCPGQeXI2ML8c3P8BHOEV2VaAVf/pc= +github.com/getkin/kin-openapi v0.116.0 h1:o986hwgMzR972JzOG5j6+WTwWqllZLs1EJKMKCivs2E= +github.com/getkin/kin-openapi v0.116.0/go.mod h1:l5e9PaFUo9fyLJCPGQeXI2ML8c3P8BHOEV2VaAVf/pc= github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4= github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= @@ -33,10 +33,10 @@ github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= github.com/gin-gonic/gin v1.9.0 h1:OjyFBKICoexlu99ctXNR2gg+c5pKrKMuyjgARg9qeY8= github.com/gin-gonic/gin v1.9.0/go.mod h1:W1Me9+hsUSyj3CePGrd1/QrKJMSJ1Tu/0hFEH89961k= -github.com/glebarez/go-sqlite v1.21.0 h1:b8MHPtBagkSD2gntImZPsG3o3QEXgMDxguW/GLUonHQ= -github.com/glebarez/go-sqlite v1.21.0/go.mod h1:GodsA6yGSa3eKbvpr7dS+JaqazzVfMcjIXvx6KHhW/c= -github.com/glebarez/sqlite v1.7.0 h1:A7Xj/KN2Lvie4Z4rrgQHY8MsbebX3NyWsL3n2i82MVI= -github.com/glebarez/sqlite v1.7.0/go.mod h1:PkeevrRlF/1BhQBCnzcMWzgrIk7IOop+qS2jUYLfHhk= +github.com/glebarez/go-sqlite v1.21.1 h1:7MZyUPh2XTrHS7xNEHQbrhfMZuPSzhkm2A1qgg0y5NY= +github.com/glebarez/go-sqlite v1.21.1/go.mod h1:ISs8MF6yk5cL4n/43rSOmVMGJJjHYr7L2MbZZ5Q4E2E= +github.com/glebarez/sqlite v1.8.0 h1:02X12E2I/4C1n+v90yTqrjRa8yuo7c3KeHI3FRznCvc= +github.com/glebarez/sqlite v1.8.0/go.mod h1:bpET16h1za2KOOMb8+jCp6UBP/iahDpfPQqSaYLTLx8= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= @@ -103,8 +103,8 @@ github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= -github.com/leodido/go-urn v1.2.2 h1:7z68G0FCGvDk646jz1AelTYNYWrTNm0bEcFAo147wt4= -github.com/leodido/go-urn v1.2.2/go.mod h1:kUaIbLZWttglzwNuG0pgsh5vuV6u2YcGBYz1hIPjtOQ= +github.com/leodido/go-urn v1.2.3 h1:6BE2vPT0lqoz3fmOesHZiaiFh7889ssCo2GMvLCfiuA= +github.com/leodido/go-urn v1.2.3/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= @@ -138,7 +138,6 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qq github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/rwtodd/Go.Sed v0.0.0-20210816025313-55464686f9ef/go.mod h1:8AEUvGVi2uQ5b24BIhcr0GCcpd/RNAFWaN2CJFrWIIQ= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= @@ -173,20 +172,20 @@ github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQ github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ= +golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= 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-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -195,13 +194,14 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -226,14 +226,14 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0/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= -gorm.io/gorm v1.24.6 h1:wy98aq9oFEetsc4CAbKD2SoBCdMzsbSIvSUUFJuHi5s= -gorm.io/gorm v1.24.6/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= -modernc.org/libc v1.22.3 h1:D/g6O5ftAfavceqlLOFwaZuA5KYafKwmr30A6iSqoyY= -modernc.org/libc v1.22.3/go.mod h1:MQrloYP209xa2zHome2a8HLiLm6k0UT8CoHpV74tOFw= +gorm.io/gorm v1.25.0 h1:+KtYtb2roDz14EQe4bla8CbQlmb9dN3VejSai3lprfU= +gorm.io/gorm v1.25.0/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +modernc.org/libc v1.22.4 h1:wymSbZb0AlrjdAVX3cjreCHTPCpPARbQXNz6BHPzdwQ= +modernc.org/libc v1.22.4/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY= modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ= modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds= modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= -modernc.org/sqlite v1.21.0 h1:4aP4MdUf15i3R3M2mx6Q90WHKz3nZLoz96zlB6tNdow= -modernc.org/sqlite v1.21.0/go.mod h1:XwQ0wZPIh1iKb5mkvCJ3szzbhk+tykC8ZWqTRTgYRwI= +modernc.org/sqlite v1.21.2 h1:ixuUG0QS413Vfzyx6FWx6PYTmHaOegTY+hjzhn7L+a0= +modernc.org/sqlite v1.21.2/go.mod h1:cxbLkB5WS32DnQqeH4h4o1B0eMr8W/y8/RGuxQ3JsC0= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/main.go b/main.go index 221a73a..4c39f7c 100644 --- a/main.go +++ b/main.go @@ -9,10 +9,14 @@ import ( "net" "net/http" "os" + "path/filepath" + "strings" "time" + "github.com/IceWhaleTech/CasaOS-Common/external" "github.com/IceWhaleTech/CasaOS-Common/model" util_http "github.com/IceWhaleTech/CasaOS-Common/utils/http" + "github.com/IceWhaleTech/CasaOS-Common/utils/jwt" "github.com/IceWhaleTech/CasaOS-Common/utils/logger" "github.com/IceWhaleTech/CasaOS-UserService/common" "github.com/IceWhaleTech/CasaOS-UserService/pkg/config" @@ -93,11 +97,19 @@ func main() { v2Router := route.InitV2Router() v2DocRouter := route.InitV2DocRouter(_docHTML, _docYAML) + _, publicKey := service.MyService.User().GetKeyPair() + + jswkJSON, err := jwt.GenerateJwksJSON(publicKey) + if err != nil { + panic(err) + } + mux := &util_http.HandlerMultiplexer{ HandlerMap: map[string]http.Handler{ - "v1": v1Router, - "v2": v2Router, - "doc": v2DocRouter, + "v1": v1Router, + "v2": v2Router, + "doc": v2DocRouter, + strings.SplitN(jwt.JWKSPath, "/", 2)[0]: jwt.JWKSHandler(jswkJSON), }, } @@ -110,6 +122,7 @@ func main() { "/v1/users", route.V2APIPath, route.V2DocPath, + "/" + jwt.JWKSPath, } for _, v := range apiPaths { err = service.MyService.Gateway().CreateRoute(&model.Route{ @@ -122,6 +135,12 @@ func main() { } } + // write address file + addressFilePath, err := writeAddressFile(config.CommonInfo.RuntimePath, external.UserServiceAddressFilename, "http://"+listener.Addr().String()) + if err != nil { + panic(err) + } + if supported, err := daemon.SdNotify(false, daemon.SdNotifyReady); err != nil { logger.Error("Failed to notify systemd that user service is ready", zap.Any("error", err)) } else if supported { @@ -130,7 +149,7 @@ func main() { logger.Info("This process is not running as a systemd service.") } go route.EventListen() - logger.Info("User service is listening...", zap.Any("address", listener.Addr().String())) + logger.Info("User service is listening...", zap.Any("address", listener.Addr().String()), zap.String("filepath", addressFilePath)) s := &http.Server{ Handler: mux, @@ -142,3 +161,13 @@ func main() { panic(err) } } + +func writeAddressFile(runtimePath string, filename string, address string) (string, error) { + err := os.MkdirAll(runtimePath, 0o755) + if err != nil { + return "", err + } + + filepath := filepath.Join(runtimePath, filename) + return filepath, os.WriteFile(filepath, []byte(address), 0o600) +} diff --git a/route/v1.go b/route/v1.go index bb1e09a..4f31cd5 100644 --- a/route/v1.go +++ b/route/v1.go @@ -1,11 +1,13 @@ package route import ( + "crypto/ecdsa" "os" "github.com/IceWhaleTech/CasaOS-Common/middleware" "github.com/IceWhaleTech/CasaOS-Common/utils/jwt" v1 "github.com/IceWhaleTech/CasaOS-UserService/route/v1" + "github.com/IceWhaleTech/CasaOS-UserService/service" "github.com/gin-contrib/gzip" "github.com/gin-gonic/gin" ) @@ -13,7 +15,7 @@ import ( func InitRouter() *gin.Engine { r := gin.Default() r.Use(middleware.Cors()) - //r.Use(middleware.WriteLog()) + // r.Use(middleware.WriteLog()) r.Use(gzip.Gzip(gzip.DefaultCompression)) // check if environment variable is set @@ -34,7 +36,12 @@ func InitRouter() *gin.Engine { v1Group := r.Group("/v1") - v1Group.Use(jwt.JWT()) + v1Group.Use(jwt.JWT( + func() (*ecdsa.PublicKey, error) { + _, publicKey := service.MyService.User().GetKeyPair() + return publicKey, nil + }, + )) { v1UsersGroup := v1Group.Group("/users") v1UsersGroup.Use() diff --git a/route/v1/user.go b/route/v1/user.go index 773502d..1034bad 100644 --- a/route/v1/user.go +++ b/route/v1/user.go @@ -1,6 +1,7 @@ package v1 import ( + "crypto/ecdsa" json2 "encoding/json" "io" "net/http" @@ -109,9 +110,23 @@ func PostUserLogin(c *gin.Context) { model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)}) return } + + privateKey, _ := service.MyService.User().GetKeyPair() + token := system_model.VerifyInformation{} - token.AccessToken = jwt.GetAccessToken(user.Username, user.Password, user.Id) - token.RefreshToken = jwt.GetRefreshToken(user.Username, user.Password, user.Id) + + accessToken, err := jwt.GetAccessToken(user.Username, privateKey, user.Id) + if err != nil { + c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()}) + } + token.AccessToken = accessToken + + refreshToken, err := jwt.GetRefreshToken(user.Username, privateKey, user.Id) + if err != nil { + c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()}) + } + token.RefreshToken = refreshToken + token.ExpiresAt = time.Now().Add(3 * time.Hour * time.Duration(1)).Unix() data := make(map[string]interface{}, 2) user.Password = "" @@ -639,20 +654,41 @@ func PostUserRefreshToken(c *gin.Context) { js := make(map[string]string) c.ShouldBind(&js) refresh := js["refresh_token"] - claims, err := jwt.ParseToken(refresh, true) + + privateKey, _ := service.MyService.User().GetKeyPair() + + claims, err := jwt.ParseToken( + refresh, + func() (*ecdsa.PublicKey, error) { + _, publicKey := service.MyService.User().GetKeyPair() + return publicKey, nil + }) if err != nil { - c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.VERIFICATION_FAILURE, Message: common_err.GetMsg(common_err.VERIFICATION_FAILURE), Data: err.Error()}) + c.JSON(http.StatusUnauthorized, model.Result{Success: common_err.VERIFICATION_FAILURE, Message: common_err.GetMsg(common_err.VERIFICATION_FAILURE), Data: err.Error()}) return } if !claims.VerifyExpiresAt(time.Now(), true) || !claims.VerifyIssuer("refresh", true) { - c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.VERIFICATION_FAILURE, Message: common_err.GetMsg(common_err.VERIFICATION_FAILURE)}) + c.JSON(http.StatusUnauthorized, model.Result{Success: common_err.VERIFICATION_FAILURE, Message: common_err.GetMsg(common_err.VERIFICATION_FAILURE)}) + return + } + + newAccessToken, err := jwt.GetAccessToken(claims.Username, privateKey, claims.ID) + if err != nil { + c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()}) return } - newToken := jwt.GetAccessToken(claims.Username, claims.Password, claims.ID) - verifyInfo := system_model.VerifyInformation{} - verifyInfo.AccessToken = newToken - verifyInfo.RefreshToken = jwt.GetRefreshToken(claims.Username, claims.Password, claims.ID) - verifyInfo.ExpiresAt = time.Now().Add(3 * time.Hour * time.Duration(1)).Unix() + + newRefreshToken, err := jwt.GetRefreshToken(claims.Username, privateKey, claims.ID) + if err != nil { + c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()}) + return + } + + verifyInfo := system_model.VerifyInformation{ + AccessToken: newAccessToken, + RefreshToken: newRefreshToken, + ExpiresAt: time.Now().Add(3 * time.Hour).Unix(), + } c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: verifyInfo}) } diff --git a/route/v2.go b/route/v2.go index c5fe160..93c2c7a 100644 --- a/route/v2.go +++ b/route/v2.go @@ -1,15 +1,16 @@ package route import ( + "crypto/ecdsa" "net/http" "net/url" "strconv" "strings" - "github.com/IceWhaleTech/CasaOS-Common/utils/common_err" "github.com/IceWhaleTech/CasaOS-Common/utils/jwt" codegen "github.com/IceWhaleTech/CasaOS-UserService/codegen/user_service" v2 "github.com/IceWhaleTech/CasaOS-UserService/route/v2" + "github.com/IceWhaleTech/CasaOS-UserService/service" "github.com/deepmap/oapi-codegen/pkg/middleware" "github.com/getkin/kin-openapi/openapi3" "github.com/getkin/kin-openapi/openapi3filter" @@ -64,8 +65,13 @@ func InitV2Router() http.Handler { return c.RealIP() == "::1" || c.RealIP() == "127.0.0.1" }, ParseTokenFunc: func(token string, c echo.Context) (interface{}, error) { - claims, code := jwt.Validate(token) - if code != common_err.SUCCESS { + valid, claims, err := jwt.Validate( + token, + func() (*ecdsa.PublicKey, error) { + _, publicKey := service.MyService.User().GetKeyPair() + return publicKey, nil + }) + if err != nil || !valid { return nil, echo.ErrUnauthorized } diff --git a/service/user.go b/service/user.go index 21d9148..54bed10 100644 --- a/service/user.go +++ b/service/user.go @@ -10,11 +10,15 @@ package service import ( + "crypto/ecdsa" "io" "mime/multipart" "os" + "github.com/IceWhaleTech/CasaOS-Common/utils/jwt" + "github.com/IceWhaleTech/CasaOS-Common/utils/logger" "github.com/IceWhaleTech/CasaOS-UserService/service/model" + "go.uber.org/zap" "gorm.io/gorm" ) @@ -31,17 +35,23 @@ type UserService interface { DeleteAllUser() GetUserInfoByUserName(userName string) (m model.UserDBModel) GetAllUserName() (list []model.UserDBModel) + + GetKeyPair() (*ecdsa.PrivateKey, *ecdsa.PublicKey) } var UserRegisterHash = make(map[string]string) type userService struct { + privateKey *ecdsa.PrivateKey // keep this private - NEVER expose it!!! + publicKey *ecdsa.PublicKey + db *gorm.DB } func (u *userService) DeleteAllUser() { u.db.Where("1=1").Delete(&model.UserDBModel{}) } + func (u *userService) DeleteUserById(id string) { u.db.Where("id= ?", id).Delete(&model.UserDBModel{}) } @@ -50,6 +60,7 @@ func (u *userService) GetAllUserName() (list []model.UserDBModel) { u.db.Select("username").Find(&list) return } + func (u *userService) CreateUser(m model.UserDBModel) model.UserDBModel { u.db.Create(&m) return m @@ -63,17 +74,21 @@ func (u *userService) GetUserCount() (userCount int64) { func (u *userService) UpdateUser(m model.UserDBModel) { u.db.Model(&m).Omit("password").Updates(&m) } + func (u *userService) UpdateUserPassword(m model.UserDBModel) { u.db.Model(&m).Update("password", m.Password) } + func (u *userService) GetUserAllInfoById(id string) (m model.UserDBModel) { u.db.Where("id= ?", id).First(&m) return } + func (u *userService) GetUserAllInfoByName(userName string) (m model.UserDBModel) { u.db.Where("username= ?", userName).First(&m) return } + func (u *userService) GetUserInfoById(id string) (m model.UserDBModel) { u.db.Select("username", "id", "role", "nickname", "description", "avatar", "email").Where("id= ?", id).First(&m) return @@ -84,15 +99,30 @@ func (u *userService) GetUserInfoByUserName(userName string) (m model.UserDBMode return } -//上传文件 +// 上传文件 func (c *userService) UpLoadFile(file multipart.File, url string) error { - out, _ := os.OpenFile(url, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644) + out, _ := os.OpenFile(url, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0o644) defer out.Close() io.Copy(out, file) return nil } -//获取用户Service +func (u *userService) GetKeyPair() (*ecdsa.PrivateKey, *ecdsa.PublicKey) { + return u.privateKey, u.publicKey +} + +// 获取用户Service func NewUserService(db *gorm.DB) UserService { - return &userService{db: db} + // DO NOT store private key anywhere - keep it in memory ONLY!!! + privateKey, publicKey, err := jwt.GenerateKeyPair() + if err != nil { + logger.Error("failed to generate key pair for JWT", zap.Error(err)) + return nil + } + + return &userService{ + privateKey: privateKey, + publicKey: publicKey, + db: db, + } }