diff --git a/Makefile b/Makefile index 0d72595..8f64142 100644 --- a/Makefile +++ b/Makefile @@ -304,7 +304,7 @@ copyright-add: tools.verify.addlicense .PHONY: swagger swagger: tools.verify.swagger @echo "===========> Generating swagger API docs" - @$(TOOLS_DIR)/swagger generate spec --scan-models -w $(ROOT_DIR)/cmd/gendocs -o $(ROOT_DIR)/server/docs/swagger.yaml + @$(TOOLS_DIR)/swagger generate spec --scan-models -w $(ROOT_DIR)/server/cmd/gendocs -o $(ROOT_DIR)/server/docs/swagger.yaml ## serve-swagger: Serve swagger spec and docs. .PHONY: swagger.serve diff --git a/server/config-example.yaml b/server/config-example.yaml index e985ba0..6ebfa3e 100644 --- a/server/config-example.yaml +++ b/server/config-example.yaml @@ -56,4 +56,9 @@ email: port: 25 from: # email address nickname: openkf - password: # smtp password \ No newline at end of file + password: # smtp password + +openim: + secret: openkf + ip: 127.0.0.1 + api_port: 10002 diff --git a/server/config.yaml b/server/config.yaml index e985ba0..6ebfa3e 100644 --- a/server/config.yaml +++ b/server/config.yaml @@ -56,4 +56,9 @@ email: port: 25 from: # email address nickname: openkf - password: # smtp password \ No newline at end of file + password: # smtp password + +openim: + secret: openkf + ip: 127.0.0.1 + api_port: 10002 diff --git a/server/go.mod b/server/go.mod index 33519af..6f8fc3c 100644 --- a/server/go.mod +++ b/server/go.mod @@ -8,11 +8,13 @@ require ( github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 github.com/gin-gonic/gin v1.9.1 github.com/go-redis/redis/v8 v8.11.5 + github.com/go-resty/resty/v2 v2.7.0 github.com/gofrs/uuid v4.4.0+incompatible github.com/golang-jwt/jwt/v4 v4.5.0 github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible github.com/minio/minio-go/v7 v7.0.57 + github.com/pkg/errors v0.9.1 github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 github.com/sirupsen/logrus v1.9.3 github.com/spf13/viper v1.16.0 @@ -47,7 +49,7 @@ require ( github.com/google/uuid v1.3.0 // indirect github.com/gookit/color v1.5.3 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/huandu/xstrings v1.3.3 // indirect + github.com/huandu/xstrings v1.4.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/jonboulle/clockwork v0.4.0 // indirect @@ -69,9 +71,8 @@ require ( github.com/muesli/reflow v0.3.0 // indirect github.com/onsi/gomega v1.27.6 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/rivo/uniseg v0.2.0 // indirect - github.com/rogpeppe/go-internal v1.10.0 // indirect + github.com/rogpeppe/go-internal v1.11.0 // indirect github.com/rs/xid v1.5.0 // indirect github.com/spf13/afero v1.9.5 // indirect github.com/spf13/cast v1.5.1 // indirect @@ -83,14 +84,14 @@ require ( github.com/ugorji/go/codec v1.2.11 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.10.0 // indirect + golang.org/x/crypto v0.11.0 // indirect golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea // indirect - golang.org/x/mod v0.11.0 // indirect - golang.org/x/net v0.11.0 // indirect - golang.org/x/sys v0.9.0 // indirect - golang.org/x/term v0.9.0 // indirect - golang.org/x/text v0.10.0 // indirect - golang.org/x/tools v0.10.0 // indirect + golang.org/x/mod v0.12.0 // indirect + golang.org/x/net v0.12.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/term v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect + golang.org/x/tools v0.11.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/server/go.sum b/server/go.sum index 00b4996..44d8d13 100644 --- a/server/go.sum +++ b/server/go.sum @@ -112,6 +112,8 @@ github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= +github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= +github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= @@ -192,8 +194,8 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ 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/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4= -github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= +github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= @@ -292,8 +294,8 @@ github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= @@ -361,8 +363,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= -golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -400,8 +402,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= -golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -433,11 +435,12 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= -golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= +golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -503,14 +506,14 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/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.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.0.0-20221017184919-83659145692c/go.mod h1:VTIZ7TEbF0BS9Sv9lPTvGbtW8i4z6GGbJBCM37uMCzY= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= -golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -520,8 +523,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/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.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= -golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -573,8 +576,8 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg= -golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM= +golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8= +golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/server/internal/config/config.go b/server/internal/config/config.go index 6b141b9..26ec727 100644 --- a/server/internal/config/config.go +++ b/server/internal/config/config.go @@ -70,6 +70,11 @@ func ConfigInit(configPath string) { Nickname: GetString("email.nickname"), Password: GetString("email.password"), }, + OpenIM: OpenIM{ + Secret: GetStringOrDefault("openim.secret", "openkf"), + Ip: GetStringOrDefault("openim.ip", "127.0.0.1"), + ApiPort: GetIntOrDefault("openim.api_port", 10002), + }, } } @@ -81,6 +86,7 @@ type config struct { Redis Redis Minio Minio Email Email + OpenIM OpenIM } // App config. @@ -142,3 +148,10 @@ type Email struct { Nickname string `mapstructure:"nickname"` Password string `mapstructure:"password"` } + +// OpenIM config. +type OpenIM struct { + Secret string `mapstructure:"secret"` + Ip string `mapstructure:"ip"` + ApiPort int `mapstructure:"api_port"` +} diff --git a/server/internal/service/user.go b/server/internal/service/user.go index a3d10ea..9b241f1 100644 --- a/server/internal/service/user.go +++ b/server/internal/service/user.go @@ -16,13 +16,18 @@ package service import ( "errors" + "fmt" + "net" "github.com/gin-gonic/gin" + "github.com/OpenIMSDK/OpenKF/server/internal/config" "github.com/OpenIMSDK/OpenKF/server/internal/dal/dao" "github.com/OpenIMSDK/OpenKF/server/internal/models/base" systemroles "github.com/OpenIMSDK/OpenKF/server/internal/models/system_roles" "github.com/OpenIMSDK/OpenKF/server/internal/param" + "github.com/OpenIMSDK/OpenKF/server/pkg/openim/param/request" + "github.com/OpenIMSDK/OpenKF/server/pkg/openim/sdk/user" "github.com/OpenIMSDK/OpenKF/server/pkg/utils" ) @@ -80,6 +85,25 @@ func (svc *UserService) CreateAdmin(user param.RegisterAdminParams) (string, uin u, _ := svc.SysUserDao.FindFirstByUUID(uuid) + // TODO: set pipline to tx. + param := &request.RegisterUserParams{ + Secret: config.Config.OpenIM.Secret, + Users: []request.User{ + { + UserID: uuid.String(), + Nickname: adminParam.Nickname, + FaceURL: "", // Use OpenKF avatar + }, + }, + } + ok, err := registerUserToOpenIM(param) + if err != nil || !ok { + // Assume that the user has been created/deleted successfully + _ = svc.SysUserDao.Delete(u) + + return uuid.String(), u.Id, err + } + return uuid.String(), u.Id, nil } @@ -108,5 +132,40 @@ func (svc *UserService) CreateStaff(user param.RegisterStaffParams) (string, uin u, _ := svc.SysUserDao.FindFirstByUUID(uuid) + // TODO: set pipline to tx. + param := &request.RegisterUserParams{ + Secret: config.Config.OpenIM.Secret, + Users: []request.User{ + { + UserID: uuid.String(), + Nickname: staffParam.Nickname, + FaceURL: "", // Use OpenKF avatar + }, + }, + } + ok, err := registerUserToOpenIM(param) + if err != nil || !ok { + // Assume that the user has been created/deleted successfully + _ = svc.SysUserDao.Delete(u) + + return uuid.String(), u.Id, err + } + return uuid.String(), u.Id, nil } + +// registerUserToOpenIM register user to openim. +func registerUserToOpenIM(param *request.RegisterUserParams) (bool, error) { + // Default not use tls/ssl + host := fmt.Sprintf("http://%s", net.JoinHostPort(config.Config.OpenIM.Ip, fmt.Sprintf("%d", config.Config.OpenIM.ApiPort))) + resp, err := user.RegisterUser(param, host) + if err != nil { + return false, err + } + + if resp.ErrCode != 0 { + return false, errors.New(resp.ErrMsg) + } + + return true, nil +} diff --git a/server/pkg/openim/client/client.go b/server/pkg/openim/client/client.go new file mode 100644 index 0000000..1b51668 --- /dev/null +++ b/server/pkg/openim/client/client.go @@ -0,0 +1,66 @@ +// Copyright © 2023 OpenIM open source community. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package client + +import ( + "encoding/json" + + "github.com/go-resty/resty/v2" +) + +// Client client. +type Client interface { + GET(operationID string, params interface{}) (map[string]interface{}, error) + POST(operationID string, params interface{}) (map[string]interface{}, error) +} + +// httpClient http client. +type httpClient struct { + url string + client *resty.Client +} + +// NewClient new client. +func NewClient(url string) Client { + return &httpClient{ + url: url, + client: resty.New(), + } +} + +// GET get unimplemented. +func (c *httpClient) GET(operationID string, params interface{}) (map[string]interface{}, error) { + return nil, nil +} + +// POST post. +func (c *httpClient) POST(operationID string, params interface{}) (map[string]interface{}, error) { + resp, err := c.client.R(). + SetHeader("Content-Type", "application/json"). + SetHeader("operationID", operationID). + SetBody(params). + Post(c.url) + if err != nil { + return nil, err + } + + var responseData map[string]interface{} + err = json.Unmarshal(resp.Body(), &responseData) + if err != nil { + return nil, err + } + + return responseData, nil +} diff --git a/server/pkg/openim/param/request/auth.go b/server/pkg/openim/param/request/auth.go new file mode 100644 index 0000000..77f66d2 --- /dev/null +++ b/server/pkg/openim/param/request/auth.go @@ -0,0 +1,22 @@ +// Copyright © 2023 OpenIM open source community. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package request + +// UserTokenParams register admin params. +type UserTokenParams struct { + Secret string `json:"secret" binding:"required"` + PlatformID uint `json:"platformID" binding:"required"` + UserID string `json:"userID" binding:"required"` +} diff --git a/server/pkg/openim/param/request/user.go b/server/pkg/openim/param/request/user.go new file mode 100644 index 0000000..354fcf8 --- /dev/null +++ b/server/pkg/openim/param/request/user.go @@ -0,0 +1,28 @@ +// Copyright © 2023 OpenIM open source community. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package request + +// RegisterUserParams register user params. +type RegisterUserParams struct { + Secret string `json:"secret" binding:"required"` + Users []User `json:"users" binding:"required"` +} + +// User user. +type User struct { + UserID string `json:"userID" binding:"required"` + Nickname string `json:"nickname" binding:"required"` + FaceURL string `json:"faceURL" binding:"required"` +} diff --git a/server/pkg/openim/param/response/response.go b/server/pkg/openim/param/response/response.go new file mode 100644 index 0000000..6e8f24a --- /dev/null +++ b/server/pkg/openim/param/response/response.go @@ -0,0 +1,34 @@ +// Copyright © 2023 OpenIM open source community. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package response + +// BaseResponse base response. +type BaseResponse struct { + ErrCode uint `json:"errCode"` + ErrMsg string `json:"errMsg"` + ErrDlt string `json:"errDlt"` +} + +// UserTokenResponse user token response. +type UserTokenResponse struct { + BaseResponse + Data TokenData `json:"data"` +} + +// TokenData token data. +type TokenData struct { + Token string `json:"token"` + ExpireTimeSeconds uint `json:"expireTimeSeconds"` +} diff --git a/server/pkg/openim/sdk/auth/auth.go b/server/pkg/openim/sdk/auth/auth.go new file mode 100644 index 0000000..7663fa5 --- /dev/null +++ b/server/pkg/openim/sdk/auth/auth.go @@ -0,0 +1,52 @@ +// Copyright © 2023 OpenIM open source community. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package auth + +import ( + "fmt" + + "github.com/OpenIMSDK/OpenKF/server/pkg/openim/client" + "github.com/OpenIMSDK/OpenKF/server/pkg/openim/param/request" + "github.com/OpenIMSDK/OpenKF/server/pkg/openim/param/response" +) + +const ( + // PATH_USER_TOKEN get user token path. + PATH_USER_TOKEN = "/auth/user_token" +) + +// GetUserToken get user token from openim server. +func GetUserToken(param *request.UserTokenParams, host string) (*response.UserTokenResponse, error) { + // host: http://ip:port + url := fmt.Sprintf("%s%s", host, PATH_USER_TOKEN) + + r := &response.UserTokenResponse{} + client := client.NewClient(url) + resp, err := client.POST(PATH_USER_TOKEN, param) + if err != nil { + return r, err + } + + r.ErrCode = uint(resp["errCode"].(float64)) + r.ErrMsg = resp["errMsg"].(string) + r.ErrDlt = resp["errDlt"].(string) + if data, ok := resp["data"]; ok { + data := data.(map[string]interface{}) + r.Data.Token = data["token"].(string) + r.Data.ExpireTimeSeconds = uint(data["expireTimeSeconds"].(float64)) + } + + return r, nil +} diff --git a/server/pkg/openim/sdk/auth/auth_test.go b/server/pkg/openim/sdk/auth/auth_test.go new file mode 100644 index 0000000..f0bc528 --- /dev/null +++ b/server/pkg/openim/sdk/auth/auth_test.go @@ -0,0 +1,50 @@ +// Copyright © 2023 OpenIM open source community. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package auth_test + +import ( + "testing" + + "github.com/OpenIMSDK/OpenKF/server/pkg/openim/param/request" + "github.com/OpenIMSDK/OpenKF/server/pkg/openim/sdk/auth" +) + +// TestGetUserToken test get user token function +func TestGetUserToken(t *testing.T) { + // test case + testData := []struct { + secret string + platformID uint + userID string + }{ + { + secret: "openkf", + platformID: 1, + userID: "openIMAdmin", + }, + } + + // range test case + for _, data := range testData { + _, err := auth.GetUserToken(&request.UserTokenParams{ + Secret: data.secret, + PlatformID: data.platformID, + UserID: data.userID, + }, "http://127.0.0.1:10002") + if err != nil { + t.Error(err) + } + } +} diff --git a/server/pkg/openim/sdk/user/user.go b/server/pkg/openim/sdk/user/user.go new file mode 100644 index 0000000..6a149da --- /dev/null +++ b/server/pkg/openim/sdk/user/user.go @@ -0,0 +1,47 @@ +// Copyright © 2023 OpenIM open source community. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package user + +import ( + "fmt" + + "github.com/OpenIMSDK/OpenKF/server/pkg/openim/client" + "github.com/OpenIMSDK/OpenKF/server/pkg/openim/param/request" + "github.com/OpenIMSDK/OpenKF/server/pkg/openim/param/response" +) + +const ( + // PATH_USER_REGISTER register user path. + PATH_USER_REGISTER = "/auth/user_register" +) + +// RegisterUser register user. +func RegisterUser(param *request.RegisterUserParams, host string) (*response.BaseResponse, error) { + // host: http://ip:port + url := fmt.Sprintf("%s%s", host, PATH_USER_REGISTER) + + r := &response.BaseResponse{} + client := client.NewClient(url) + resp, err := client.POST(PATH_USER_REGISTER, param) + if err != nil { + return r, err + } + + r.ErrCode = uint(resp["errCode"].(float64)) + r.ErrMsg = resp["errMsg"].(string) + r.ErrDlt = resp["errDlt"].(string) + + return r, nil +} diff --git a/server/pkg/openim/sdk/user/user_test.go b/server/pkg/openim/sdk/user/user_test.go new file mode 100644 index 0000000..6b55b50 --- /dev/null +++ b/server/pkg/openim/sdk/user/user_test.go @@ -0,0 +1,57 @@ +// Copyright © 2023 OpenIM open source community. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package user_test + +import ( + "testing" + + "github.com/OpenIMSDK/OpenKF/server/pkg/openim/param/request" + "github.com/OpenIMSDK/OpenKF/server/pkg/openim/sdk/user" +) + +// TestGetUserToken test get user token function +func TestRegisterUser(t *testing.T) { + // test case + testData := []struct { + secret string + userID string + nickname string + faceURL string + }{ + { + secret: "openkf", + userID: "test123", + nickname: "test123", + faceURL: "https://openim.com/openkf.png", + }, + } + + // range test case + for _, data := range testData { + _, err := user.RegisterUser(&request.RegisterUserParams{ + Secret: data.secret, + Users: []request.User{ + { + UserID: data.userID, + Nickname: data.nickname, + FaceURL: data.faceURL, + }, + }, + }, "http://127.0.0.1:10002") + if err != nil { + t.Error(err) + } + } +}