diff --git a/UI b/UI index 7af1bf5..bca2742 160000 --- a/UI +++ b/UI @@ -1 +1 @@ -Subproject commit 7af1bf549dd35c93f48b6c501204a4efe57e8d6b +Subproject commit bca27426e1f398c31fb6c5c23885482326514f6e diff --git a/alpha.md b/alpha.md index e471b7d..85e9085 100644 --- a/alpha.md +++ b/alpha.md @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2022-06-27 11:37:26 * @LastEditors: LinkLeong - * @LastEditTime: 2022-07-01 15:51:29 + * @LastEditTime: 2022-07-21 18:12:31 * @FilePath: /CasaOS/alpha.md * @Description: * @Website: https://www.casaos.io @@ -17,7 +17,7 @@ There is a risk of data loss in non-release versions, so please be careful to ba ## Install/Update -``` curl -fsSL https://get.casaos.io | bash -s -- -v v0.3.3-alpha ``` +``` curl -fsSL https://get.casaos.io | bash -s -- -v v0.3.4-alpha ``` ## Check change log diff --git a/conf/conf.conf.sample b/conf/conf.conf.sample index 5dfe5a6..c4f8179 100644 --- a/conf/conf.conf.sample +++ b/conf/conf.conf.sample @@ -15,18 +15,10 @@ TempPath = /var/lib/casaos/temp [server] HttpPort = 80 -UDPPort = RunMode = release ServerApi = https://api.casaos.io/casaos-api Handshake = socket.casaos.io Token = USBAutoMount = - -[system] -WidgetList = - - -[file] -ShareDir = -DownloadDir = \ No newline at end of file +[system] \ No newline at end of file diff --git a/go.mod b/go.mod index 48a2305..f329d17 100644 --- a/go.mod +++ b/go.mod @@ -19,12 +19,10 @@ require ( github.com/docker/go-connections v0.4.0 github.com/dsoprea/go-exif/v3 v3.0.0-20210625224831-a6301f85c82b github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd // indirect - github.com/forease/gotld v0.0.0-20190808124948-c50ff635576b github.com/gin-contrib/gzip v0.0.2 github.com/gin-gonic/gin v1.7.2 github.com/go-ini/ini v1.62.0 github.com/go-ole/go-ole v1.2.5 // indirect - github.com/go-openapi/spec v0.20.4 // indirect github.com/go-playground/validator/v10 v10.6.1 // indirect github.com/gogo/googleapis v1.4.1 // indirect github.com/golang-jwt/jwt/v4 v4.4.1 @@ -38,9 +36,9 @@ require ( github.com/jinzhu/copier v0.3.2 github.com/json-iterator/go v1.1.11 // indirect github.com/klauspost/compress v1.13.6 // indirect + github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.2.1 // indirect github.com/lucas-clemente/quic-go v0.25.0 - github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-isatty v0.0.14 // indirect github.com/mattn/go-sqlite3 v1.14.11 // indirect github.com/mholt/archiver/v3 v3.5.1 @@ -50,7 +48,6 @@ require ( github.com/opencontainers/selinux v1.8.5 // indirect github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pkg/errors v0.9.1 - github.com/prestonTao/upnp v0.0.0-20150206124352-f4370df5e109 github.com/prometheus/procfs v0.7.3 // indirect github.com/robfig/cron v1.2.0 github.com/satori/go.uuid v1.2.0 @@ -58,8 +55,6 @@ require ( github.com/sirupsen/logrus v1.8.1 github.com/smartystreets/assertions v1.2.0 // indirect github.com/smartystreets/goconvey v1.6.4 // indirect - github.com/swaggo/gin-swagger v1.3.0 - github.com/swaggo/swag v1.7.3 github.com/tidwall/gjson v1.10.2 github.com/tklauser/go-sysconf v0.3.6 // indirect github.com/ugorji/go v1.2.6 // indirect @@ -71,6 +66,7 @@ require ( golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f golang.org/x/sys v0.0.0-20211020174200-9d6173849985 // indirect golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect + golang.org/x/text v0.3.7 // indirect golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect golang.org/x/tools v0.1.7 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index 949a69d..f5c119c 100644 --- a/go.sum +++ b/go.sum @@ -59,8 +59,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d h1:62lEBImTxZ83pgzywgDNIrPPuQ+j4ep9QjqrWBn1hrU= github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d/go.mod h1:lW9x+yEjqKdPbE3+cf2fGPJXCw/hChX3Omi9QHTLFsQ= -github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= -github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= @@ -85,17 +83,13 @@ github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5 github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 h1:5sXbqlSomvdjlRbWyNqkPsJ3Fg+tQZCbgeX1VGljbQY= github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -328,8 +322,6 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/forease/gotld v0.0.0-20190808124948-c50ff635576b h1:r13MvtFTtnvxtuKK7z0ZSQ2EfMmTzWDHwfDvGCoqUQE= -github.com/forease/gotld v0.0.0-20190808124948-c50ff635576b/go.mod h1:EfR6AU78zUiZ36oVS5YrmTzc2um3zDXWPx4L4st++jo= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= @@ -340,15 +332,10 @@ github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXt github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w= github.com/gin-contrib/gzip v0.0.2 h1:VMBkd4ZB1Hl7e1lOA5gEZ/qdD3d9vLIq57xKWgPCCV8= github.com/gin-contrib/gzip v0.0.2/go.mod h1:YxxswVZIqOvcHEQpsSn+QF5guQtO1dCfy0shBPy4jFc= -github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= -github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= 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.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y= -github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gin-gonic/gin v1.7.2 h1:Tg03T9yM2xa8j6I3Z3oqLaQRSmKvxPd6g/2HJ6zICFA= github.com/gin-gonic/gin v1.7.2/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= @@ -372,29 +359,13 @@ github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTg github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= -github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= -github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs= -github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= -github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg= -github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M= -github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= -github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM= -github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= @@ -563,9 +534,6 @@ github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/ github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -611,14 +579,10 @@ github.com/lucas-clemente/quic-go v0.25.0 h1:K+X9Gvd7JXsOHtU0N2icZ2Nw3rx82uBej3m github.com/lucas-clemente/quic-go v0.25.0/go.mod h1:YtzP8bxRVCBlO77yRanE264+fY/T2U9ZlW1AaHOsMOg= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= 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.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= github.com/marten-seemann/qtls-go1-15 v0.1.4/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= @@ -630,8 +594,6 @@ github.com/marten-seemann/qtls-go1-18 v0.1.0-beta.1 h1:EnzzN9fPUkUck/1CuY1FlzBaI github.com/marten-seemann/qtls-go1-18 v0.1.0-beta.1/go.mod h1:PUhIQk19LoFt2174H4+an8TYvWOGjb/hHwphBeaDHwI= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= @@ -676,7 +638,6 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+ github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7MQ= github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -749,8 +710,6 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE 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/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= -github.com/prestonTao/upnp v0.0.0-20150206124352-f4370df5e109 h1:h9WYaTCQJ7hap8C5vQniEum2YZbc+iRad/ROafTjy10= -github.com/prestonTao/upnp v0.0.0-20150206124352-f4370df5e109/go.mod h1:U7VCLF6LMHzOFD/6Kww2MTQuwaNeEA1U1dOxFyZBoBE= github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -799,7 +758,6 @@ github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvW github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shirou/gopsutil/v3 v3.21.5 h1:YUBf0w/KPLk7w1803AYBnH7BmA+1Z/Q5MEZxpREUaB4= github.com/shirou/gopsutil/v3 v3.21.5/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw= -github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= @@ -868,12 +826,6 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E= -github.com/swaggo/gin-swagger v1.3.0 h1:eOmp7r57oUgZPw2dJOjcGNMse9cvXcI4tTqBcnZtPsI= -github.com/swaggo/gin-swagger v1.3.0/go.mod h1:oy1BRA6WvgtCp848lhxce7BnWH4C8Bxa0m5SkWx+cS0= -github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y= -github.com/swaggo/swag v1.7.3 h1:ucB7irEdRrhjmW+Z1Ss4GjO68oPKQFjSgOR8BCAvcbU= -github.com/swaggo/swag v1.7.3/go.mod h1:zD8h6h4SPv7t3l+4BKdRquqW1ASWjKZgT6Qv9z3kNqI= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= @@ -896,12 +848,9 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1 github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go v1.1.13/go.mod h1:jxau1n+/wyTGLQoCkjok9r5zFa/FxT6eI5HiHKQszjc= github.com/ugorji/go v1.2.6 h1:tGiWC9HENWE2tqYycIqFTNorMmFRVhNwCpDOpWqnk8E= github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0= -github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/ugorji/go/codec v1.1.13/go.mod h1:oNVt3Dq+FO91WNQ/9JnHKQP2QJxTzoN7wCBFCq1OeuU= github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ= github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw= github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= @@ -911,7 +860,6 @@ github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= @@ -1018,7 +966,6 @@ golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= 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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1033,7 +980,6 @@ golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1062,10 +1008,8 @@ golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211020060615-d418f374d309 h1:A0lJIi+hcTR6aajJH4YqKWwohY4aW9RO7oRMcdv+HKI= @@ -1098,9 +1042,7 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1112,7 +1054,6 @@ golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1163,13 +1104,11 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1213,9 +1152,7 @@ golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= @@ -1251,7 +1188,6 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= @@ -1375,15 +1311,12 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/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/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= @@ -1407,7 +1340,6 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/sqlite v1.2.6 h1:SStaH/b+280M7C8vXeZLz/zo9cLQmIGwwj3cSj7p6l4= diff --git a/main.go b/main.go index ccf2d9e..932f28d 100644 --- a/main.go +++ b/main.go @@ -24,7 +24,6 @@ var sqliteDB *gorm.DB var configFlag = flag.String("c", "", "config address") var dbFlag = flag.String("db", "", "db path") -var showUserInfo = flag.Bool("show-user-info", false, "show user info") var resetUser = flag.Bool("ru", false, "reset user") var user = flag.String("user", "", "user name") @@ -42,10 +41,6 @@ func init() { service.Cache = cache.Init() service.GetToken() - service.UDPAddressMap = make(map[string]string) - //go service.SocketConnect() - service.CancelList = make(map[string]string) - service.InternalInspection = make(map[string][]string) service.NewVersionApp = make(map[string]string) route.InitFunction() @@ -67,15 +62,7 @@ func init() { // @BasePath /v1 func main() { service.NotifyMsg = make(chan notify.Message, 10) - if *showUserInfo { - fmt.Println("CasaOS User Info") - fmt.Println("UserName:" + config.UserInfo.UserName) - fmt.Println("Password:" + config.UserInfo.PWD) - return - } - fmt.Println("Reset User", *resetUser) if *resetUser { - if user == nil || len(*user) == 0 { fmt.Println("user is empty") return @@ -89,21 +76,11 @@ func main() { userData.Password = encryption.GetMD5ByStr(password) service.MyService.User().UpdateUserPassword(userData) fmt.Println("User reset successful") - fmt.Println("UserName:" + userData.UserName) + fmt.Println("UserName:" + userData.Username) fmt.Println("Password:" + password) return } - go func() { - service.UDPService() - service.SendIPToServer() - }() go route.SocketInit(service.NotifyMsg) - go func() { - for i := 0; i < 1000; i++ { - time.Sleep(2 * time.Second) - //service.NotifyMsg <- strconv.Itoa(i) - } - }() //model.Setup() //gredis.Setup() @@ -111,20 +88,8 @@ func main() { //service.SyncTask(sqliteDB) cron2 := cron.New() //every day execution - err := cron2.AddFunc("0 0/5 * * * *", func() { - //service.PushIpInfo(*&config.ServerInfo.Token) - //service.UpdataDDNSList(mysqldb) - //service.SyncTask(sqliteDB) - service.SendIPToServer() - - service.LoopFriend() - //service.MyService.App().CheckNewImage() - }) - if err != nil { - fmt.Println(err) - } - err = cron2.AddFunc("0/5 * * * * *", func() { + err := cron2.AddFunc("0/5 * * * * *", func() { if service.ClientCount > 0 { //route.SendNetINfoBySocket() //route.SendCPUBySocket() diff --git a/middleware/gin.go b/middleware/gin.go index d70dfb9..3febab2 100644 --- a/middleware/gin.go +++ b/middleware/gin.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2021-10-08 10:29:08 * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-21 15:10:03 + * @LastEditTime: 2022-07-13 11:26:12 * @FilePath: /CasaOS/middleware/gin.go * @Description: * @Website: https://www.casaos.io @@ -26,14 +26,14 @@ func Cors() gin.HandlerFunc { c.Header("Access-Control-Allow-Origin", "*") c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE") //允许跨域设置可以返回其他子段,可以自定义字段 - c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,Language") + c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,Language,Content-Type,Access-Control-Allow-Origin,Access-Control-Allow-Headers,Access-Control-Allow-Methods,Connection,Host,Origin,Referer,User-Agent,X-Requested-With") // 允许浏览器(客户端)可以解析的头部 (重要) c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers") //c.Writer.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type, Content-Length, X-CSRF-Token, Token, session, Origin, Host, Connection, Accept-Encoding, Accept-Language, X-Requested-With") //设置缓存时间 c.Header("Access-Control-Max-Age", "172800") c.Header("Access-Control-Allow-Credentials", "true") - c.Set("content-type", "application/json") + c.Set("Content-Type", "application/json") //} //允许类型校验 diff --git a/model/app-analyse.go b/model/app-analyse.go deleted file mode 100644 index 70ce46c..0000000 --- a/model/app-analyse.go +++ /dev/null @@ -1,27 +0,0 @@ -/* - * @Author: LinkLeong link@icewhale.com - * @Date: 2022-03-18 11:40:55 - * @LastEditors: LinkLeong - * @LastEditTime: 2022-05-13 14:48:01 - * @FilePath: /CasaOS/model/app-analyse.go - * @Description: - * @Website: https://www.casaos.io - * Copyright (c) 2022 by icewhale, All Rights Reserved. - */ -package model - -type AppAnalyse struct { - Name string `json:"name"` - Type string `json:"type"` - UUId string `json:"uuid"` - Language string `json:"language"` - Version string `json:"version"` -} - -type ConnectionStatus struct { - From string `json:"from"` - To string `json:"to"` - Error string `json:"error"` - UUId string `json:"uuid"` - Event string `json:"event"` -} diff --git a/model/app.go b/model/app.go index 387e437..d195132 100644 --- a/model/app.go +++ b/model/app.go @@ -13,6 +13,15 @@ type ServerAppListCollection struct { Version string `json:"version"` } +// @tiger - 对于用于出参的数据结构,静态信息(例如 title)和 +// 动态信息(例如 state、query_count)应该划分到不同的数据结构中 +// +// 这样的好处是 +// 1 - 多次获取动态信息时可以减少出参复杂度,因为静态信息只获取一次就好 +// 2 - 在未来的迭代中,可以降低维护成本(所有字段都展开放在一个层级维护成本略高) +// +// 另外,一些针对性字段,例如 Docker 相关的,可以用 map 来保存。 +// 这样在未来增加多态 App,例如 Snap,不需要维护多个结构,或者一个结构保存不必要的字段 type ServerAppList struct { Id uint `gorm:"column:id;primary_key" json:"id"` Title string `json:"title"` diff --git a/model/category.go b/model/category.go index 3ee71a0..3005491 100644 --- a/model/category.go +++ b/model/category.go @@ -2,10 +2,9 @@ * @Author: link a624669980@163.com * @Date: 2022-05-16 17:37:08 * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-22 17:45:53 + * @LastEditTime: 2022-07-13 10:46:38 * @FilePath: /CasaOS/model/category.go - * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE - + * @Description: */ package model @@ -18,7 +17,7 @@ type CategoryList struct { //CreatedAt time.Time `json:"created_at"` // //UpdatedAt time.Time `json:"updated_at"` - Font string `json:"font"` + Font string `json:"font"` // @tiger - 如果这个和前端有关,应该不属于后端的出参范围,而是前端去界定 Name string `json:"name"` - Count uint `json:"count"` + Count uint `json:"count"` // @tiger - count 属于动态信息,应该单独放在一个出参结构中(原因见另外一个关于 静态/动态 出参的注释) } diff --git a/model/disk.go b/model/disk.go index b58049b..dd48976 100644 --- a/model/disk.go +++ b/model/disk.go @@ -1,3 +1,13 @@ +/* + * @Author: LinkLeong link@icewhale.com + * @Date: 2022-07-13 10:43:45 + * @LastEditors: LinkLeong + * @LastEditTime: 2022-07-13 11:00:04 + * @FilePath: /CasaOS/model/disk.go + * @Description: + * @Website: https://www.casaos.io + * Copyright (c) 2022 by icewhale, All Rights Reserved. + */ package model type LSBLKModel struct { @@ -53,8 +63,8 @@ type DriveUSB struct { Size uint64 `json:"size"` Used uint64 `json:"use"` Model string `json:"model"` - Mount bool `json:"mount"` //是否完全挂载 - Avail uint64 `json:"avail"` //可用空间 + Mount bool `json:"mount"` + Avail uint64 `json:"avail"` } type Storage struct { diff --git a/model/docker.go b/model/docker.go index 59b006d..a083319 100644 --- a/model/docker.go +++ b/model/docker.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2021-12-08 18:10:25 * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-14 17:20:36 + * @LastEditTime: 2022-07-13 10:49:16 * @FilePath: /CasaOS/model/docker.go * @Description: * @Website: https://www.casaos.io @@ -11,8 +11,8 @@ package model type DockerStatsModel struct { - Icon string `json:"icon"` - Title string `json:"title"` - Data interface{} `json:"data"` - Pre interface{} `json:"pre"` + Icon string `json:"icon"` + Title string `json:"title"` + Data interface{} `json:"data"` + Previous interface{} `json:"previous"` } diff --git a/model/manifest.go b/model/manifest.go index 541c4a4..0888fb0 100644 --- a/model/manifest.go +++ b/model/manifest.go @@ -104,16 +104,17 @@ func (p *PathArray) Scan(input interface{}) error { //} type CustomizationPostData struct { - CustomId string `json:"custom_id"` - Origin string `json:"origin"` - NetworkModel string `json:"network_model"` - Index string `json:"index"` - Icon string `json:"icon"` - Image string `json:"image"` - Envs EnvArray `json:"envs"` - Ports PortArray `json:"ports"` - Volumes PathArray `json:"volumes"` - Devices PathArray `json:"devices"` + ContainerName string `json:"container_name"` + CustomId string `json:"custom_id"` + Origin string `json:"origin"` + NetworkModel string `json:"network_model"` + Index string `json:"index"` + Icon string `json:"icon"` + Image string `json:"image"` + Envs EnvArray `json:"envs"` + Ports PortArray `json:"ports"` + Volumes PathArray `json:"volumes"` + Devices PathArray `json:"devices"` //Port string `json:"port,omitempty"` PortMap string `json:"port_map"` CpuShares int64 `json:"cpu_shares"` diff --git a/model/notify/person.go b/model/notify/person.go deleted file mode 100644 index a2b903b..0000000 --- a/model/notify/person.go +++ /dev/null @@ -1,16 +0,0 @@ -/* - * @Author: LinkLeong link@icewhale.com - * @Date: 2022-05-27 18:42:42 - * @LastEditors: LinkLeong - * @LastEditTime: 2022-05-27 18:43:08 - * @FilePath: /CasaOS/model/notify/person.go - * @Description: - * @Website: https://www.casaos.io - * Copyright (c) 2022 by icewhale, All Rights Reserved. - */ -package notify - -type Person struct { - ShareId string `json:"share_id"` - Type string `json:"type"` -} diff --git a/model/notify/storage.go b/model/notify/storage.go new file mode 100644 index 0000000..0c62970 --- /dev/null +++ b/model/notify/storage.go @@ -0,0 +1,19 @@ +/* + * @Author: LinkLeong link@icewhale.com + * @Date: 2022-07-15 10:43:00 + * @LastEditors: LinkLeong + * @LastEditTime: 2022-07-15 10:56:17 + * @FilePath: /CasaOS/model/notify/storage.go + * @Description: + * @Website: https://www.casaos.io + * Copyright (c) 2022 by icewhale, All Rights Reserved. + */ +package notify + +type StorageMessage struct { + Type string `json:"type"` //sata,usb + Action string `json:"action"` //remove add + Path string `json:"path"` + Volume string `json:"volume"` + Size uint64 `json:"size"` +} diff --git a/model/person.go b/model/person.go deleted file mode 100644 index d8a119a..0000000 --- a/model/person.go +++ /dev/null @@ -1,54 +0,0 @@ -package model - -import "time" - -type PersionModel struct { - Token string `json:"token"` - Ips []string `json:"ips"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` -} - -//记录链接状态 -type ConnectState struct { - From string `json:"from"` - To string `json:"to"` - Type string `json:"type"` //current state 1:ready 2:ok - CreatedAt time.Time `json:"created_at"` - UUId string `json:"uuid"` //对接标识 -} -type MessageModel struct { - Type string `json:"type"` - Data interface{} `json:"data"` - UUId string `json:"uuid"` - From string `json:"from"` - To string `json:"to"` -} - -type TranFileModel struct { - Hash string `json:"hash"` //Verify current fragment integrity - Length int `json:"length"` - Index int `json:"index"` -} - -//需要获取文件详情 -type FileDetailModel struct { - Path string `json:"path"` -} - -//返回文件详情 -type FileSummaryModel struct { - Hash string `json:"hash"` //Verify file - Name string `json:"name"` - BlockSize int `json:"block_size"` - Length int `json:"length"` - Size int64 `json:"size"` - Message string `json:"message"` -} - -type FriendsModel struct { - Id uint `gorm:"column:id;primary_key" json:"id"` - NickName string `json:"nick_name"` - Desc string `json:"desc"` - ShareId string `json:"share_id"` -} diff --git a/model/sys_common.go b/model/sys_common.go index 68d9786..162757d 100644 --- a/model/sys_common.go +++ b/model/sys_common.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2022-05-13 18:15:46 * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-16 17:50:56 + * @LastEditTime: 2022-07-14 11:02:06 * @FilePath: /CasaOS/model/sys_common.go * @Description: * @Website: https://www.casaos.io @@ -37,9 +37,7 @@ type ServerModel struct { RunMode string ServerApi string LockAccount bool - Handshake string Token string - UDPPort string USBAutoMount string SocketPort string } @@ -76,12 +74,7 @@ type RedisModel struct { } type SystemConfig struct { - ConfigStr string `json:"config_str"` - WidgetList string `json:"widget_list"` ConfigPath string `json:"config_path"` - SyncPort string `json:"sync_port"` - SyncKey string `json:"sync_key"` - Analyse string `json:"analyse"` } type CasaOSGlobalVariables struct { diff --git a/pkg/config/init.go b/pkg/config/init.go index efa495f..738ecc5 100644 --- a/pkg/config/init.go +++ b/pkg/config/init.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2022-05-13 18:15:46 * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-21 16:01:26 + * @LastEditTime: 2022-07-14 10:58:45 * @FilePath: /CasaOS/pkg/config/init.go * @Description: * @Website: https://www.casaos.io diff --git a/pkg/docker/helper.go b/pkg/docker/helper.go index 115f085..be76b7d 100644 --- a/pkg/docker/helper.go +++ b/pkg/docker/helper.go @@ -6,7 +6,6 @@ import ( "fmt" "io" "regexp" - "strconv" "sync" "time" @@ -15,7 +14,7 @@ import ( "golang.org/x/crypto/ssh" ) -func NewSshClient(user, password string) (*ssh.Client, error) { +func NewSshClient(user, password string, port string) (*ssh.Client, error) { // connet to ssh // addr = fmt.Sprintf("%s:%d", host, port) @@ -32,7 +31,7 @@ func NewSshClient(user, password string) (*ssh.Client, error) { //} else { // config.Auth = []ssh.AuthMethod{publicKeyAuthFunc(h.Key)} //} - addr := fmt.Sprintf("%s:%d", "127.0.0.1", 22) + addr := fmt.Sprintf("%s:%s", "127.0.0.1", port) c, err := ssh.Dial("tcp", addr, config) if err != nil { return nil, err @@ -396,7 +395,7 @@ func WsReaderCopy(reader *websocket.Conn, writer io.Writer) { if err = json2.Unmarshal(p, &msgObj); err != nil { writer.Write(p) } else if msgObj.Type == wsMsgResize { - writer.Write([]byte("stty rows " + strconv.Itoa(msgObj.Rows) + " && stty cols " + strconv.Itoa(msgObj.Cols) + " \r")) + //writer.Write([]byte("stty rows " + strconv.Itoa(msgObj.Rows) + " && stty cols " + strconv.Itoa(msgObj.Cols) + " \r")) } } } diff --git a/pkg/sqlite/db.go b/pkg/sqlite/db.go index b395b0e..3503cd0 100644 --- a/pkg/sqlite/db.go +++ b/pkg/sqlite/db.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2022-05-13 18:15:46 * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-22 18:50:44 + * @LastEditTime: 2022-07-11 18:10:53 * @FilePath: /CasaOS/pkg/sqlite/db.go * @Description: * @Website: https://www.casaos.io @@ -42,8 +42,22 @@ func GetDb(dbPath string) *gorm.DB { return nil } gdb = db - err = db.AutoMigrate(&model2.AppNotify{}, &model2.AppListDBModel{}, &model2.SerialDisk{}, model2.PersonDownloadDBModel{}, model2.FriendModel{}, model2.PersonDownRecordDBModel{}, model2.UserDBModel{}) + + db.Exec(`alter table o_user rename to old_user; + + create table o_users ( id integer primary key,username text,password text,role text,email text,nickname text,avatar text,description text,created_at datetime,updated_at datetime); + + insert into o_users select id,user_name,password,role,email,nick_name,avatar,description,created_at,updated_at from old_user; + + drop table old_user; + drop table o_user; + `) + + err = db.AutoMigrate(&model2.AppNotify{}, &model2.AppListDBModel{}, &model2.SerialDisk{}, model2.UserDBModel{}) db.Exec("DROP TABLE IF EXISTS o_application") + db.Exec("DROP TABLE IF EXISTS o_friend") + db.Exec("DROP TABLE IF EXISTS o_person_download") + db.Exec("DROP TABLE IF EXISTS o_person_down_record") if err != nil { loger.Error("check or create db error", zap.Any("error", err)) } diff --git a/pkg/utils/common_err/e.go b/pkg/utils/common_err/e.go index e87e64d..79ee8cd 100644 --- a/pkg/utils/common_err/e.go +++ b/pkg/utils/common_err/e.go @@ -2,10 +2,11 @@ package common_err const ( SUCCESS = 200 - ERROR = 500 - INVALID_PARAMS = 400 + SERVICE_ERROR = 500 + CLIENT_ERROR = 400 ERROR_AUTH_TOKEN = 401 + INVALID_PARAMS = 4000 //user PWD_INVALID = 10001 PWD_IS_EMPTY = 10002 @@ -49,19 +50,12 @@ const ( //shortcuts SHORTCUTS_URL_ERROR = 70001 - - //person - PERSON_REMOTE_ERROR = 80001 - PERSON_DOWN_NOT_EXIST = 80002 - PERSON_EXIST_DOWNLOAD = 80003 - PERSON_NOT_EXIST_USER = 80004 - PERSON_EXIST_FRIEND = 80005 - PERSON_MYSELF = 80006 ) var MsgFlags = map[int]string{ SUCCESS: "ok", - ERROR: "fail", + SERVICE_ERROR: "Fail", + CLIENT_ERROR: "Fail", INVALID_PARAMS: "Parameters Error", ERROR_AUTH_TOKEN: "Error auth token", @@ -108,12 +102,6 @@ var MsgFlags = map[int]string{ FILE_DELETE_ERROR: "Delete error", SHORTCUTS_URL_ERROR: "URL error", - PERSON_REMOTE_ERROR: "Remote connection error", - PERSON_DOWN_NOT_EXIST: "Download record does not exist", - PERSON_EXIST_DOWNLOAD: "The same download task exists", - PERSON_EXIST_FRIEND: "Friend already exist", - PERSON_NOT_EXIST_USER: "User does not exist", - PERSON_MYSELF: "You can not add yourself", COMMAND_ERROR_INVALID_OPERATION: "invalid operation", } @@ -123,5 +111,5 @@ func GetMsg(code int) string { if ok { return msg } - return MsgFlags[ERROR] + return MsgFlags[SERVICE_ERROR] } diff --git a/pkg/utils/jwt/jwt.go b/pkg/utils/jwt/jwt.go index 18f619d..ad88197 100644 --- a/pkg/utils/jwt/jwt.go +++ b/pkg/utils/jwt/jwt.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2021-09-30 18:18:14 * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-24 10:02:46 + * @LastEditTime: 2022-07-18 17:30:38 * @FilePath: /CasaOS/pkg/utils/jwt/jwt.go * @Description: * @Website: https://www.casaos.io @@ -16,67 +16,26 @@ import ( jwt "github.com/golang-jwt/jwt/v4" ) -// type Claims struct { -// UserName string `json:"username"` -// PassWord string `json:"password"` -// Id int `json:"id"` -// jwt.RegisteredClaims -// } - -// var jwtSecret []byte - -// //创建token -// func GenerateToken(username, password string, id int, issuer string, t time.Duration) (string, error) { -// clims := Claims{ -// username, -// password, -// id, -// jwt.RegisteredClaims{ -// ExpiresAt: jwt.NewNumericDate(time.Now().Add(t)), -// IssuedAt: jwt.NewNumericDate(time.Now()), -// NotBefore: jwt.NewNumericDate(time.Now()), -// Issuer: issuer, -// }, -// } - -// tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, clims) -// token, err := tokenClaims.SignedString(jwtSecret) -// return token, err - -// } - -// //解析token -// func ParseToken(token string) (*Claims, error) { -// tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (interface{}, error) { -// return jwtSecret, nil -// }) -// if tokenClaims != nil { -// if clims, ok := tokenClaims.Claims.(*Claims); ok && tokenClaims.Valid { -// return clims, nil -// } -// } -// return nil, err -// } - -//****************** soon to be removed ****************** - type Claims struct { - UserName string `json:"username"` + Username string `json:"username"` PassWord string `json:"password"` - jwt.StandardClaims + Id int `json:"id"` + jwt.RegisteredClaims } var jwtSecret []byte //创建token -func GenerateToken(username, password string) (string, error) { - expireTime := time.Now().AddDate(999, 0, 0) +func GenerateToken(username, password string, id int, issuer string, t time.Duration) (string, error) { clims := Claims{ username, password, - jwt.StandardClaims{ - ExpiresAt: expireTime.Unix(), - Issuer: "gin-blog", + id, + jwt.RegisteredClaims{ + ExpiresAt: jwt.NewNumericDate(time.Now().Add(t)), + IssuedAt: jwt.NewNumericDate(time.Now()), + NotBefore: jwt.NewNumericDate(time.Now()), + Issuer: issuer, }, } @@ -87,13 +46,17 @@ func GenerateToken(username, password string) (string, error) { } //解析token -func ParseToken(token string) (*Claims, error) { +func ParseToken(token string, valid bool) (*Claims, error) { tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (interface{}, error) { return jwtSecret, nil }) if tokenClaims != nil { - if clims, ok := tokenClaims.Claims.(*Claims); ok && tokenClaims.Valid { - return clims, nil + if clims, ok := tokenClaims.Claims.(*Claims); ok { + if valid && tokenClaims.Valid { + return clims, nil + } else if !valid { + return clims, nil + } } } return nil, err diff --git a/pkg/utils/jwt/jwt_helper.go b/pkg/utils/jwt/jwt_helper.go index 068ac66..2c18e67 100644 --- a/pkg/utils/jwt/jwt_helper.go +++ b/pkg/utils/jwt/jwt_helper.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2022-06-17 14:01:25 * @LastEditors: LinkLeong - * @LastEditTime: 2022-07-04 16:26:22 + * @LastEditTime: 2022-07-18 17:31:15 * @FilePath: /CasaOS/pkg/utils/jwt/jwt_helper.go * @Description: * @Website: https://www.casaos.io @@ -11,65 +11,16 @@ package jwt import ( - "net/http" + "fmt" + "strconv" + "time" "github.com/IceWhaleTech/CasaOS/model" "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" + loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger" "github.com/gin-gonic/gin" ) -// func JWT() gin.HandlerFunc { -// return func(c *gin.Context) { -// var code int -// code = common_err.SUCCESS -// token := c.GetHeader("Authorization") -// if len(token) == 0 { -// token = c.Query("token") -// } -// if token == "" { -// code = common_err.INVALID_PARAMS -// } - -// claims, err := ParseToken(token) -// //_, err := ParseToken(token) -// if err != nil { -// code = common_err.ERROR_AUTH_TOKEN -// } else if !claims.VerifyExpiresAt(time.Now(), true) || !claims.VerifyIssuer("casaos", true) { -// code = common_err.ERROR_AUTH_TOKEN -// } -// if code != common_err.SUCCESS { -// c.JSON(code, model.Result{Success: code, Message: common_err.GetMsg(code)}) -// c.Abort() -// return -// } -// c.Request.Header.Add("user_id", strconv.Itoa(claims.Id)) -// c.Next() -// } -// } - -// //get AccessToken -// func GetAccessToken(username, pwd string, id int) string { -// token, err := GenerateToken(username, pwd, id, "casaos", 3*time.Hour*time.Duration(1)) -// if err == nil { -// return token -// } else { -// loger2.Error(fmt.Sprintf("Get Token Fail: %V", err)) -// return "" -// } -// } - -// func GetRefreshToken(username, pwd string, id int) string { -// token, err := GenerateToken(username, pwd, id, "fresh", 7*24*time.Hour*time.Duration(1)) -// if err == nil { -// return token -// } else { -// loger2.Error(fmt.Sprintf("Get Token Fail: %V", err)) -// return "" -// } -// } - -//*************** soon to be removed ***************** - func JWT() gin.HandlerFunc { return func(c *gin.Context) { var code int @@ -82,32 +33,43 @@ func JWT() gin.HandlerFunc { code = common_err.INVALID_PARAMS } - //claims, err := ParseToken(token) - _, err := ParseToken(token) + claims, err := ParseToken(token, false) + + //_, err := ParseToken(token) if err != nil { code = common_err.ERROR_AUTH_TOKEN - + } else if (c.Request.URL.Path == "/v1/file" || c.Request.URL.Path == "/v1/image" || c.Request.URL.Path == "/v1/file/upload" || c.Request.URL.Path == "/v1/batch") && claims.VerifyIssuer("casaos", true) { + //Special treatment + } else if !claims.VerifyExpiresAt(time.Now(), true) || !claims.VerifyIssuer("casaos", true) { + code = common_err.ERROR_AUTH_TOKEN } - //else if time.Now().Unix() > claims.ExpiresAt { - // code = oasis_err2.ERROR_AUTH_TOKEN - //} - if code != common_err.SUCCESS { - c.JSON(http.StatusOK, model.Result{Success: code, Message: common_err.GetMsg(code)}) + c.JSON(code, model.Result{Success: code, Message: common_err.GetMsg(code)}) c.Abort() return } + c.Request.Header.Add("user_id", strconv.Itoa(claims.Id)) c.Next() } } -//获取token -func GetToken(username, pwd string) string { - token, err := GenerateToken(username, pwd) +//get AccessToken +func GetAccessToken(username, pwd string, id int) string { + token, err := GenerateToken(username, pwd, id, "casaos", 3*time.Hour*time.Duration(1)) if err == nil { return token } else { - //loger2.NewOLoger().Fatal(fmt.Sprintf("Get Token Fail: %V", err)) + loger2.Error(fmt.Sprintf("Get Token Fail: %V", err)) + return "" + } +} + +func GetRefreshToken(username, pwd string, id int) string { + token, err := GenerateToken(username, pwd, id, "refresh", 7*24*time.Hour*time.Duration(1)) + if err == nil { + return token + } else { + loger2.Error(fmt.Sprintf("Get Token Fail: %V", err)) return "" } } diff --git a/pkg/utils/version/version.go b/pkg/utils/version/version.go index de857d2..8752f4a 100644 --- a/pkg/utils/version/version.go +++ b/pkg/utils/version/version.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2022-05-13 18:15:46 * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-29 14:29:34 + * @LastEditTime: 2022-07-21 15:27:53 * @FilePath: /CasaOS/pkg/utils/version/version.go * @Description: * @Website: https://www.casaos.io @@ -33,9 +33,6 @@ func IsNeedUpdate(version model.Version) (bool, model.Version) { for i := 0; i < len(v1); i++ { a, _ := strconv.Atoi(v1[i]) b, _ := strconv.Atoi(v2[i]) - if i == 0 && a > b { - continue - } if a > b { return true, version } diff --git a/route/init.go b/route/init.go index 6967c7f..7aedb2f 100644 --- a/route/init.go +++ b/route/init.go @@ -1,30 +1,21 @@ package route import ( - "encoding/xml" - "fmt" "os" - "path/filepath" - "runtime" "strconv" "strings" - "time" - "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/model/system_app" "github.com/IceWhaleTech/CasaOS/pkg/config" "github.com/IceWhaleTech/CasaOS/pkg/utils/command" "github.com/IceWhaleTech/CasaOS/pkg/utils/encryption" - "github.com/IceWhaleTech/CasaOS/pkg/utils/env_helper" "github.com/IceWhaleTech/CasaOS/pkg/utils/file" - "github.com/IceWhaleTech/CasaOS/pkg/utils/port" "github.com/IceWhaleTech/CasaOS/service" model2 "github.com/IceWhaleTech/CasaOS/service/model" uuid "github.com/satori/go.uuid" ) func InitFunction() { - go checkSystemApp() + ShellInit() CheckSerialDiskMount() @@ -35,132 +26,6 @@ func InitFunction() { MoveUserToDB() } -var syncIsExistence = false - -func installSyncthing(appId string) { - - var appInfo model.ServerAppList - m := model.CustomizationPostData{} - var dockerImage string - var dockerImageVersion string - appInfo = service.MyService.Casa().GetServerAppInfo(appId, "system", "us_en") - dockerImage = appInfo.Image - dockerImageVersion = appInfo.ImageVersion - - if len(appInfo.ImageVersion) == 0 { - dockerImageVersion = "latest" - } - - if appInfo.NetworkModel != "host" { - for i := 0; i < len(appInfo.Ports); i++ { - if p, _ := strconv.Atoi(appInfo.Ports[i].ContainerPort); port.IsPortAvailable(p, appInfo.Ports[i].Protocol) { - appInfo.Ports[i].CommendPort = strconv.Itoa(p) - } else { - if appInfo.Ports[i].Protocol == "tcp" { - if p, err := port.GetAvailablePort("tcp"); err == nil { - appInfo.Ports[i].CommendPort = strconv.Itoa(p) - } - } else if appInfo.Ports[i].Protocol == "upd" { - if p, err := port.GetAvailablePort("udp"); err == nil { - appInfo.Ports[i].CommendPort = strconv.Itoa(p) - } - } - } - - if appInfo.Ports[i].Type == 0 { - appInfo.PortMap = appInfo.Ports[i].CommendPort - } - } - } - - for i := 0; i < len(appInfo.Devices); i++ { - if !file.CheckNotExist(appInfo.Devices[i].ContainerPath) { - appInfo.Devices[i].Path = appInfo.Devices[i].ContainerPath - } - } - if len(appInfo.Tip) > 0 { - appInfo.Tip = env_helper.ReplaceStringDefaultENV(appInfo.Tip) - } - - appInfo.MaxMemory = service.MyService.System().GetMemInfo()["total"].(uint64) >> 20 - - id := uuid.NewV4().String() - - // step:下载镜像 - err := service.MyService.Docker().DockerPullImage(dockerImage+":"+dockerImageVersion, "", "") - if err != nil { - //pull image error - fmt.Println("pull image error", err, dockerImage, dockerImageVersion) - return - } - for !service.MyService.Docker().IsExistImage(dockerImage + ":" + dockerImageVersion) { - time.Sleep(time.Second) - } - - m.CpuShares = 50 - m.Envs = appInfo.Envs - m.Memory = int64(appInfo.MaxMemory) - m.Origin = "system" - m.PortMap = appInfo.PortMap - m.Ports = appInfo.Ports - m.Restart = "always" - m.Volumes = appInfo.Volumes - m.NetworkModel = appInfo.NetworkModel - m.Label = id - m.CustomId = id - containerId, err := service.MyService.Docker().DockerContainerCreate(dockerImage+":"+dockerImageVersion, m) - if err != nil { - fmt.Println("container create error", err) - // create container error - return - } - - //step:start container - err = service.MyService.Docker().DockerContainerStart(containerId) - if err != nil { - //start container error - return - } - - checkSystemApp() -} - -// check if the system application is installed -func checkSystemApp() { - list := service.MyService.App().GetSystemAppList() - for _, v := range list { - info, err := service.MyService.Docker().DockerContainerInfo(v.ID) - if err != nil { - continue - } - if strings.Contains(info.Config.Image, "linuxserver/syncthing") { - if v.State != "running" { - //step:start container - service.MyService.Docker().DockerContainerStart(v.ID) - } - syncIsExistence = true - if config.SystemConfigInfo.SyncPort != v.Labels["web"] { - config.SystemConfigInfo.SyncPort = v.Labels["web"] - } - - path := "" - for _, i := range info.Mounts { - if i.Destination == "/config" { - path = i.Source - break - } - } - content := file.ReadFullFile(filepath.Join(path, "config.xml")) - syncConfig := &system_app.SyncConfig{} - xml.Unmarshal(content, &syncConfig) - config.SystemConfigInfo.SyncKey = syncConfig.Key - break - } - } - if !syncIsExistence { - installSyncthing("74") - } -} func CheckSerialDiskMount() { // check mount point dbList := service.MyService.Disk().GetSerialAll() @@ -216,31 +81,11 @@ func CheckToken2_11() { config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath) } - sysType := runtime.GOOS - if len(config.FileSettingInfo.DownloadDir) == 0 { - downloadPath := "/DATA/Downloads" - if sysType == "windows" { - downloadPath = "C:\\CasaOS\\DATA\\Downloads" - } - if sysType == "darwin" { - downloadPath = "./CasaOS/DATA/Downloads" - } - config.Cfg.Section("file").Key("DownloadDir").SetValue(downloadPath) - config.FileSettingInfo.DownloadDir = downloadPath - file.IsNotExistMkDir(config.FileSettingInfo.DownloadDir) - config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath) - } - if len(config.UserInfo.Description) == 0 { config.Cfg.Section("user").Key("Description").SetValue("nothing") config.UserInfo.Description = "nothing" config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath) } - if len(config.ServerInfo.Handshake) == 0 { - config.Cfg.Section("server").Key("Handshake").SetValue("socket.casaos.io") - config.ServerInfo.Handshake = "socket.casaos.io" - config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath) - } if service.MyService.System().GetSysInfo().KernelArch == "aarch64" && config.ServerInfo.USBAutoMount != "True" && strings.Contains(service.MyService.System().GetDeviceTree(), "Raspberry Pi") { service.MyService.System().UpdateUSBAutoMount("False") @@ -279,9 +124,9 @@ func MoveUserToDB() { if len(config.UserInfo.UserName) > 0 && service.MyService.User().GetUserInfoByUserName(config.UserInfo.UserName).Id == 0 { user := model2.UserDBModel{} - user.UserName = config.UserInfo.UserName + user.Username = config.UserInfo.UserName user.Email = config.UserInfo.Email - user.NickName = config.UserInfo.NickName + user.Nickname = config.UserInfo.NickName user.Password = encryption.GetMD5ByStr(config.UserInfo.PWD) user.Role = "admin" user = service.MyService.User().CreateUser(user) diff --git a/route/periodical.go b/route/periodical.go index 4ee7d8c..0740ab2 100644 --- a/route/periodical.go +++ b/route/periodical.go @@ -2,17 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2022-07-01 15:11:36 * @LastEditors: LinkLeong - * @LastEditTime: 2022-07-01 15:16:00 - * @FilePath: /CasaOS/route/periodical.go - * @Description: - * @Website: https://www.casaos.io - * Copyright (c) 2022 by icewhale, All Rights Reserved. - */ -/* - * @Author: LinkLeong link@icewhale.com - * @Date: 2022-05-27 15:55:36 - * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-29 16:47:19 + * @LastEditTime: 2022-07-21 15:25:07 * @FilePath: /CasaOS/route/periodical.go * @Description: * @Website: https://www.casaos.io diff --git a/route/route.go b/route/route.go index 5d5c032..22d8aa8 100644 --- a/route/route.go +++ b/route/route.go @@ -23,6 +23,7 @@ func InitRouter() *gin.Engine { r.Use(middleware.WriteLog()) r.Use(gzip.Gzip(gzip.DefaultCompression)) gin.SetMode(config.ServerInfo.RunMode) + r.StaticFS("/ui", http.FS(web.Static)) r.GET("/", WebUIHome) // r.StaticFS("/assets", http.Dir("./static/assets")) @@ -31,199 +32,191 @@ func InitRouter() *gin.Engine { // c.Redirect(http.StatusMovedPermanently, "ui/") //}) - r.POST("/v1/user/register/:key", v1.PostUserRegister) - r.POST("/v1/user/login", v1.PostUserLogin) // - r.GET("/v1/user/all/name", v1.GetUserAllUserName) + r.POST("/v1/users/register", v1.PostUserRegister) + r.POST("/v1/users/login", v1.PostUserLogin) + r.GET("/v1/users/name", v1.GetUserAllUsername) //all/name + r.POST("/v1/user/refresh", v1.PostUserRefreshToken) + // No short-term modifications + r.GET("/v1/users/image", v1.GetUserImage) - r.GET("/v1/sys/init/check", v1.GetSystemInitCheck) - r.GET("/v1/guide/check", v1.GetGuideCheck) - r.GET("/v1/debug", v1.GetSystemConfigDebug) - r.POST("/v1/user/setusernamepwd", v1.Set_Name_Pwd) - r.GET("/v1/user/info/:id", v1.GetUserInfo) - r.GET("/v1/user/avatar/:id", v1.GetUserAvatar) - r.GET("/v1/user/image", v1.GetUserImage) + r.GET("/v1/users/status", v1.GetUserStatus) //init/check + //r.GET("/v1/guide/check", v1.GetGuideCheck) // /v1/sys/guide_check + r.GET("/v1/sys/debug", v1.GetSystemConfigDebug) // //debug + + r.GET("/v1/sys/socket-port", v1.GetSystemSocketPort) //sys/socket_port - //get user info - r.GET("/v1/person/shareid", v1.GetPersonShareId) - r.GET("/v1/sys/socket/port", v1.GetSystemSocketPort) - //r.POST("/v1/user/refresh/token", v1.PostUserRefreshToken) v1Group := r.Group("/v1") v1Group.Use(jwt2.JWT()) { - v1UserGroup := v1Group.Group("/user") - v1UserGroup.Use() + v1UsersGroup := v1Group.Group("/users") + v1UsersGroup.Use() { + v1UsersGroup.GET("/current", v1.GetUserInfo) + v1UsersGroup.PUT("/current", v1.PutUserInfo) + v1UsersGroup.PUT("/current/password", v1.PutUserPassword) - //****************** New version needs to be modified start ****************** - //chang user name - v1UserGroup.PUT("/username", v1.PutUserName) - v1UserGroup.PUT("/password", v1.PutUserPwd) - v1UserGroup.PUT("/nick", v1.PutUserNick) - v1UserGroup.PUT("/desc", v1.PutUserDesc) - v1UserGroup.GET("/info", v1.GetUserInfoByUserName) - v1UserGroup.GET("/custom/:id/:key", v1.GetUserCustomConf) - v1UserGroup.POST("/custom/:id/:key", v1.PostUserCustomConf) - v1UserGroup.DELETE("/custom/:id/:key", v1.DeleteUserCustomConf) - v1UserGroup.POST("/upload/image/:id/:key", v1.PostUserUploadImage) - v1UserGroup.POST("/file/image/:id/:key", v1.PostUserFileImage) - v1UserGroup.DELETE("/image/:id", v1.DeleteUserImage) - //****************** New version needs to be modified end ****************** + v1UsersGroup.GET("/current/custom/:key", v1.GetUserCustomConf) + v1UsersGroup.POST("/current/custom/:key", v1.PostUserCustomConf) + v1UsersGroup.DELETE("/current/custom/:key", v1.DeleteUserCustomConf) - //****************** soon to be removed start ****************** - v1UserGroup.POST("/person/info", v1.PostUserPersonInfo) - v1UserGroup.GET("/shareid", v1.GetUserShareID) - //****************** soon to be removed end ****************** + v1UsersGroup.POST("/current/image/:key", v1.PostUserUploadImage) + v1UsersGroup.PUT("/current/image/:key", v1.PutUserImage) + //v1UserGroup.POST("/file/image/:key", v1.PostUserFileImage) + v1UsersGroup.DELETE("/current/image", v1.DeleteUserImage) - //v1UserGroup.GET("/info", v1.GetUserInfo) + //v1UserGroup.PUT("/avatar", v1.PutUserAvatar) + //v1UserGroup.GET("/avatar", v1.GetUserAvatar) + v1UsersGroup.DELETE("/:id", v1.DeleteUser) + v1UsersGroup.GET("/:username", v1.GetUserInfoByUsername) + v1UsersGroup.DELETE("", v1.DeleteUserAll) + } - v1UserGroup.PUT("/avatar", v1.PutUserAvatar) - v1UserGroup.GET("/avatar", v1.GetUserAvatar) - v1UserGroup.DELETE("/delete/:id", v1.DeleteUser) + v1AppsGroup := v1Group.Group("/apps") + v1AppsGroup.Use() + { + v1AppsGroup.GET("", v1.AppList) //list + v1AppsGroup.GET("/:id", v1.AppInfo) + } + v1ContainerGroup := v1Group.Group("/container") + v1ContainerGroup.Use() + { + v1ContainerGroup.GET("", v1.MyAppList) ///my/list + v1ContainerGroup.GET("/usage", v1.AppUsageList) + v1ContainerGroup.GET("/:id", v1.ContainerUpdateInfo) ///update/:id/info + v1ContainerGroup.GET("/:id/logs", v1.ContainerLog) // /app/logs/:id + v1ContainerGroup.GET("/networks", v1.GetDockerNetworks) //app/install/config + + v1ContainerGroup.GET("/:id/state", v1.GetContainerState) //app/state/:id ?state=install_progress + // there are problems, temporarily do not deal with + v1ContainerGroup.GET("/:id/terminal", v1.DockerTerminal) //app/terminal/:id + v1ContainerGroup.POST("", v1.InstallApp) //app/install + //v1ContainerGroup.GET("/:id", v1.ContainerInfo) // /app/info/:id + + v1ContainerGroup.PUT("/:id", v1.UpdateSetting) ///update/:id/setting + + v1ContainerGroup.PUT("/:id/state", v1.ChangAppState) // /app/state/:id + v1ContainerGroup.DELETE("/:id", v1.UnInstallApp) //app/uninstall/:id + //Not used + v1ContainerGroup.PUT("/:id/latest", v1.PutAppUpdate) + //Not used + v1ContainerGroup.POST("/share", v1.ShareAppFile) } - v1AppGroup := v1Group.Group("/app") - v1AppGroup.Use() + v1AppCategoriesGroup := v1Group.Group("/app-categories") + v1AppCategoriesGroup.Use() { - //获取我的已安装的列表 - v1AppGroup.GET("/my/list", v1.MyAppList) - // - v1AppGroup.GET("/usage", v1.AppUsageList) - //app详情 - v1AppGroup.GET("/appinfo/:id", v1.AppInfo) - //获取未安装的列表 - v1AppGroup.GET("/list", v1.AppList) - //获取端口 - v1AppGroup.GET("/port", v1.GetPort) - //检查端口 - v1AppGroup.GET("/check/:port", v1.PortCheck) - - v1AppGroup.GET("/category", v1.CategoryList) - - v1AppGroup.GET("/terminal/:id", v1.DockerTerminal) - //app容器详情 - v1AppGroup.GET("/info/:id", v1.ContainerInfo) - //app容器日志 - v1AppGroup.GET("/logs/:id", v1.ContainerLog) - //暂停或启动容器 - v1AppGroup.PUT("/state/:id", v1.ChangAppState) - //安装app - v1AppGroup.POST("/install", v1.InstallApp) - //卸载app - v1AppGroup.DELETE("/uninstall/:id", v1.UnInstallApp) - //获取进度 - v1AppGroup.GET("/state/:id", v1.GetContainerState) - //更新容器配置 - v1AppGroup.PUT("/update/:id/setting", v1.UpdateSetting) - //获取可能新数据 - v1AppGroup.GET("/update/:id/info", v1.ContainerUpdateInfo) - v1AppGroup.GET("/rely/:id/info", v1.ContainerRelyInfo) - v1AppGroup.GET("/install/config", v1.GetDockerInstallConfig) - v1AppGroup.PUT("/update/:id", v1.PutAppUpdate) - v1AppGroup.POST("/share", v1.ShareAppFile) + v1AppCategoriesGroup.GET("", v1.CategoryList) } v1SysGroup := v1Group.Group("/sys") v1SysGroup.Use() { - v1SysGroup.GET("/version/check", v1.GetSystemCheckVersion) - v1SysGroup.GET("/hardware/info", v1.GetSystemHardwareInfo) + v1SysGroup.GET("/version", v1.GetSystemCheckVersion) //version/check v1SysGroup.POST("/update", v1.SystemUpdate) + + v1SysGroup.GET("/hardware", v1.GetSystemHardwareInfo) //hardware/info + v1SysGroup.GET("/wsssh", v1.WsSsh) - v1SysGroup.GET("/config", v1.GetSystemConfig) + v1SysGroup.POST("/ssh-login", v1.PostSshLogin) + //v1SysGroup.GET("/config", v1.GetSystemConfig) //delete //v1SysGroup.POST("/config", v1.PostSetSystemConfig) - v1SysGroup.GET("/error/logs", v1.GetCasaOSErrorLogs) - v1SysGroup.GET("/widget/config", v1.GetWidgetConfig) - v1SysGroup.POST("/widget/config", v1.PostSetWidgetConfig) + v1SysGroup.GET("/logs", v1.GetCasaOSErrorLogs) //error/logs + //v1SysGroup.GET("/widget/config", v1.GetWidgetConfig)//delete + //v1SysGroup.POST("/widget/config", v1.PostSetWidgetConfig)//delete + + v1SysGroup.POST("/stop", v1.PostKillCasaOS) + + v1SysGroup.GET("/utilization", v1.GetSystemUtilization) + // v1SysGroup.GET("/cpu", v1.GetSystemCupInfo) + // v1SysGroup.GET("/mem", v1.GetSystemMemInfo) + // v1SysGroup.GET("/disk", v1.GetSystemDiskInfo) + // v1SysGroup.GET("/network", v1.GetSystemNetInfo) + + v1SysGroup.PUT("/usb-auto-mount", v1.PutSystemUSBAutoMount) ///sys/usb/:status + v1SysGroup.GET("/usb-auto-mount", v1.GetSystemUSBAutoMount) ///sys/usb/status + + v1SysGroup.GET("/server-info", nil) + v1SysGroup.PUT("/server-info", nil) + v1SysGroup.GET("/apps-state", v1.GetSystemAppsStatus) v1SysGroup.GET("/port", v1.GetCasaOSPort) v1SysGroup.PUT("/port", v1.PutCasaOSPort) - v1SysGroup.POST("/stop", v1.PostKillCasaOS) - v1SysGroup.GET("/utilization", v1.GetSystemUtilization) - v1SysGroup.PUT("/usb/:status", v1.PutSystemUSBAutoMount) - v1SysGroup.GET("/usb/status", v1.GetSystemUSBAutoMount) - v1SysGroup.GET("/cpu", v1.GetSystemCupInfo) - v1SysGroup.GET("/mem", v1.GetSystemMemInfo) - v1SysGroup.GET("/disk", v1.GetSystemDiskInfo) - v1SysGroup.GET("/network", v1.GetSystemNetInfo) } + v1PortGroup := v1Group.Group("/port") + v1PortGroup.Use() + { + v1PortGroup.GET("/", v1.GetPort) //app/port + v1PortGroup.GET("/state/:port", v1.PortCheck) //app/check/:port + } + v1FileGroup := v1Group.Group("/file") v1FileGroup.Use() { - v1FileGroup.PUT("/rename", v1.RenamePath) - v1FileGroup.GET("/read", v1.GetFilerContent) + v1FileGroup.GET("", v1.GetDownloadSingleFile) //download/:path + v1FileGroup.POST("", v1.PostCreateFile) + v1FileGroup.PUT("", v1.PutFileContent) + v1FileGroup.PUT("/name", v1.RenamePath) + //file/rename + v1FileGroup.GET("/content", v1.GetFilerContent) //file/read + + //File uploads need to be handled separately, and will not be modified here v1FileGroup.POST("/upload", v1.PostFileUpload) v1FileGroup.GET("/upload", v1.GetFileUpload) - v1FileGroup.GET("/dirpath", v1.DirPath) - //create folder - v1FileGroup.POST("/mkdir", v1.MkdirAll) - v1FileGroup.POST("/create", v1.PostCreateFile) - - v1FileGroup.GET("/download", v1.GetDownloadFile) - v1FileGroup.GET("/download/*path", v1.GetDownloadSingleFile) - v1FileGroup.POST("/operate", v1.PostOperateFileOrDir) - v1FileGroup.DELETE("/delete", v1.DeleteFile) - v1FileGroup.PUT("/update", v1.PutFileContent) - v1FileGroup.GET("/image", v1.GetFileImage) - v1FileGroup.DELETE("/operate/:id", v1.DeleteOperateFileOrDir) //v1FileGroup.GET("/download", v1.UserFileDownloadCommonService) } - v1DiskGroup := v1Group.Group("/disk") - v1DiskGroup.Use() + v1FolderGroup := v1Group.Group("/folder") + v1FolderGroup.Use() { - v1DiskGroup.GET("/check", v1.GetDiskCheck) - - v1DiskGroup.GET("/list", v1.GetDiskList) - - //获取磁盘详情 - v1DiskGroup.GET("/info", v1.GetDiskInfo) - - //format storage - v1DiskGroup.POST("/format", v1.PostDiskFormat) - - // add storage - v1DiskGroup.POST("/storage", v1.PostDiskAddPartition) - - //mount SATA disk - v1DiskGroup.POST("/mount", v1.PostMountDisk) - - //umount sata disk - v1DiskGroup.POST("/umount", v1.PostDiskUmount) - - //获取可以格式化的内容 - v1DiskGroup.GET("/type", v1.FormatDiskType) - - //删除分区 - v1DiskGroup.DELETE("/delpart", v1.RemovePartition) - v1DiskGroup.GET("/usb", v1.GetUSBList) - + v1FolderGroup.PUT("/name", v1.RenamePath) + v1FolderGroup.GET("", v1.DirPath) ///file/dirpath + v1FolderGroup.POST("", v1.MkdirAll) ///file/mkdir } - v1PersonGroup := v1Group.Group("/person") - v1PersonGroup.Use() + v1BatchGroup := v1Group.Group("/batch") + v1BatchGroup.Use() { - v1PersonGroup.GET("/detection", v1.GetPersonDetection) - v1PersonGroup.GET("/users", v1.GetPersonFriend) - v1PersonGroup.POST("/user/:shareids", v1.PostAddPersonFriend) - v1PersonGroup.DELETE("/user/:shareid", v1.DeletePersonFriend) - v1PersonGroup.GET("/directory", v1.GetPersonDirectory) - v1PersonGroup.GET("/file", v1.GetPersonFile) - v1PersonGroup.GET("/refile/:uuid", v1.GetPersonReFile) - v1PersonGroup.PUT("/remarks/:shareid", v1.PutPersonRemarks) - v1PersonGroup.GET("/list", v1.GetPersonDownloadList) - v1PersonGroup.DELETE("/file/:uuid", v1.DeletePersonDownloadFile) - - v1PersonGroup.POST("/share", v1.PostPersonShare) - v1PersonGroup.POST("/file/:shareid", v1.PostPersonFile) - v1PersonGroup.GET("/share", v1.GetPersonShare) - v1PersonGroup.POST("/down/dir", v1.PostPersonDownDir) - v1PersonGroup.GET("/down/dir", v1.GetPersonDownDir) - v1PersonGroup.PUT("/block/:shareid", v1.PutPersonBlock) - v1PersonGroup.GET("/public", v1.GetPersonPublic) - v1PersonGroup.PUT("/friend/:shareid", v1.PutPersonAgreeFriend) - v1PersonGroup.PUT("/write/:shareid", v1.PutPersonWrite) - v1PersonGroup.GET("/image/thumbnail/:shareid", v1.GetPersonImageThumbnail) + v1BatchGroup.DELETE("", v1.DeleteFile) //file/delete + v1BatchGroup.DELETE("/:id/task", v1.DeleteOperateFileOrDir) + v1BatchGroup.POST("/task", v1.PostOperateFileOrDir) //file/operate + v1BatchGroup.GET("", v1.GetDownloadFile) + } + v1ImageGroup := v1Group.Group("/image") + v1ImageGroup.Use() + { + v1ImageGroup.GET("", v1.GetFileImage) + } + + v1DisksGroup := v1Group.Group("/disks") + v1DisksGroup.Use() + { + //v1DiskGroup.GET("/check", v1.GetDiskCheck) //delete + //v1DisksGroup.GET("", v1.GetDiskInfo) + + //v1DisksGroup.POST("", v1.PostMountDisk) + v1DisksGroup.GET("", v1.GetDiskList) + // //format storage + // v1DiskGroup.POST("/format", v1.PostDiskFormat) + + // //mount SATA disk + // v1DiskGroup.POST("/mount", v1.PostMountDisk) + + // //umount sata disk + // v1DiskGroup.POST("/umount", v1.PostDiskUmount) + + //v1DiskGroup.GET("/type", v1.FormatDiskType)//delete + + v1DisksGroup.DELETE("/part", v1.RemovePartition) //disk/delpart + } + + v1StorageGroup := v1Group.Group("/storage") + v1StorageGroup.Use() + { + v1StorageGroup.POST("", v1.PostDiskAddPartition) + + v1StorageGroup.PUT("", v1.PostDiskFormat) + + v1StorageGroup.DELETE("", v1.PostDiskUmount) } - v1Group.GET("/sync/config", v1.GetSyncConfig) } return r } diff --git a/route/v1/app.go b/route/v1/app.go index 5ff3953..7d6b6ed 100644 --- a/route/v1/app.go +++ b/route/v1/app.go @@ -3,7 +3,6 @@ package v1 import ( "encoding/json" "io/ioutil" - "net/http" "strconv" "github.com/IceWhaleTech/CasaOS/model" @@ -37,10 +36,14 @@ func AppList(c *gin.Context) { categoryId := c.DefaultQuery("category_id", "0") key := c.DefaultQuery("key", "") if len(index) == 0 || len(size) == 0 || len(t) == 0 || len(categoryId) == 0 { - c.JSON(http.StatusOK, &model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + c.JSON(common_err.CLIENT_ERROR, &model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + return + } + collection, err := service.MyService.Casa().GetServerList(index, size, t, categoryId, key) + if err != nil { + c.JSON(common_err.SERVICE_ERROR, &model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return } - collection := service.MyService.Casa().GetServerList(index, size, t, categoryId, key) // for i := 0; i < len(recommend); i++ { // ct, _ := service.MyService.Docker().DockerListByImage(recommend[i].Image, recommend[i].ImageVersion) // if ct != nil { @@ -64,7 +67,7 @@ func AppList(c *gin.Context) { data["list"] = collection.List data["community"] = collection.Community - c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) + c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) } // @Summary 获取一个可用端口 @@ -83,7 +86,8 @@ func GetPort(c *gin.Context) { p, _ = port2.GetAvailablePort(t) ok = !port2.IsPortAvailable(p, t) } - c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: p}) + // @tiger 这里最好封装成 {'port': ...} 的形式,来体现出参的上下文 + c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: p}) } // @Summary 检查端口是否可用 @@ -98,7 +102,7 @@ func GetPort(c *gin.Context) { func PortCheck(c *gin.Context) { p, _ := strconv.Atoi(c.Param("port")) t := c.DefaultQuery("type", "tcp") - c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: port2.IsPortAvailable(p, t)}) + c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: port2.IsPortAvailable(p, t)}) } // @Summary 我的应用列表 @@ -117,10 +121,10 @@ func MyAppList(c *gin.Context) { position, _ := strconv.ParseBool(c.DefaultQuery("position", "true")) list, unTranslation := service.MyService.App().GetMyList(index, size, position) data := make(map[string]interface{}, 2) - data["list"] = list - data["local"] = unTranslation + data["casaos_apps"] = list + data["local_apps"] = unTranslation - c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) + c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) } // @Summary my app hardware usage list @@ -132,7 +136,7 @@ func MyAppList(c *gin.Context) { // @Router /app/usage [get] func AppUsageList(c *gin.Context) { list := service.MyService.App().GetHardwareUsage() - c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list}) + c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list}) } // @Summary 应用详情 @@ -147,7 +151,11 @@ func AppInfo(c *gin.Context) { id := c.Param("id") language := c.GetHeader("Language") - info := service.MyService.Casa().GetServerAppInfo(id, "", language) + info, err := service.MyService.Casa().GetServerAppInfo(id, "", language) + if err != nil { + c.JSON(common_err.SERVICE_ERROR, &model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) + return + } if info.NetworkModel != "host" { for i := 0; i < len(info.Ports); i++ { if p, _ := strconv.Atoi(info.Ports[i].ContainerPort); port2.IsPortAvailable(p, info.Ports[i].Protocol) { @@ -214,7 +222,7 @@ func AppInfo(c *gin.Context) { info.MaxMemory = (service.MyService.System().GetMemInfo()["total"]).(uint64) >> 20 - c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: info}) + c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: info}) } // @Summary 获取远程分类列表 @@ -225,7 +233,11 @@ func AppInfo(c *gin.Context) { // @Success 200 {string} string "ok" // @Router /app/category [get] func CategoryList(c *gin.Context) { - list := service.MyService.Casa().GetServerCategoryList() + list, err := service.MyService.Casa().GetServerCategoryList() + if err != nil { + c.JSON(common_err.SERVICE_ERROR, &model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) + return + } var count uint = 0 for _, category := range list { count += category.Count @@ -234,7 +246,7 @@ func CategoryList(c *gin.Context) { rear := append([]model.CategoryList{}, list[0:]...) list = append(list[:0], model.CategoryList{Count: count, Name: "All", Font: "apps"}) list = append(list, rear...) - c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list}) + c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list}) } // @Summary 分享该应用配置 @@ -247,5 +259,5 @@ func CategoryList(c *gin.Context) { func ShareAppFile(c *gin.Context) { str, _ := ioutil.ReadAll(c.Request.Body) content := service.MyService.Casa().ShareAppFile(str) - c.JSON(http.StatusOK, json.RawMessage(content)) + c.JSON(common_err.SUCCESS, json.RawMessage(content)) } diff --git a/route/v1/disk.go b/route/v1/disk.go index 59afcbc..9d19a16 100644 --- a/route/v1/disk.go +++ b/route/v1/disk.go @@ -9,8 +9,9 @@ import ( "time" "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/pkg/config" + "github.com/IceWhaleTech/CasaOS/model/notify" "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" + "github.com/IceWhaleTech/CasaOS/pkg/utils/encryption" "github.com/IceWhaleTech/CasaOS/pkg/utils/file" "github.com/IceWhaleTech/CasaOS/service" model2 "github.com/IceWhaleTech/CasaOS/service/model" @@ -28,7 +29,42 @@ var diskMap = make(map[string]string) // @Success 200 {string} string "ok" // @Router /disk/list [get] func GetDiskList(c *gin.Context) { + path := c.Query("path") + if len(path) > 0 { + m := service.MyService.Disk().GetDiskInfo(path) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: m}) + return + } + t := c.DefaultQuery("type", "") list := service.MyService.Disk().LSBLK(false) + if t == "usb" { + data := []model.DriveUSB{} + for _, v := range list { + if v.Tran == "usb" { + temp := model.DriveUSB{} + temp.Model = v.Model + temp.Name = v.Name + temp.Size = v.Size + mountTemp := true + if len(v.Children) == 0 { + mountTemp = false + } + for _, child := range v.Children { + if len(child.MountPoint) > 0 { + avail, _ := strconv.ParseUint(child.FSAvail, 10, 64) + temp.Avail += avail + } else { + mountTemp = false + } + } + temp.Mount = mountTemp + data = append(data, temp) + } + } + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) + return + } + dbList := service.MyService.Disk().GetSerialAll() part := make(map[string]int64, len(dbList)) for _, v := range dbList { @@ -154,7 +190,7 @@ func GetDiskList(c *gin.Context) { data["storage"] = storage data["avail"] = avail - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) } // @Summary get disk list @@ -191,49 +227,6 @@ func GetDiskInfo(c *gin.Context) { c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: m}) } -// @Summary format storage -// @Produce application/json -// @Accept multipart/form-data -// @Tags disk -// @Security ApiKeyAuth -// @Param path formData string true "e.g. /dev/sda1" -// @Param pwd formData string true "user password" -// @Param volume formData string true "mount point" -// @Success 200 {string} string "ok" -// @Router /disk/format [post] -func PostDiskFormat(c *gin.Context) { - path := c.PostForm("path") - t := "ext4" - pwd := c.PostForm("pwd") - volume := c.PostForm("volume") - - if pwd != config.UserInfo.PWD { - c.JSON(http.StatusOK, model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)}) - return - } - - if len(path) == 0 || len(t) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - if _, ok := diskMap[path]; ok { - c.JSON(http.StatusOK, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)}) - return - } - diskMap[path] = "busying" - service.MyService.Disk().UmountPointAndRemoveDir(path) - format := service.MyService.Disk().FormatDisk(path, t) - if len(format) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.FORMAT_ERROR, Message: common_err.GetMsg(common_err.FORMAT_ERROR)}) - delete(diskMap, path) - return - } - service.MyService.Disk().MountDisk(path, volume) - service.MyService.Disk().RemoveLSBLKCache() - delete(diskMap, path) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - // @Summary 获取支持的格式 // @Produce application/json // @Accept application/json @@ -256,15 +249,17 @@ func FormatDiskType(c *gin.Context) { // @Success 200 {string} string "ok" // @Router /disk/delpart [delete] func RemovePartition(c *gin.Context) { - path := c.PostForm("path") + js := make(map[string]string) + c.ShouldBind(&js) + path := js["path"] if len(path) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) } var p = path[:len(path)-1] var n = path[len(path)-1:] service.MyService.Disk().DelPartition(p, n) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) } // @Summary add storage @@ -280,32 +275,40 @@ func RemovePartition(c *gin.Context) { // @Router /disk/storage [post] func PostDiskAddPartition(c *gin.Context) { - name := c.PostForm("name") - path := c.PostForm("path") - format, _ := strconv.ParseBool(c.PostForm("format")) + js := make(map[string]interface{}) + c.ShouldBind(&js) + path := js["path"].(string) + name := js["name"].(string) + format := js["format"].(bool) if len(name) == 0 || len(path) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return } if _, ok := diskMap[path]; ok { - c.JSON(http.StatusOK, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)}) return } if !file.CheckNotExist("/DATA/" + name) { // /mnt/name exist - c.JSON(http.StatusOK, model.Result{Success: common_err.NAME_NOT_AVAILABLE, Message: common_err.GetMsg(common_err.NAME_NOT_AVAILABLE)}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.NAME_NOT_AVAILABLE, Message: common_err.GetMsg(common_err.NAME_NOT_AVAILABLE)}) return } diskMap[path] = "busying" currentDisk := service.MyService.Disk().GetDiskInfo(path) if !format { if len(currentDisk.Children) != 1 || !(len(currentDisk.Children) > 0 && currentDisk.Children[0].FsType == "ext4") { - c.JSON(http.StatusOK, model.Result{Success: common_err.DISK_NEEDS_FORMAT, Message: common_err.GetMsg(common_err.DISK_NEEDS_FORMAT)}) delete(diskMap, path) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DISK_NEEDS_FORMAT, Message: common_err.GetMsg(common_err.DISK_NEEDS_FORMAT)}) return } } else { + // format := service.MyService.Disk().FormatDisk(path+"1", "ext4") + // if len(format) == 0 { + // delete(diskMap, path) + // c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FORMAT_ERROR, Message: common_err.GetMsg(common_err.FORMAT_ERROR)}) + // return + // } service.MyService.Disk().AddPartition(path) } @@ -321,7 +324,7 @@ func PostDiskAddPartition(c *gin.Context) { } currentDisk = service.MyService.Disk().GetDiskInfo(path) if len(currentDisk.Children) != 1 { - c.JSON(http.StatusOK, model.Result{Success: common_err.DISK_NEEDS_FORMAT, Message: common_err.GetMsg(common_err.DISK_NEEDS_FORMAT)}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DISK_NEEDS_FORMAT, Message: common_err.GetMsg(common_err.DISK_NEEDS_FORMAT)}) return } @@ -340,47 +343,61 @@ func PostDiskAddPartition(c *gin.Context) { service.MyService.Disk().RemoveLSBLKCache() delete(diskMap, path) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) + + //send notify to client + msg := notify.StorageMessage{} + msg.Action = "ADDED" + msg.Path = currentDisk.Children[0].Path + msg.Volume = mountPath + msg.Size = currentDisk.Children[0].Size + msg.Type = currentDisk.Children[0].Tran + service.MyService.Notify().SendStorageBySocket(msg) + + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) } -// @Summary add mount point -// @Produce application/json -// @Accept multipart/form-data -// @Tags disk -// @Security ApiKeyAuth -// @Param path formData string true "for example: /dev/sda1" -// @Param serial formData string true "disk id" +// @Param pwd formData string true "user password" +// @Param volume formData string true "mount point" // @Success 200 {string} string "ok" -// @Router /disk/mount [post] -func PostMountDisk(c *gin.Context) { - // for example: path=/dev/sda1 - path := c.PostForm("path") - serial := c.PostForm("serial") - - mountPath := "/DATA/volume" - var list = service.MyService.Disk().GetSerialAll() - var pathMapList = make(map[string]string, len(list)) - for _, v := range list { - pathMapList[v.MountPoint] = "1" +// @Router /disk/format [post] +func PostDiskFormat(c *gin.Context) { + id := c.GetHeader("user_id") + js := make(map[string]string) + c.ShouldBind(&js) + path := js["path"] + t := "ext4" + pwd := js["password"] + volume := js["volume"] + user := service.MyService.User().GetUserAllInfoById(id) + if user.Id == 0 { + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) + return + } + if encryption.GetMD5ByStr(pwd) != user.Password { + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)}) + return } - for i := 0; i < len(list)+1; i++ { - if _, ok := pathMapList[mountPath+strconv.Itoa(i)]; !ok { - mountPath = mountPath + strconv.Itoa(i) - break - } + if len(path) == 0 || len(t) == 0 { + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + return } - - //mount dir - service.MyService.Disk().MountDisk(path, mountPath) - - m := model2.SerialDisk{} - m.MountPoint = mountPath - m.Path = path - m.UUID = serial - m.State = 0 - //service.MyService.Disk().SaveMountPoint(m) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) + if _, ok := diskMap[path]; ok { + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)}) + return + } + diskMap[path] = "busying" + service.MyService.Disk().UmountPointAndRemoveDir(path) + format := service.MyService.Disk().FormatDisk(path, t) + if len(format) == 0 { + delete(diskMap, path) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FORMAT_ERROR, Message: common_err.GetMsg(common_err.FORMAT_ERROR)}) + return + } + service.MyService.Disk().MountDisk(path, volume) + service.MyService.Disk().RemoveLSBLKCache() + delete(diskMap, path) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) } // @Summary remove mount point @@ -394,22 +411,30 @@ func PostMountDisk(c *gin.Context) { // @Success 200 {string} string "ok" // @Router /disk/umount [post] func PostDiskUmount(c *gin.Context) { + id := c.GetHeader("user_id") + js := make(map[string]string) + c.ShouldBind(&js) - path := c.PostForm("path") - mountPoint := c.PostForm("volume") - pwd := c.PostForm("pwd") + path := js["path"] + mountPoint := js["volume"] + pwd := js["password"] if len(path) == 0 || len(mountPoint) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return } - if pwd != config.UserInfo.PWD { - c.JSON(http.StatusOK, model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)}) + user := service.MyService.User().GetUserAllInfoById(id) + if user.Id == 0 { + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) + return + } + if encryption.GetMD5ByStr(pwd) != user.Password { + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)}) return } if _, ok := diskMap[path]; ok { - c.JSON(http.StatusOK, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)}) return } @@ -417,7 +442,16 @@ func PostDiskUmount(c *gin.Context) { //delete data service.MyService.Disk().DeleteMountPoint(path, mountPoint) service.MyService.Disk().RemoveLSBLKCache() - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) + + //send notify to client + msg := notify.StorageMessage{} + msg.Action = "REMOVED" + msg.Path = path + msg.Volume = mountPoint + msg.Size = 0 + msg.Type = "" + service.MyService.Notify().SendStorageBySocket(msg) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) } // @Summary confirm delete disk @@ -455,45 +489,10 @@ func GetDiskCheck(c *gin.Context) { for _, v := range dbList { if _, ok := mapList[v.UUID]; !ok { //disk undefind - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: "disk undefind"}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: "disk undefind"}) return } } c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) } - -// @Summary check mount point -// @Produce application/json -// @Accept application/json -// @Tags disk -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /disk/usb [get] -func GetUSBList(c *gin.Context) { - list := service.MyService.Disk().LSBLK(false) - data := []model.DriveUSB{} - for _, v := range list { - if v.Tran == "usb" { - temp := model.DriveUSB{} - temp.Model = v.Model - temp.Name = v.Name - temp.Size = v.Size - mountTemp := true - if len(v.Children) == 0 { - mountTemp = false - } - for _, child := range v.Children { - if len(child.MountPoint) > 0 { - avail, _ := strconv.ParseUint(child.FSAvail, 10, 64) - temp.Avail += avail - } else { - mountTemp = false - } - } - temp.Mount = mountTemp - data = append(data, temp) - } - } - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) -} diff --git a/route/v1/docker.go b/route/v1/docker.go index 5c252b7..4c2cd7f 100644 --- a/route/v1/docker.go +++ b/route/v1/docker.go @@ -4,6 +4,7 @@ import ( "bytes" json2 "encoding/json" "net/http" + "os/exec" "path/filepath" "strconv" "strings" @@ -15,6 +16,7 @@ import ( "github.com/IceWhaleTech/CasaOS/pkg/docker" "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" "github.com/IceWhaleTech/CasaOS/pkg/utils/file" + "github.com/IceWhaleTech/CasaOS/pkg/utils/loger" port2 "github.com/IceWhaleTech/CasaOS/pkg/utils/port" "github.com/IceWhaleTech/CasaOS/pkg/utils/random" "github.com/IceWhaleTech/CasaOS/service" @@ -25,6 +27,7 @@ import ( "github.com/gorilla/websocket" "github.com/jinzhu/copier" uuid "github.com/satori/go.uuid" + "go.uber.org/zap" "golang.org/x/crypto/ssh" ) @@ -41,14 +44,14 @@ func DockerTerminal(c *gin.Context) { row := c.DefaultQuery("rows", "30") conn, err := upgrader.Upgrade(c.Writer, c.Request, nil) if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return } defer conn.Close() container := c.Param("id") hr, err := service.Exec(container, row, col) if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return } // 关闭I/O流 @@ -63,14 +66,41 @@ func DockerTerminal(c *gin.Context) { docker.WsReaderCopy(conn, hr.Conn) } -//打开本机的ssh接口 -func WsSsh(c *gin.Context) { - wsConn, _ := upgrader.Upgrade(c.Writer, c.Request, nil) +func PostSshLogin(c *gin.Context) { + j := make(map[string]string) + c.ShouldBind(&j) + userName := j["username"] + password := j["password"] + port := j["port"] + if userName == "" || password == "" || port == "" { + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: "Username or password or port is empty"}) + return + } + _, err := docker.NewSshClient(userName, password, port) + if err != nil { + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "Please check if the username and port are correct, and make sure that ssh server is installed."}) + loger.Error("connect ssh error", zap.Any("error", err)) + return + } + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) +} +func WsSsh(c *gin.Context) { + _, e := exec.LookPath("ssh") + if e != nil { + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: "ssh server not found"}) + return + } + + userName := c.Query("username") + password := c.Query("password") + port := c.Query("port") + wsConn, _ := upgrader.Upgrade(c.Writer, c.Request, nil) var logBuff = new(bytes.Buffer) + quitChan := make(chan bool, 3) - user := "" - password := "" + // user := "" + // password := "" var login int = 1 cols, _ := strconv.Atoi(c.DefaultQuery("cols", "200")) rows, _ := strconv.Atoi(c.DefaultQuery("rows", "32")) @@ -78,14 +108,16 @@ func WsSsh(c *gin.Context) { for login != 0 { var err error - - wsConn.WriteMessage(websocket.TextMessage, []byte("login:")) - user = docker.ReceiveWsMsgUser(wsConn, logBuff) - wsConn.WriteMessage(websocket.TextMessage, []byte("\r\n\x1b[0m")) - wsConn.WriteMessage(websocket.TextMessage, []byte("password:")) - password = docker.ReceiveWsMsgPassword(wsConn, logBuff) - wsConn.WriteMessage(websocket.TextMessage, []byte("\r\n\x1b[0m")) - client, err = docker.NewSshClient(user, password) + if userName == "" || password == "" || port == "" { + wsConn.WriteMessage(websocket.TextMessage, []byte("username or password or port is empty")) + } + // wsConn.WriteMessage(websocket.TextMessage, []byte("login:")) + // user = docker.ReceiveWsMsgUser(wsConn, logBuff) + // wsConn.WriteMessage(websocket.TextMessage, []byte("\r\n\x1b[0m")) + // wsConn.WriteMessage(websocket.TextMessage, []byte("password:")) + // password = docker.ReceiveWsMsgPassword(wsConn, logBuff) + // wsConn.WriteMessage(websocket.TextMessage, []byte("\r\n\x1b[0m")) + client, err = docker.NewSshClient(userName, password, port) if err != nil && client == nil { wsConn.WriteMessage(websocket.TextMessage, []byte(err.Error())) @@ -110,25 +142,6 @@ func WsSsh(c *gin.Context) { } -//安装进度推送 -func SpeedPush(c *gin.Context) { - //token := c.Query("token") - //if len(token) == 0 || token != config.UserInfo.Token { - // c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR_AUTH_TOKEN, Message: common_err.GetMsg(common_err.ERROR_AUTH_TOKEN)}) - // return - //} - - //ws, _ := upgrader.Upgrade(c.Writer, c.Request, nil) - //defer ws.Close() - // - //for { - // select { - // case msg := <-WSMSG: - // ws.WriteMessage(websocket.TextMessage, []byte(fmt.Sprintln(msg))) - // } - //} -} - // @Summary 安装app(该接口需要post json数据) // @Produce application/json // @Accept application/json @@ -144,7 +157,7 @@ func SpeedPush(c *gin.Context) { func InstallApp(c *gin.Context) { var appInfo model.ServerAppList m := model.CustomizationPostData{} - c.BindJSON(&m) + c.ShouldBind(&m) const CUSTOM = "custom" var dockerImage string @@ -154,19 +167,22 @@ func InstallApp(c *gin.Context) { if len(m.Protocol) == 0 { m.Protocol = "http" } - if m.Origin != "custom" { - oldName := m.Label + m.ContainerName = strings.Replace(m.Label, " ", "_", -1) + if m.Origin != CUSTOM { + oldName := m.ContainerName + oldLabel := m.Label for i := 0; true; i++ { if i != 0 { - m.Label = oldName + "-" + strconv.Itoa(i) + m.ContainerName = oldName + "-" + strconv.Itoa(i) + m.Label = oldLabel + "-" + strconv.Itoa(i) } - if _, err := service.MyService.Docker().DockerListByName(m.Label); err != nil { + if _, err := service.MyService.Docker().DockerListByName(m.ContainerName); err != nil { break } } } else { - if _, err := service.MyService.Docker().DockerListByName(m.Label); err == nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR_APP_NAME_EXIST, Message: common_err.GetMsg(common_err.ERROR_APP_NAME_EXIST)}) + if _, err := service.MyService.Docker().DockerListByName(m.ContainerName); err == nil { + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.ERROR_APP_NAME_EXIST, Message: common_err.GetMsg(common_err.ERROR_APP_NAME_EXIST)}) return } @@ -177,7 +193,7 @@ func InstallApp(c *gin.Context) { //c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) portMap, _ := strconv.Atoi(m.PortMap) if !port2.IsPortAvailable(portMap, "tcp") { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + m.PortMap}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + m.PortMap}) return } } @@ -199,33 +215,33 @@ func InstallApp(c *gin.Context) { if u.Protocol == "udp" { t, _ := strconv.Atoi(u.CommendPort) if !port2.IsPortAvailable(t, "udp") { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + u.CommendPort}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + u.CommendPort}) return } } else if u.Protocol == "tcp" { te, _ := strconv.Atoi(u.CommendPort) if !port2.IsPortAvailable(te, "tcp") { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + u.CommendPort}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + u.CommendPort}) return } } else if u.Protocol == "both" { t, _ := strconv.Atoi(u.CommendPort) if !port2.IsPortAvailable(t, "udp") { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + u.CommendPort}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + u.CommendPort}) return } te, _ := strconv.Atoi(u.CommendPort) if !port2.IsPortAvailable(te, "tcp") { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + u.CommendPort}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + u.CommendPort}) return } } } - if m.Origin == "custom" { + if m.Origin == CUSTOM { for _, device := range m.Devices { if file.CheckNotExist(device.Path) { - c.JSON(http.StatusOK, model.Result{Success: common_err.DEVICE_NOT_EXIST, Message: device.Path + "," + common_err.GetMsg(common_err.DEVICE_NOT_EXIST)}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DEVICE_NOT_EXIST, Message: device.Path + "," + common_err.GetMsg(common_err.DEVICE_NOT_EXIST)}) return } @@ -263,7 +279,7 @@ func InstallApp(c *gin.Context) { // installLog.UpdatedAt = strconv.FormatInt(time.Now().Unix(), 10) // installLog.Id = uuid.NewV4().String() // service.MyService.Notify().AddLog(installLog) - if m.Origin != "custom" { + if m.Origin != CUSTOM { for _, plugin := range appInfo.Plugins { if plugin == "mysql" { mid := uuid.NewV4().String() @@ -349,7 +365,7 @@ func InstallApp(c *gin.Context) { // echo -e "hellow\nworld" >> //step:启动容器 - err = service.MyService.Docker().DockerContainerStart(m.Label) + err = service.MyService.Docker().DockerContainerStart(m.ContainerName) if err != nil { //service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":90}", 100) notify := notify.Application{} @@ -372,7 +388,7 @@ func InstallApp(c *gin.Context) { } //step: 启动成功 检查容器状态确认启动成功 - container, err := service.MyService.Docker().DockerContainerInfo(m.Label) + container, err := service.MyService.Docker().DockerContainerInfo(m.ContainerName) if err != nil && container.ContainerJSONBase.State.Running { notify := notify.Application{} notify.Icon = m.Icon @@ -405,7 +421,7 @@ func InstallApp(c *gin.Context) { }() - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: m.Label}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: m.Label}) } @@ -426,7 +442,7 @@ func InstallApp(c *gin.Context) { // // appInfo := service.MyService.App().GetServerAppInfo(appId) // // m := model.CustomizationPostData{} -// c.BindJSON(&m) +// c.ShouldBind(&m) // //检查端口 // if len(m.PortMap) == 0 || m.PortMap == "0" { // c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) @@ -603,27 +619,27 @@ func UnInstallApp(c *gin.Context) { appId := c.Param("id") if len(appId) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return } //info := service.MyService.App().GetUninstallInfo(appId) info, err := service.MyService.Docker().DockerContainerInfo(appId) if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return } //step:停止容器 err = service.MyService.Docker().DockerContainerStop(appId) if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.UNINSTALL_APP_ERROR, Message: common_err.GetMsg(common_err.UNINSTALL_APP_ERROR), Data: err.Error()}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.UNINSTALL_APP_ERROR, Message: common_err.GetMsg(common_err.UNINSTALL_APP_ERROR), Data: err.Error()}) return } err = service.MyService.Docker().DockerContainerRemove(appId, false) if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.UNINSTALL_APP_ERROR, Message: common_err.GetMsg(common_err.UNINSTALL_APP_ERROR), Data: err.Error()}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.UNINSTALL_APP_ERROR, Message: common_err.GetMsg(common_err.UNINSTALL_APP_ERROR), Data: err.Error()}) return } @@ -688,7 +704,7 @@ func UnInstallApp(c *gin.Context) { notify.Success = true notify.Finished = true service.MyService.Notify().SendUninstallAppBySocket(notify) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) } @@ -703,26 +719,35 @@ func UnInstallApp(c *gin.Context) { // @Router /app/state/{id} [put] func ChangAppState(c *gin.Context) { appId := c.Param("id") - state := c.DefaultPostForm("state", "stop") + js := make(map[string]string) + c.ShouldBind(&js) + state := js["state"] + if len(appId) == 0 || len(state) == 0 { + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + return + } var err error - if state == "stop" { - err = service.MyService.Docker().DockerContainerStop(appId) - } else if state == "start" { + if state == "start" { err = service.MyService.Docker().DockerContainerStart(appId) } else if state == "restart" { service.MyService.Docker().DockerContainerStop(appId) err = service.MyService.Docker().DockerContainerStart(appId) + } else { + err = service.MyService.Docker().DockerContainerStop(appId) } + if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return } info, err := service.MyService.App().GetContainerInfo(appId) if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return } - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: info.State}) + + // @tiger - 用 {'state': ...} 来体现出参上下文 + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: info.State}) } // @Summary 查看容器日志 @@ -736,7 +761,7 @@ func ChangAppState(c *gin.Context) { func ContainerLog(c *gin.Context) { appId := c.Param("id") log, _ := service.MyService.Docker().DockerContainerLog(appId) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: log}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: log}) } // @Summary 获取容器状态 @@ -750,10 +775,10 @@ func ContainerLog(c *gin.Context) { // @Router /app/state/{id} [get] func GetContainerState(c *gin.Context) { id := c.Param("id") - t := c.DefaultQuery("type", "0") + //t := c.DefaultQuery("type", "0") containerInfo, e := service.MyService.App().GetSimpleContainerInfo(id) if e != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: e.Error()}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: e.Error()}) return } @@ -761,12 +786,12 @@ func GetContainerState(c *gin.Context) { data["state"] = containerInfo.State - if t == "1" { - appInfo := service.MyService.App().GetAppDBInfo(id) - data["app"] = appInfo - } + // if t == "1" { + // appInfo := service.MyService.App().GetAppDBInfo(id) + // data["app"] = appInfo + // } - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) } // @Summary 更新设置 @@ -786,10 +811,10 @@ func UpdateSetting(c *gin.Context) { id := c.Param("id") const CUSTOM = "custom" m := model.CustomizationPostData{} - c.BindJSON(&m) + c.ShouldBind(&m) if len(id) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return } //var cpd model.CustomizationPostData @@ -809,7 +834,7 @@ func UpdateSetting(c *gin.Context) { portMap, _ := strconv.Atoi(m.PortMap) if !port2.IsPortAvailable(portMap, "tcp") { service.MyService.Docker().DockerContainerStart(id) - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + m.PortMap}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + m.PortMap}) return } @@ -819,28 +844,28 @@ func UpdateSetting(c *gin.Context) { t, _ := strconv.Atoi(u.CommendPort) if !port2.IsPortAvailable(t, "udp") { service.MyService.Docker().DockerContainerStart(id) - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + u.CommendPort}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + u.CommendPort}) return } } else if u.Protocol == "tcp" { te, _ := strconv.Atoi(u.CommendPort) if !port2.IsPortAvailable(te, "tcp") { service.MyService.Docker().DockerContainerStart(id) - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + u.CommendPort}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + u.CommendPort}) return } } else if u.Protocol == "both" { t, _ := strconv.Atoi(u.CommendPort) if !port2.IsPortAvailable(t, "udp") { service.MyService.Docker().DockerContainerStart(id) - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + u.CommendPort}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + u.CommendPort}) return } te, _ := strconv.Atoi(u.CommendPort) if !port2.IsPortAvailable(te, "tcp") { service.MyService.Docker().DockerContainerStart(id) - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + u.CommendPort}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + u.CommendPort}) return } } @@ -851,9 +876,9 @@ func UpdateSetting(c *gin.Context) { containerId, err := service.MyService.Docker().DockerContainerCreate(m.Image, m) if err != nil { - service.MyService.Docker().DockerContainerUpdateName(m.Label, id) + service.MyService.Docker().DockerContainerUpdateName(m.ContainerName, id) service.MyService.Docker().DockerContainerStart(id) - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR)}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)}) return } // echo -e "hellow\nworld" >> @@ -862,7 +887,7 @@ func UpdateSetting(c *gin.Context) { err = service.MyService.Docker().DockerContainerStart(containerId) if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR)}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)}) return } service.MyService.Docker().DockerContainerRemove(id, true) @@ -933,7 +958,7 @@ func UpdateSetting(c *gin.Context) { //service.MyService.App().UpdateApp(appInfo) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) } // @Summary update app version @@ -948,20 +973,20 @@ func PutAppUpdate(c *gin.Context) { id := c.Param("id") if len(id) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return } inspect, err := service.MyService.Docker().DockerContainerInfo(id) if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return } imageLatest := strings.Split(inspect.Config.Image, ":")[0] + ":latest" err = service.MyService.Docker().DockerPullImage(imageLatest, "", "") if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return } @@ -974,7 +999,7 @@ func PutAppUpdate(c *gin.Context) { if err != nil { service.MyService.Docker().DockerContainerUpdateName(inspect.Name, id) service.MyService.Docker().DockerContainerStart(id) - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR)}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)}) return } @@ -982,13 +1007,13 @@ func PutAppUpdate(c *gin.Context) { err = service.MyService.Docker().DockerContainerStart(containerId) if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR)}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)}) return } service.MyService.Docker().DockerContainerRemove(id, true) delete(service.NewVersionApp, id) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) } // @Summary 获取容器详情 @@ -1001,6 +1026,8 @@ func PutAppUpdate(c *gin.Context) { // @Router /app/info/{id} [get] func ContainerInfo(c *gin.Context) { appId := c.Param("id") + + // @tiger - 作为最佳实践,不应该直接把数据库的信息返回,来避免未来数据库结构上的迭代带来的新字段 appInfo := service.MyService.App().GetAppDBInfo(appId) containerInfo, _ := service.MyService.Docker().DockerContainerStats(appId) var cpuModel = "arm" @@ -1015,44 +1042,34 @@ func ContainerInfo(c *gin.Context) { info, err := service.MyService.Docker().DockerContainerInfo(appId) if err != nil { //todo 需要自定义错误 - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: err.Error()}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return } con := struct { Status string `json:"status"` StartedAt string `json:"started_at"` CPUShares int64 `json:"cpu_shares"` - Memory int64 `json:"memory"` - Restart string `json:"restart"` + Memory int64 `json:"total_memory"` // @tiger - 改成 total_memory,方便以后增加 free_memory 之类的字段 + Restart string `json:"restart_policy"` // @tiger - 改成 restart_policy? }{Status: info.State.Status, StartedAt: info.State.StartedAt, CPUShares: info.HostConfig.CPUShares, Memory: info.HostConfig.Memory >> 20, Restart: info.HostConfig.RestartPolicy.Name} data := make(map[string]interface{}, 5) - data["app"] = appInfo - data["cpu"] = cpuModel - data["memory"] = service.MyService.System().GetMemInfo()["total"] + data["app"] = appInfo // @tiget - 最佳实践是,返回 appid,然后具体的 app 信息由前端另行获取 + data["cpu"] = cpuModel // @tiger - 改成 arch + data["memory"] = service.MyService.System().GetMemInfo()["total"] // @tiger - 改成 total_memory,方便以后增加 free_memory 之类的字段 data["container"] = json2.RawMessage(containerInfo) data["info"] = con - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) } -// @Summary 获取安装所需要的数据 -// @Produce application/json -// @Accept application/json -// @Tags app -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /app/install/config [get] -func GetDockerInstallConfig(c *gin.Context) { +func GetDockerNetworks(c *gin.Context) { networks := service.MyService.Docker().DockerNetworkModelList() - data := make(map[string]interface{}, 2) list := []map[string]string{} for _, network := range networks { if network.Driver != "null" { list = append(list, map[string]string{"name": network.Name, "driver": network.Driver, "id": network.ID}) } } - data["networks"] = list - data["memory"] = service.MyService.System().GetMemInfo() - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list}) } // @Summary 获取依赖数据 @@ -1069,7 +1086,6 @@ func ContainerRelyInfo(c *gin.Context) { c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: appInfo}) } -// @Summary 获取可更新数据 // @Produce application/json // @Accept application/json // @Tags app @@ -1083,7 +1099,7 @@ func ContainerUpdateInfo(c *gin.Context) { info, err := service.MyService.Docker().DockerContainerInfo(appId) if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: err.Error()}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: err.Error()}) return } var port model.PortArray @@ -1161,7 +1177,7 @@ func ContainerUpdateInfo(c *gin.Context) { } m.NetworkModel = string(info.HostConfig.NetworkMode) m.Description = info.Config.Labels["desc"] - m.Label = strings.ReplaceAll(info.Name, "/", "") + m.ContainerName = strings.ReplaceAll(info.Name, "/", "") m.PortMap = info.Config.Labels["web"] m.Devices = driver m.Envs = envs @@ -1181,6 +1197,11 @@ func ContainerUpdateInfo(c *gin.Context) { m.Cmd = info.Config.Cmd m.HostName = info.Config.Hostname m.Privileged = info.HostConfig.Privileged + name := info.Config.Labels["name"] + if len(name) == 0 { + name = strings.ReplaceAll(info.Name, "/", "") + } + m.Label = name m.Protocol = info.Config.Labels["protocol"] if m.Protocol == "" { diff --git a/route/v1/file.go b/route/v1/file.go index 9733fbf..e2ca2b2 100644 --- a/route/v1/file.go +++ b/route/v1/file.go @@ -1,9 +1,6 @@ package v1 import ( - "bufio" - "encoding/csv" - "fmt" "io" "io/ioutil" "log" @@ -26,32 +23,6 @@ import ( uuid "github.com/satori/go.uuid" ) -func downloadReadFile(c *gin.Context) { - //http下载地址 csv - csvFileUrl := c.PostForm("file_name") - res, err := http.Get(csvFileUrl) - if err != nil { - c.String(400, err.Error()) - return - } - defer res.Body.Close() - //读取csv - reader := csv.NewReader(bufio.NewReader(res.Body)) - for { - line, err := reader.Read() - if err == io.EOF { - break - } else if err != nil { - c.String(400, err.Error()) - return - } - //line 就是每一行的内容 - fmt.Println(line) - //line[0] 就是第几列 - fmt.Println(line[0]) - } -} - // @Summary 读取文件 // @Produce application/json // @Accept application/json @@ -63,14 +34,14 @@ func downloadReadFile(c *gin.Context) { func GetFilerContent(c *gin.Context) { filePath := c.Query("path") if len(filePath) == 0 { - c.JSON(http.StatusOK, model.Result{ + c.JSON(common_err.CLIENT_ERROR, model.Result{ Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS), }) return } if !file.Exists(filePath) { - c.JSON(http.StatusOK, model.Result{ + c.JSON(common_err.SERVICE_ERROR, model.Result{ Success: common_err.FILE_DOES_NOT_EXIST, Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST), }) @@ -79,7 +50,7 @@ func GetFilerContent(c *gin.Context) { //文件读取任务是将文件内容读取到内存中。 info, err := ioutil.ReadFile(filePath) if err != nil { - c.JSON(http.StatusOK, model.Result{ + c.JSON(common_err.SERVICE_ERROR, model.Result{ Success: common_err.FILE_READ_ERROR, Message: common_err.GetMsg(common_err.FILE_READ_ERROR), Data: err.Error(), @@ -88,8 +59,7 @@ func GetFilerContent(c *gin.Context) { } result := string(info) - //返回结果 - c.JSON(http.StatusOK, model.Result{ + c.JSON(common_err.SUCCESS, model.Result{ Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: result, @@ -121,18 +91,18 @@ func GetLocalFile(c *gin.Context) { // @Accept application/json // @Tags file // @Security ApiKeyAuth -// @Param t query string false "Compression format" Enums(zip,tar,targz) +// @Param format query string false "Compression format" Enums(zip,tar,targz) // @Param files query string true "file list eg: filename1,filename2,filename3 " // @Success 200 {string} string "ok" // @Router /file/download [get] func GetDownloadFile(c *gin.Context) { - t := c.Query("t") + t := c.Query("format") files := c.Query("files") if len(files) == 0 { - c.JSON(http.StatusOK, model.Result{ + c.JSON(common_err.CLIENT_ERROR, model.Result{ Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS), }) @@ -141,7 +111,7 @@ func GetDownloadFile(c *gin.Context) { list := strings.Split(files, ",") for _, v := range list { if !file.Exists(v) { - c.JSON(http.StatusOK, model.Result{ + c.JSON(common_err.SERVICE_ERROR, model.Result{ Success: common_err.FILE_DOES_NOT_EXIST, Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST), }) @@ -179,7 +149,7 @@ func GetDownloadFile(c *gin.Context) { extension, ar, err := file.GetCompressionAlgorithm(t) if err != nil { - c.JSON(http.StatusOK, model.Result{ + c.JSON(common_err.CLIENT_ERROR, model.Result{ Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS), }) @@ -188,9 +158,9 @@ func GetDownloadFile(c *gin.Context) { err = ar.Create(c.Writer) if err != nil { - c.JSON(http.StatusOK, model.Result{ - Success: common_err.ERROR, - Message: common_err.GetMsg(common_err.ERROR), + c.JSON(common_err.SERVICE_ERROR, model.Result{ + Success: common_err.SERVICE_ERROR, + Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error(), }) return @@ -213,8 +183,22 @@ func GetDownloadFile(c *gin.Context) { } func GetDownloadSingleFile(c *gin.Context) { - filePath := c.Param("path") - fileTmp, _ := os.Open(filePath) + filePath := c.Query("path") + if len(filePath) == 0 { + c.JSON(service.ClientCount, model.Result{ + Success: common_err.INVALID_PARAMS, + Message: common_err.GetMsg(common_err.INVALID_PARAMS), + }) + return + } + fileTmp, err := os.Open(filePath) + if err != nil { + c.JSON(common_err.SERVICE_ERROR, model.Result{ + Success: common_err.FILE_DOES_NOT_EXIST, + Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST), + }) + return + } defer fileTmp.Close() fileName := path.Base(filePath) @@ -297,7 +281,7 @@ func DirPath(c *gin.Context) { } } - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: pathList}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: pathList}) } // @Summary rename file or dir @@ -311,15 +295,15 @@ func DirPath(c *gin.Context) { // @Router /file/rename [put] func RenamePath(c *gin.Context) { json := make(map[string]string) - c.BindJSON(&json) - op := json["oldpath"] - np := json["newpath"] + c.ShouldBind(&json) + op := json["old_path"] + np := json["new_path"] if len(op) == 0 || len(np) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return } success, err := service.MyService.System().RenameFile(op, np) - c.JSON(http.StatusOK, model.Result{Success: success, Message: common_err.GetMsg(success), Data: err}) + c.JSON(common_err.SUCCESS, model.Result{Success: success, Message: common_err.GetMsg(success), Data: err}) } // @Summary create folder @@ -332,11 +316,11 @@ func RenamePath(c *gin.Context) { // @Router /file/mkdir [post] func MkdirAll(c *gin.Context) { json := make(map[string]string) - c.BindJSON(&json) + c.ShouldBind(&json) path := json["path"] var code int if len(path) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return } // decodedPath, err := url.QueryUnescape(path) @@ -345,7 +329,7 @@ func MkdirAll(c *gin.Context) { // return // } code, _ = service.MyService.System().MkdirAll(path) - c.JSON(http.StatusOK, model.Result{Success: code, Message: common_err.GetMsg(code)}) + c.JSON(common_err.SUCCESS, model.Result{Success: code, Message: common_err.GetMsg(code)}) } // @Summary create file @@ -358,11 +342,11 @@ func MkdirAll(c *gin.Context) { // @Router /file/create [post] func PostCreateFile(c *gin.Context) { json := make(map[string]string) - c.BindJSON(&json) + c.ShouldBind(&json) path := json["path"] var code int if len(path) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return } // decodedPath, err := url.QueryUnescape(path) @@ -371,7 +355,7 @@ func PostCreateFile(c *gin.Context) { // return // } code, _ = service.MyService.System().CreateFile(path) - c.JSON(http.StatusOK, model.Result{Success: code, Message: common_err.GetMsg(code)}) + c.JSON(common_err.SUCCESS, model.Result{Success: code, Message: common_err.GetMsg(code)}) } // @Summary upload file @@ -452,7 +436,7 @@ func PostFileUpload(c *gin.Context) { defer out.Close() _, err := io.Copy(out, f) if err != nil { - c.JSON(common_err.ERROR, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return } } else { @@ -460,7 +444,7 @@ func PostFileUpload(c *gin.Context) { defer out.Close() _, err := io.Copy(out, f) if err != nil { - c.JSON(common_err.ERROR, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return } c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) @@ -468,7 +452,7 @@ func PostFileUpload(c *gin.Context) { } fileNum, err := ioutil.ReadDir(tempDir) if err != nil { - c.JSON(common_err.ERROR, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return } if totalChunks == len(fileNum) { @@ -476,7 +460,7 @@ func PostFileUpload(c *gin.Context) { file.RMDir(tempDir) } - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) } // @Summary copy or move file @@ -490,14 +474,14 @@ func PostFileUpload(c *gin.Context) { func PostOperateFileOrDir(c *gin.Context) { list := model.FileOperate{} - c.BindJSON(&list) + c.ShouldBind(&list) if len(list.Item) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return } if list.To == list.Item[0].From[:strings.LastIndex(list.Item[0].From, "/")] { - c.JSON(http.StatusOK, model.Result{Success: common_err.SOURCE_DES_SAME, Message: common_err.GetMsg(common_err.SOURCE_DES_SAME)}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SOURCE_DES_SAME, Message: common_err.GetMsg(common_err.SOURCE_DES_SAME)}) return } @@ -526,7 +510,7 @@ func PostOperateFileOrDir(c *gin.Context) { } - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) } // @Summary delete file @@ -540,9 +524,9 @@ func PostOperateFileOrDir(c *gin.Context) { func DeleteFile(c *gin.Context) { paths := []string{} - c.BindJSON(&paths) + c.ShouldBind(&paths) if len(paths) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return } // path := c.Query("path") @@ -552,12 +536,12 @@ func DeleteFile(c *gin.Context) { for _, v := range paths { err := os.RemoveAll(v) if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.FILE_DELETE_ERROR, Message: common_err.GetMsg(common_err.FILE_DELETE_ERROR), Data: err}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_DELETE_ERROR, Message: common_err.GetMsg(common_err.FILE_DELETE_ERROR), Data: err}) return } } - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) } // @Summary update file @@ -572,26 +556,26 @@ func DeleteFile(c *gin.Context) { func PutFileContent(c *gin.Context) { fi := model.FileUpdate{} - c.BindJSON(&fi) + c.ShouldBind(&fi) // path := c.PostForm("path") // content := c.PostForm("content") if !file.Exists(fi.FilePath) { - c.JSON(http.StatusOK, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)}) return } //err := os.Remove(path) err := os.RemoveAll(fi.FilePath) if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.FILE_DELETE_ERROR, Message: common_err.GetMsg(common_err.FILE_DELETE_ERROR), Data: err}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_DELETE_ERROR, Message: common_err.GetMsg(common_err.FILE_DELETE_ERROR), Data: err}) return } err = file.CreateFileAndWriteContent(fi.FilePath, fi.FileContent) if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return } - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) } // @Summary image thumbnail/original image @@ -607,13 +591,13 @@ func GetFileImage(c *gin.Context) { t := c.Query("type") path := c.Query("path") if !file.Exists(path) { - c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)}) return } if t == "thumbnail" { f, err := file.GetImage(path, 100, 0) if err != nil { - c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return } c.Writer.WriteString(string(f)) @@ -621,13 +605,13 @@ func GetFileImage(c *gin.Context) { } f, err := os.Open(path) if err != nil { - c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return } defer f.Close() data, err := ioutil.ReadAll(f) if err != nil { - c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return } c.Writer.WriteString(string(data)) @@ -652,5 +636,5 @@ func DeleteOperateFileOrDir(c *gin.Context) { } go service.MyService.Notify().SendFileOperateNotify(true) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) } diff --git a/route/v1/person.go b/route/v1/person.go deleted file mode 100644 index 3385b2d..0000000 --- a/route/v1/person.go +++ /dev/null @@ -1,804 +0,0 @@ -package v1 - -import ( - "bytes" - "encoding/base64" - "encoding/gob" - "encoding/json" - "io/ioutil" - "net" - "net/http" - "os" - "reflect" - "strconv" - "strings" - "time" - - natType "github.com/Curtis-Milo/nat-type-identifier-go" - "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/pkg/config" - "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" - "github.com/IceWhaleTech/CasaOS/pkg/utils/file" - "github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper" - - "github.com/IceWhaleTech/CasaOS/service" - model2 "github.com/IceWhaleTech/CasaOS/service/model" - "github.com/IceWhaleTech/CasaOS/types" - "github.com/gin-gonic/gin" - uuid "github.com/satori/go.uuid" -) - -// @Summary Retry the file that failed to download -// @Produce application/json -// @Accept application/json -// @Tags person -// @Param uui path string true "download uuid" -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/refile/{uuid} [get] -func GetPersonReFile(c *gin.Context) { - - uid := c.Param("uuid") - _, err := uuid.FromString(uid) - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - - task := service.MyService.Download().GetDownloadById(uid) - if reflect.DeepEqual(task, model2.PersonDownloadDBModel{}) { - c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_REMOTE_ERROR, Message: common_err.GetMsg(common_err.PERSON_REMOTE_ERROR)}) - return - } - token := task.From - if _, ok := service.UDPAddressMap[token]; !ok { - c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_REMOTE_ERROR, Message: common_err.GetMsg(common_err.PERSON_REMOTE_ERROR)}) - return - } - - m := model.MessageModel{} - m.Data = task.Path - m.From = config.ServerInfo.Token - m.To = token - m.Type = types.PERSONDOWNLOAD - m.UUId = uid - go service.Dial(m, false) - - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary download file -// @Produce application/json -// @Accept application/json -// @Tags person -// @Param share_id query string true "opponent share_id" -// @Param path query string true "file path" -// @Param file_name query string true "file name" -// @Param local_path query string true "local_path" -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/file [get] -func GetPersonFile(c *gin.Context) { - - path := c.Query("path") - localPath := c.Query("local_path") - token := c.Query("share_id") - fileName := c.Query("file_name") - _, err := uuid.FromString(token) - if len(path) == 0 || err != nil || len(localPath) == 0 || len(fileName) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - if file.CheckNotExist(localPath) { - c.JSON(http.StatusOK, model.Result{Success: common_err.DIR_NOT_EXISTS, Message: common_err.GetMsg(common_err.DIR_NOT_EXISTS)}) - return - } - if _, ok := service.UDPAddressMap[token]; !ok { - c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_REMOTE_ERROR, Message: common_err.GetMsg(common_err.PERSON_REMOTE_ERROR)}) - return - } - - if _, ok := service.UDPAddressMap[token]; !ok { - c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_REMOTE_ERROR, Message: common_err.GetMsg(common_err.PERSON_REMOTE_ERROR)}) - return - } - - // task id - uuid := uuid.NewV4().String() - - task := model2.PersonDownloadDBModel{} - task.UUID = uuid - task.Name = fileName - task.Length = 0 - task.From = token - task.Path = path - task.Size = 0 - task.State = types.DOWNLOADAWAIT - task.Created = time.Now().Unix() - task.Type = types.PERSONFILEDOWNLOAD - task.LocalPath = localPath - if service.MyService.Download().GetDownloadListByPath(task) > 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_EXIST_DOWNLOAD, Message: common_err.GetMsg(common_err.PERSON_EXIST_DOWNLOAD)}) - return - } - service.MyService.Download().AddDownloadTask(task) - - m := model.MessageModel{} - m.Data = path - m.From = config.ServerInfo.Token - m.To = token - m.Type = types.PERSONDOWNLOAD - m.UUId = uuid - go service.Dial(m, false) - - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary delete download file records -// @Produce application/json -// @Accept application/json -// @Tags person -// @Param uuid path string true "download uuid" -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/file/{uuid} [delete] -func DeletePersonDownloadFile(c *gin.Context) { - - id := c.Param("uuid") - _, err := uuid.FromString(id) - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - - task := service.MyService.Download().GetDownloadById(id) - if task.State == types.DOWNLOADING { - m := model.MessageModel{} - m.Data = "" - m.From = config.ServerInfo.Token - m.To = task.From - m.Type = types.PERSONCANCEL - m.UUId = task.UUID - service.CancelList[task.UUID] = task.UUID - service.Dial(m, false) - } - service.MyService.Download().DelDownload(id) - - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary Get file download list -// @Produce application/json -// @Accept application/json -// @Tags person -// @Param state query int false "wait:0,downloading:1,pause:2,finish:3,error:4,finished:5" Enums(0,1,2,3,4,5) -// @Security ApiKeyAuth -// @Success 200 {object} []model2.PersonDownloadDBModel -// @Router /person/list [get] -func GetPersonDownloadList(c *gin.Context) { - state := c.DefaultQuery("state", "") - list := service.MyService.Download().GetDownloadListByState(state, types.PERSONFILEDOWNLOAD) - //if it is downloading, it need to add 'already' - for i := 0; i < len(list); i++ { - if list[i].State == types.DOWNLOADING { - tempDir := config.AppInfo.TempPath + "/" + list[i].UUID - files, err := ioutil.ReadDir(tempDir) - if err == nil { - list[i].Already = len(files) - } - } - list[i].Duration = time.Now().Unix() - list[i].Created - } - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list}) -} - -// @Summary edit friend's remarks -// @Produce application/json -// @Accept application/json -// @Tags person -// @Param remarks formData string true "remarks name" -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/remarks/{shareid} [put] -func PutPersonRemarks(c *gin.Context) { - token := c.Param("shareid") - _, err := uuid.FromString(token) - mark := c.PostForm("remarks") - if err != nil || len(mark) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - friend := model2.FriendModel{} - friend.Token = token - friend.Mark = mark - service.MyService.Friend().EditFriendMark(friend) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary edit friend's -// @Produce application/json -// @Accept application/json -// @Tags person -// @Param write formData bool true "write" -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/write/{shareid} [put] -func PutPersonWrite(c *gin.Context) { - token := c.Param("shareid") - _, err := uuid.FromString(token) - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - write, _ := strconv.ParseBool(c.PostForm("write")) - friend := model2.FriendModel{} - friend.Token = token - friend.Write = write - service.MyService.Friend().EditFriendMark(friend) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary image thumbnail -// @Produce application/json -// @Accept application/json -// @Tags person -// @Param write formData bool true "write" -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/image/thumbnail/{shareid} [get] -func GetPersonImageThumbnail(c *gin.Context) { - token := c.Param("shareid") - path := c.Query("path") - _, err := uuid.FromString(token) - if err != nil || len(path) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - uuid := uuid.NewV4().String() - m := model.MessageModel{} - m.Data = path - m.From = config.ServerInfo.Token - m.To = token - m.Type = types.PERSONIMAGETHUMBNAIL - m.UUId = uuid - - img, err := service.Dial(m, false) - if err != nil { - c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) - return - } - - // var buf bytes.Buffer - //err = gob.NewEncoder(&buf).Encode(img.Data) - - if err != nil { - c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) - return - } - var buf bytes.Buffer - err = gob.NewEncoder(&buf).Encode(img.Data) - if err != nil { - c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) - return - } - - imageBuffer, _ := base64.StdEncoding.DecodeString(img.Data.(string)) - c.Writer.WriteString(string(imageBuffer)) - // c.String(http.StatusOK, "data:image/"+filesuffix+";base64,"+img.Data.(string)) - //c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: img.Data.(string)}) -} - -// @Summary get my friend list -// @Produce application/json -// @Accept application/json -// @Tags person -// @Security ApiKeyAuth -// @Success 200 {object} []model2.FriendModel -// @Router /person/users [get] -func GetPersonFriend(c *gin.Context) { - list := service.MyService.Friend().GetFriendList() - for i := 0; i < len(list); i++ { - if v, ok := service.UDPAddressMap[list[i].Token]; ok && len(v) > 0 { - list[i].OnLine = true - if ip_helper.HasLocalIP(net.ParseIP(strings.Split(v, ":")[0])) { - list[i].LocalIP = strings.Split(v, ":")[0] - } - } - } - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list}) -} - -// @Summary network type detection -// @Produce application/json -// @Accept application/json -// @Tags person -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/detection [get] -func GetPersonDetection(c *gin.Context) { - // - Blocked - // - Open Internet - // - Full Cone - // - Symmetric UDP Firewall - // - Restric NAT - // - Restric Port NAT - // - Symmetric NAT - - result, err := natType.GetDeterminedNatType(true, 5, "stun.l.google.com") - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) - return - } - //result := service.MyService.Person().GetPersionNetWorkTypeDetection() - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: result}) -} - -// @Summary add friend -// @Produce application/json -// @Accept application/json -// @Tags person -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/user/{shareids} [post] -func PostAddPersonFriend(c *gin.Context) { - token := c.Param("shareids") - tokenList := strings.Split(token, ",") - - for _, v := range tokenList { - _, err := uuid.FromString(v) - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - - if v == config.ServerInfo.Token { - c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_MYSELF, Message: common_err.GetMsg(common_err.PERSON_MYSELF)}) - return - } - - udb := service.MyService.Friend().GetFriendById(model2.FriendModel{Token: v}) - if !reflect.DeepEqual(udb, model2.FriendModel{Token: v}) { - c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_EXIST_FRIEND, Message: common_err.GetMsg(common_err.PERSON_EXIST_FRIEND)}) - return - } - - user := service.MyService.Casa().GetUserInfoByShareId(v) - if reflect.DeepEqual(user, model.UserInfo{}) { - c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_NOT_EXIST_USER, Message: common_err.GetMsg(common_err.PERSON_NOT_EXIST_USER)}) - return - } - - message := model.MessageModel{} - message.Type = types.PERSONCONNECTION - message.Data = v - message.From = config.ServerInfo.Token - message.To = v - message.UUId = uuid.NewV4().String() - - go service.Dial(message, true) - - msg := model.MessageModel{} - msg.Type = types.PERSONGETIP - msg.Data = "" - msg.From = config.ServerInfo.Token - msg.To = v - msg.UUId = uuid.NewV4().String() - - service.Dial(msg, true) - - friend := model2.FriendModel{} - friend.Token = v - friend.Avatar = user.Avatar - friend.Block = false - friend.State = types.FRIENDSTATEWAIT - friend.NickName = user.NickName - friend.Profile = user.Desc - friend.Version = user.Version - service.MyService.Friend().AddFriend(friend) - } - - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary Get a list of directories -// @Produce application/json -// @Accept application/json -// @Tags person -// @Param share_id query string true "Opponent share_id" -// @Param path query string true "dir path" -// @Security ApiKeyAuth -// @Success 200 {object} []model.Path -// @Router /person/directory [get] -func GetPersonDirectory(c *gin.Context) { - path := c.Query("path") - token := c.Query("share_id") - _, err := uuid.FromString(token) - if len(path) == 0 || err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - if _, ok := service.UDPAddressMap[token]; !ok { - c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_REMOTE_ERROR, Message: common_err.GetMsg(common_err.PERSON_REMOTE_ERROR)}) - return - } - uuid := uuid.NewV4().String() - m := model.MessageModel{} - m.Data = path - m.From = config.ServerInfo.Token - m.To = token - m.Type = types.PERSONDIRECTORY - m.UUId = uuid - result, err := service.Dial(m, false) - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) - return - } - dataModel := []model.Path{} - if uuid == m.UUId { - dataModelByte, _ := json.Marshal(result.Data) - err := json.Unmarshal(dataModelByte, &dataModel) - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) - return - } - } - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: dataModel}) -} - -// @Summary Modify the download storage directory -// @Produce application/json -// @Accept multipart/form-data -// @Tags person -// @Security ApiKeyAuth -// @Param path formData string true "path" -// @Success 200 {string} string "ok" -// @Router /person/down/dir [post] -func PostPersonDownDir(c *gin.Context) { - - downPath := c.PostForm("path") - - if len(downPath) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - if file.CheckNotExist(downPath) { - c.JSON(http.StatusOK, model.Result{Success: common_err.DIR_NOT_EXISTS, Message: common_err.GetMsg(common_err.DIR_NOT_EXISTS)}) - return - } - config.Cfg.Section("file").Key("DownloadDir").SetValue(downPath) - config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath) - config.FileSettingInfo.DownloadDir = downPath - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary Get the download storage directory -// @Produce application/json -// @Accept application/json -// @Tags person -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/down/dir [get] -func GetPersonDownDir(c *gin.Context) { - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: config.FileSettingInfo.DownloadDir}) -} - -// @Summary Modify the shared directory -// @Produce application/json -// @Accept multipart/form-data -// @Tags person -// @Security ApiKeyAuth -// @Param share formData string true "share" -// @Success 200 {string} string "ok" -// @Router /person/share [post] -func PostPersonShare(c *gin.Context) { - - share := c.PostForm("share") - - if len(share) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - - var list []string - json.Unmarshal([]byte(share), &list) - - if len(list) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - for _, v := range list { - if !file.Exists(v) { - c.JSON(http.StatusOK, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)}) - return - } - } - - config.Cfg.Section("file").Key("ShareDir").SetValue(strings.Join(list, "|")) - config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath) - config.FileSettingInfo.ShareDir = list - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary Get the shared directory -// @Produce application/json -// @Accept application/json -// @Tags person -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/share [get] -func GetPersonShare(c *gin.Context) { - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: config.FileSettingInfo.ShareDir}) -} - -// @Summary Get the shareid -// @Produce application/json -// @Accept application/json -// @Tags person -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/shareid [get] -func GetPersonShareId(c *gin.Context) { - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: config.ServerInfo.Token}) -} - -// @Summary Modify disabled status -// @Produce application/json -// @Accept application/json -// @Tags person -// @Param block formData bool false "Disable or not,Default:false " -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/block/{shareid} [put] -func PutPersonBlock(c *gin.Context) { - token := c.Param("shareid") - _, err := uuid.FromString(token) - block, _ := strconv.ParseBool(c.PostForm("block")) - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - friend := model2.FriendModel{} - friend.Token = token - friend.Block = block - service.MyService.Friend().EditFriendBlock(friend) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary Delete my friend -// @Produce application/json -// @Accept application/json -// @Tags person -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/user/{shareid} [delete] -func DeletePersonFriend(c *gin.Context) { - token := c.Param("shareid") - _, err := uuid.FromString(token) - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - friend := model2.FriendModel{} - friend.Token = token - - service.MyService.Friend().DeleteFriend(friend) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary Get public person -// @Produce application/json -// @Accept application/json -// @Tags person -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/public [get] -func GetPersonPublic(c *gin.Context) { - list := service.MyService.Casa().GetPersonPublic() - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list}) -} - -// @Summary upload file to friend -// @Produce application/json -// @Accept application/json -// @Tags person -// @Security ApiKeyAuth -// @Param path formData string true "Destination path" -// @Param local_path formData string true "Full path of the file to be uploaded" -// @Success 200 {string} string "ok" -// @Router /person/file/{shareid} [post] -func PostPersonFile(c *gin.Context) { - token := c.Param("shareid") - _, err := uuid.FromString(token) - path := c.PostForm("path") - localPath := c.PostForm("local_path") - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - if !file.Exists(localPath) { - c.JSON(http.StatusOK, model.Result{Success: common_err.FILE_DOES_NOT_EXIST, Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST)}) - return - } - uuid := uuid.NewV4().String() - m := model.MessageModel{} - m.Data = path - m.From = config.ServerInfo.Token - m.To = token - m.Type = types.PERSONUPLOAD - m.UUId = uuid - go service.UDPSendData(m, localPath) - - f, _ := os.Stat(localPath) - - task := model2.PersonDownloadDBModel{} - task.UUID = uuid - task.Name = f.Name() - task.Length = 0 - task.From = token - task.Path = path - task.Size = f.Size() - task.State = types.DOWNLOADFINISHED - task.Created = time.Now().Unix() - task.Type = types.PERSONFILEUPLOAD - task.LocalPath = localPath - if service.MyService.Download().GetDownloadListByPath(task) > 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_EXIST_DOWNLOAD, Message: common_err.GetMsg(common_err.PERSON_EXIST_DOWNLOAD)}) - return - } - service.MyService.Download().AddDownloadTask(task) - - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary agree add friend -// @Produce application/json -// @Accept application/json -// @Tags person -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/friend/{shareid} [put] -func PutPersonAgreeFriend(c *gin.Context) { - token := c.Param("shareid") - _, err := uuid.FromString(token) - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - - user := service.MyService.Friend().GetFriendById(model2.FriendModel{Token: token}) - - if user.State != types.FRIENDSTATEREQUEST { - c.JSON(http.StatusOK, model.Result{Success: common_err.COMMAND_ERROR_INVALID_OPERATION, Message: common_err.GetMsg(common_err.COMMAND_ERROR_INVALID_OPERATION)}) - return - } - service.MyService.Friend().AgreeFrined(user.Token) - - uuid := uuid.NewV4().String() - m := model.MessageModel{} - m.Data = "" - m.From = config.ServerInfo.Token - m.To = token - m.Type = types.PERSONAGREEFRIEND - m.UUId = uuid - go service.Dial(m, true) - - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// // @Summary upload file -// // @Produce application/json -// // @Accept multipart/form-data -// // @Tags person -// // @Security ApiKeyAuth -// // @Param path formData string false "file path" -// // @Param file formData file true "file" -// // @Success 200 {string} string "ok" -// // @Router /person/upload/{shareid} [get] -// func GetPersonFileUpload(c *gin.Context) { - -// token := c.Param("shareid") -// _, err := uuid.FromString(token) -// path := c.Query("path") -// if err != nil { -// c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) -// return -// } - -// relative := c.Query("relativePath") -// fileName := c.Query("filename") -// chunkNumber := c.Query("chunkNumber") -// totalChunks, _ := strconv.Atoi(c.DefaultQuery("totalChunks", "0")) -// dirPath := "" -// hash := file.GetHashByContent([]byte(fileName)) -// tempDir := "/casaOS/temp/" + hash + strconv.Itoa(totalChunks) + "/" -// if fileName != relative { -// dirPath = strings.TrimSuffix(relative, fileName) -// tempDir += dirPath -// file.MkDir(path + "/" + dirPath) -// } -// tempDir += chunkNumber -// if !file.CheckNotExist(tempDir) { -// c.JSON(200, model.Result{Success: 200, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)}) -// return -// } - -// c.JSON(204, model.Result{Success: 204, Message: common_err.GetMsg(common_err.SUCCESS)}) -// } - -// // @Summary upload file -// // @Produce application/json -// // @Accept multipart/form-data -// // @Tags person -// // @Security ApiKeyAuth -// // @Param path formData string false "file path" -// // @Param file formData file true "file" -// // @Success 200 {string} string "ok" -// // @Router /person/upload [post] -// func PostPersonFileUpload(c *gin.Context) { -// token := c.Param("shareid") -// _, err := uuid.FromString(token) -// if err != nil { -// c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) -// return -// } -// f, _, _ := c.Request.FormFile("file") -// relative := c.PostForm("relativePath") -// fileName := c.PostForm("filename") -// totalChunks, _ := strconv.Atoi(c.DefaultPostForm("totalChunks", "0")) -// chunkNumber := c.PostForm("chunkNumber") -// dirPath := "" -// path := c.PostForm("path") - -// hash := file.GetHashByContent([]byte(fileName)) - -// if len(path) == 0 { -// c.JSON(common_err.INVALID_PARAMS, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) -// return -// } -// tempDir := "/casaOS/temp/" + hash + strconv.Itoa(totalChunks) + "/" - -// if fileName != relative { -// dirPath = strings.TrimSuffix(relative, fileName) -// tempDir += dirPath -// file.MkDir(path + "/" + dirPath) -// } - -// path += "/" + relative - -// if !file.CheckNotExist(tempDir + chunkNumber) { -// file.RMDir(tempDir + chunkNumber) -// } - -// if totalChunks > 1 { -// file.IsNotExistMkDir(tempDir) - -// out, _ := os.OpenFile(tempDir+chunkNumber, os.O_WRONLY|os.O_CREATE, 0644) -// defer out.Close() -// _, err := io.Copy(out, f) -// if err != nil { -// c.JSON(common_err.ERROR, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) -// return -// } -// } else { -// out, _ := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0644) -// defer out.Close() -// _, err := io.Copy(out, f) -// if err != nil { -// c.JSON(common_err.ERROR, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) -// return -// } -// c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -// return -// } - -// fileNum, err := ioutil.ReadDir(tempDir) -// if err != nil { -// c.JSON(common_err.ERROR, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) -// return -// } -// if totalChunks == len(fileNum) { -// file.RMDir(tempDir) -// } - -// c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -// } diff --git a/route/v1/shortcuts.go b/route/v1/shortcuts.go deleted file mode 100644 index c866470..0000000 --- a/route/v1/shortcuts.go +++ /dev/null @@ -1,107 +0,0 @@ -/* - * @Author: LinkLeong link@icewhale.com - * @Date: 2021-09-30 18:18:14 - * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-15 14:30:05 - * @FilePath: /CasaOS/route/v1/shortcuts.go - * @Description: - * @Website: https://www.casaos.io - * Copyright (c) 2022 by icewhale, All Rights Reserved. - */ -package v1 - -import ( - "net/http" - "net/url" - - "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" - "github.com/IceWhaleTech/CasaOS/service" - model2 "github.com/IceWhaleTech/CasaOS/service/model" - "github.com/gin-gonic/gin" -) - -// @Summary 获取短链列表 -// @Produce application/json -// @Accept application/json -// @Tags shortcuts -// @Param username formData string true "User name" -// @Param pwd formData string true "password" -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /shortcuts/list [get] -func GetShortcutsList(c *gin.Context) { - list := service.MyService.Shortcuts().GetList() - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list}) -} - -// @Summary 添加shortcuts -// @Produce application/json -// @Accept application/json -// @Tags shortcuts -// @Param title formData string true "title" -// @Param url formData string true "url" -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /shortcuts/add [post] -func PostShortcutsAdd(c *gin.Context) { - var m model2.ShortcutsDBModel - - c.BindJSON(&m) - if len(m.Url) == 0 || len(m.Title) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - u, err := url.Parse(m.Url) - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.SHORTCUTS_URL_ERROR, Message: common_err.GetMsg(common_err.SHORTCUTS_URL_ERROR), Data: err.Error()}) - return - } - m.Icon = "https://api.faviconkit.com/" + u.Host + "/57" - service.MyService.Shortcuts().AddData(m) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) - -} - -// @Summary 删除shortcuts -// @Produce application/json -// @Accept application/json -// @Tags shortcuts -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /shortcuts/del/{id} [post] -func DeleteShortcutsDelete(c *gin.Context) { - id := c.Param("id") - service.MyService.Shortcuts().DeleteData(id) - c.JSON(http.StatusOK, model.Result{ - Success: common_err.SUCCESS, - Message: common_err.GetMsg(common_err.SUCCESS), - Data: "", - }) -} - -// @Summary 编辑shortcuts -// @Produce application/json -// @Accept application/json -// @Tags shortcuts -// @Param title formData string true "title" -// @Param url formData string true "url" -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /shortcuts/edit [put] -func PutShortcutsEdit(c *gin.Context) { - var m model2.ShortcutsDBModel - c.BindJSON(&m) - if len(m.Url) == 0 || len(m.Title) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - u, err := url.Parse(m.Url) - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.SHORTCUTS_URL_ERROR, Message: common_err.GetMsg(common_err.SHORTCUTS_URL_ERROR), Data: err.Error()}) - return - } - m.Icon = "https://api.faviconkit.com/" + u.Host + "/57" - service.MyService.Shortcuts().EditData(m) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: ""}) -} diff --git a/route/v1/storage.go b/route/v1/storage.go new file mode 100644 index 0000000..ca02ed6 --- /dev/null +++ b/route/v1/storage.go @@ -0,0 +1,17 @@ +/* + * @Author: LinkLeong link@icewhale.com + * @Date: 2022-07-11 16:02:29 + * @LastEditors: LinkLeong + * @LastEditTime: 2022-07-11 16:02:55 + * @FilePath: /CasaOS/route/v1/storage.go + * @Description: + * @Website: https://www.casaos.io + * Copyright (c) 2022 by icewhale, All Rights Reserved. + */ +package v1 + +import "github.com/gin-gonic/gin" + +func GetStorageList(c *gin.Context) { + +} diff --git a/route/v1/sync.go b/route/v1/sync.go deleted file mode 100644 index 14a7f65..0000000 --- a/route/v1/sync.go +++ /dev/null @@ -1,27 +0,0 @@ -/* - * @Author: LinkLeong link@icewhale.com - * @Date: 2021-11-08 18:02:02 - * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-21 19:13:59 - * @FilePath: /CasaOS/route/v1/sync.go - * @Description: - * @Website: https://www.casaos.io - * Copyright (c) 2022 by icewhale, All Rights Reserved. - */ -package v1 - -import ( - "net/http" - - "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/pkg/config" - "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" - "github.com/gin-gonic/gin" -) - -func GetSyncConfig(c *gin.Context) { - data := make(map[string]string) - data["key"] = config.SystemConfigInfo.SyncKey - data["port"] = config.SystemConfigInfo.SyncPort - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) -} diff --git a/route/v1/system.go b/route/v1/system.go index 4b57278..42d7d32 100644 --- a/route/v1/system.go +++ b/route/v1/system.go @@ -1,7 +1,6 @@ package v1 import ( - "encoding/json" "fmt" "net/http" "os" @@ -21,7 +20,6 @@ import ( model2 "github.com/IceWhaleTech/CasaOS/service/model" "github.com/IceWhaleTech/CasaOS/types" "github.com/gin-gonic/gin" - uuid "github.com/satori/go.uuid" "go.uber.org/zap" ) @@ -45,10 +43,10 @@ func GetSystemCheckVersion(c *gin.Context) { service.MyService.Notify().AddLog(installLog) } data := make(map[string]interface{}, 3) - data["is_need"] = need + data["need_update"] = need data["version"] = version data["current_version"] = types.CURRENTVERSION - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) } // @Summary 系统信息 @@ -63,12 +61,7 @@ func SystemUpdate(c *gin.Context) { if need { service.MyService.System().UpdateSystemVersion(version.Version) } - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -//Get system config -func GetSystemConfig(c *gin.Context) { - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: ""}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) } // @Summary get logs @@ -80,86 +73,29 @@ func GetSystemConfig(c *gin.Context) { // @Router /sys/error/logs [get] func GetCasaOSErrorLogs(c *gin.Context) { line, _ := strconv.Atoi(c.DefaultQuery("line", "100")) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: service.MyService.System().GetCasaOSLogs(line)}) -} - -// @Summary 修改配置文件 -// @Produce application/json -// @Accept multipart/form-data -// @Tags sys -// @Param config formData string true "config json string" -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /sys/changhead [post] -func PostSetSystemConfig(c *gin.Context) { - buf := make([]byte, 1024) - n, _ := c.Request.Body.Read(buf) - - service.MyService.System().UpSystemConfig(string(buf[0:n]), "") - c.JSON(http.StatusOK, - model.Result{ - Success: common_err.SUCCESS, - Message: common_err.GetMsg(common_err.SUCCESS), - Data: json.RawMessage(config.SystemConfigInfo.ConfigStr), - }) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: service.MyService.System().GetCasaOSLogs(line)}) } //系统配置 func GetSystemConfigDebug(c *gin.Context) { - array := service.MyService.System().GetSystemConfigDebug() disk := service.MyService.System().GetDiskInfo() sys := service.MyService.System().GetSysInfo() - //todo 准备sync需要显示的数据(镜像,容器) - var systemAppStatus string - images := service.MyService.Docker().IsExistImage("linuxserver/syncthing") - systemAppStatus += "Sync img: " + strconv.FormatBool(images) + "\n\t" - - list := service.MyService.App().GetSystemAppList() - for _, v := range list { - systemAppStatus += v.Image + ",\n\t" - } - - systemAppStatus += "Sync Key length: " + strconv.Itoa(len(config.SystemConfigInfo.SyncKey)) - + version := service.MyService.Casa().GetCasaosVersion() var bugContent string = fmt.Sprintf(` - OS: %s - CasaOS Version: %s - Disk Total: %v - Disk Used: %v - - Sync State: %s - System Info: %s + - Remote Version: %s - Browser: $Browser$ - Version: $Version$ -`, sys.OS, types.CURRENTVERSION, disk.Total>>20, disk.Used>>20, systemAppStatus, array) +`, sys.OS, types.CURRENTVERSION, disk.Total>>20, disk.Used>>20, array, version.Version) // array = append(array, fmt.Sprintf("disk,total:%v,used:%v,UsedPercent:%v", disk.Total>>20, disk.Used>>20, disk.UsedPercent)) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: bugContent}) -} - -//widget配置 -func GetWidgetConfig(c *gin.Context) { - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json.RawMessage(config.SystemConfigInfo.WidgetList)}) -} - -// @Summary 修改组件配置文件 -// @Produce application/json -// @Accept application/json -// @Tags sys -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /sys/widget/config [post] -func PostSetWidgetConfig(c *gin.Context) { - buf := make([]byte, 1024) - n, _ := c.Request.Body.Read(buf) - service.MyService.System().UpSystemConfig("", string(buf[0:n])) - c.JSON(http.StatusOK, - model.Result{ - Success: common_err.SUCCESS, - Message: common_err.GetMsg(common_err.SUCCESS), - Data: json.RawMessage(config.SystemConfigInfo.WidgetList), - }) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: bugContent}) } // @Summary get casaos server port @@ -170,7 +106,7 @@ func PostSetWidgetConfig(c *gin.Context) { // @Success 200 {string} string "ok" // @Router /sys/port [get] func GetCasaOSPort(c *gin.Context) { - c.JSON(http.StatusOK, + c.JSON(common_err.SUCCESS, model.Result{ Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), @@ -188,13 +124,13 @@ func GetCasaOSPort(c *gin.Context) { // @Router /sys/port [put] func PutCasaOSPort(c *gin.Context) { json := make(map[string]string) - c.BindJSON(&json) + c.ShouldBind(&json) portStr := json["port"] port, err := strconv.Atoi(portStr) if err != nil { - c.JSON(http.StatusOK, + c.JSON(common_err.SERVICE_ERROR, model.Result{ - Success: common_err.ERROR, + Success: common_err.SERVICE_ERROR, Message: err.Error(), }) return @@ -202,7 +138,7 @@ func PutCasaOSPort(c *gin.Context) { isAvailable := port2.IsPortAvailable(port, "tcp") if !isAvailable { - c.JSON(http.StatusOK, + c.JSON(common_err.SERVICE_ERROR, model.Result{ Success: common_err.PORT_IS_OCCUPIED, Message: common_err.GetMsg(common_err.PORT_IS_OCCUPIED), @@ -210,40 +146,13 @@ func PutCasaOSPort(c *gin.Context) { return } service.MyService.System().UpSystemPort(strconv.Itoa(port)) - c.JSON(http.StatusOK, + c.JSON(common_err.SUCCESS, model.Result{ Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), }) } -// @Summary 检查是否进入引导状态 -// @Produce application/json -// @Accept application/json -// @Tags sys -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /sys/init/check [get] -func GetSystemInitCheck(c *gin.Context) { - data := make(map[string]interface{}, 2) - - if service.MyService.User().GetUserCount() > 0 { - data["initialized"] = true - data["key"] = "" - } else { - key := uuid.NewV4().String() - service.UserRegisterHash[key] = key - data["key"] = key - data["initialized"] = false - } - c.JSON(http.StatusOK, - model.Result{ - Success: common_err.SUCCESS, - Message: common_err.GetMsg(common_err.SUCCESS), - Data: data, - }) -} - // @Summary active killing casaos // @Produce application/json // @Accept application/json @@ -263,7 +172,9 @@ func PostKillCasaOS(c *gin.Context) { // @Success 200 {string} string "ok" // @Router /sys/usb/off [put] func PutSystemUSBAutoMount(c *gin.Context) { - status := c.Param("status") + js := make(map[string]string) + c.ShouldBind(&js) + status := js["status"] if status == "on" { service.MyService.System().UpdateUSBAutoMount("True") service.MyService.System().ExecUSBAutoMountShell("True") @@ -272,7 +183,7 @@ func PutSystemUSBAutoMount(c *gin.Context) { service.MyService.System().ExecUSBAutoMountShell("False") } - c.JSON(http.StatusOK, + c.JSON(common_err.SUCCESS, model.Result{ Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), @@ -292,7 +203,7 @@ func GetSystemUSBAutoMount(c *gin.Context) { state = "False" } - c.JSON(http.StatusOK, + c.JSON(common_err.SUCCESS, model.Result{ Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), @@ -300,6 +211,40 @@ func GetSystemUSBAutoMount(c *gin.Context) { }) } +func GetSystemAppsStatus(c *gin.Context) { + systemAppList := service.MyService.App().GetSystemAppList() + appList := []model2.MyAppList{} + for _, v := range systemAppList { + name := strings.ReplaceAll(v.Names[0], "/", "") + if len(v.Labels["name"]) > 0 { + name = v.Labels["name"] + } + appList = append(appList, model2.MyAppList{ + Name: name, + Icon: v.Labels["icon"], + State: v.State, + CustomId: v.Labels["custom_id"], + Id: v.ID, + Port: v.Labels["web"], + Index: v.Labels["index"], + //Order: m.Labels["order"], + Image: v.Image, + Latest: false, + //Type: m.Labels["origin"], + //Slogan: m.Slogan, + //Rely: m.Rely, + Host: v.Labels["host"], + Protocol: v.Labels["protocol"], + }) + } + c.JSON(common_err.SUCCESS, + model.Result{ + Success: common_err.SUCCESS, + Message: common_err.GetMsg(common_err.SUCCESS), + Data: appList, + }) +} + // @Summary get system hardware info // @Produce application/json // @Accept application/json @@ -311,7 +256,7 @@ func GetSystemHardwareInfo(c *gin.Context) { data := make(map[string]string, 1) data["drive_model"] = service.MyService.System().GetDeviceTree() - c.JSON(http.StatusOK, + c.JSON(common_err.SUCCESS, model.Result{ Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), @@ -454,7 +399,7 @@ func GetSystemUtilization(c *gin.Context) { data["net"] = newNet - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) } // @Summary Get notification port @@ -466,11 +411,11 @@ func GetSystemUtilization(c *gin.Context) { // @Router /sys/socket/port [get] func GetSystemSocketPort(c *gin.Context) { - c.JSON(http.StatusOK, + c.JSON(common_err.SUCCESS, model.Result{ Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), - Data: config.ServerInfo.SocketPort, + Data: config.ServerInfo.SocketPort, // @tiger 这里最好封装成 {'port': ...} 的形式,来体现出参的上下文 }) } @@ -540,26 +485,3 @@ func GetSystemNetInfo(c *gin.Context) { c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: newNet}) } - -//********************************************* Soon to be removed *********************************************** -// @Summary 检查是否进入引导状态 -// @Produce application/json -// @Accept application/json -// @Tags sys -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /guide/check [get] -func GetGuideCheck(c *gin.Context) { - initUser := true - if service.MyService.User().GetUserCount() > 0 { - initUser = false - } - data := make(map[string]interface{}, 1) - data["need_init_user"] = initUser - c.JSON(http.StatusOK, - model.Result{ - Success: common_err.SUCCESS, - Message: common_err.GetMsg(common_err.SUCCESS), - Data: data, - }) -} diff --git a/route/v1/user.go b/route/v1/user.go index f9bb4c8..a8c5293 100644 --- a/route/v1/user.go +++ b/route/v1/user.go @@ -10,15 +10,17 @@ import ( "path/filepath" "strconv" "strings" + "time" "github.com/IceWhaleTech/CasaOS/model" + "github.com/IceWhaleTech/CasaOS/model/system_model" "github.com/IceWhaleTech/CasaOS/pkg/config" "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" "github.com/IceWhaleTech/CasaOS/pkg/utils/encryption" "github.com/IceWhaleTech/CasaOS/pkg/utils/file" "github.com/IceWhaleTech/CasaOS/pkg/utils/jwt" model2 "github.com/IceWhaleTech/CasaOS/service/model" - "github.com/IceWhaleTech/CasaOS/types" + uuid "github.com/satori/go.uuid" "github.com/tidwall/gjson" "github.com/IceWhaleTech/CasaOS/service" @@ -29,46 +31,47 @@ import ( // @Router /user/register/ [post] func PostUserRegister(c *gin.Context) { json := make(map[string]string) - c.BindJSON(&json) - username := json["user_name"] + c.ShouldBind(&json) + + username := json["username"] pwd := json["password"] - key := c.Param("key") + key := json["key"] if _, ok := service.UserRegisterHash[key]; !ok { - c.JSON(http.StatusOK, + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.KEY_NOT_EXIST, Message: common_err.GetMsg(common_err.KEY_NOT_EXIST)}) return } if len(username) == 0 || len(pwd) == 0 { - c.JSON(http.StatusOK, + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return } if len(pwd) < 6 { - c.JSON(http.StatusOK, + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.PWD_IS_TOO_SIMPLE, Message: common_err.GetMsg(common_err.PWD_IS_TOO_SIMPLE)}) return } oldUser := service.MyService.User().GetUserInfoByUserName(username) if oldUser.Id > 0 { - c.JSON(http.StatusOK, + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.USER_EXIST, Message: common_err.GetMsg(common_err.USER_EXIST)}) return } user := model2.UserDBModel{} - user.UserName = username - user.Password = encryption.GetMD5ByStr(config.UserInfo.PWD) + user.Username = username + user.Password = encryption.GetMD5ByStr(pwd) user.Role = "admin" user = service.MyService.User().CreateUser(user) if user.Id == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR)}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)}) return } file.MkDir(config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id)) delete(service.UserRegisterHash, key) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) } @@ -82,44 +85,43 @@ func PostUserRegister(c *gin.Context) { // @Router /user/login [post] func PostUserLogin(c *gin.Context) { json := make(map[string]string) - c.BindJSON(&json) + c.ShouldBind(&json) username := json["username"] - pwd := json["pwd"] + + password := json["password"] //check params is empty - if len(username) == 0 || len(pwd) == 0 { - c.JSON(http.StatusOK, + if len(username) == 0 || len(password) == 0 { + c.JSON(common_err.CLIENT_ERROR, model.Result{ - Success: common_err.ERROR, + Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS), }) return } user := service.MyService.User().GetUserAllInfoByName(username) if user.Id == 0 { - c.JSON(http.StatusOK, + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) return } - if user.Password != encryption.GetMD5ByStr(pwd) { - c.JSON(http.StatusOK, + if user.Password != encryption.GetMD5ByStr(password) { + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)}) return } + token := system_model.VerifyInformation{} + token.AccessToken = jwt.GetAccessToken(user.Username, user.Password, user.Id) + token.RefreshToken = jwt.GetRefreshToken(user.Username, user.Password, user.Id) + token.ExpiresAt = time.Now().Add(3 * time.Hour * time.Duration(1)).Unix() + data := make(map[string]interface{}, 2) user.Password = "" - // token := system_model.VerifyInformation{} - // token.AccessToken = jwt.GetAccessToken(user.UserName, user.Password, user.Id) - // token.RefreshToken = jwt.GetRefreshToken(user.UserName, user.Password, user.Id) - // token.ExpiresAt = time.Now().Add(3 * time.Hour * time.Duration(1)).Unix() - // data := make(map[string]interface{}, 2) - // data["token"] = token - // data["user"] = user - data := make(map[string]interface{}, 3) - data["token"] = jwt.GetToken(username, pwd) - data["version"] = types.CURRENTVERSION + data["token"] = token + + // TODO:1 Database fields cannot be external data["user"] = user - c.JSON(http.StatusOK, + c.JSON(common_err.SUCCESS, model.Result{ Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), @@ -139,14 +141,14 @@ func PutUserAvatar(c *gin.Context) { id := c.GetHeader("user_id") user := service.MyService.User().GetUserInfoById(id) if user.Id == 0 { - c.JSON(http.StatusOK, + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) return } f, err := c.FormFile("file") if err != nil { - c.JSON(http.StatusOK, - model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) + c.JSON(common_err.CLIENT_ERROR, + model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: err.Error()}) return } if len(user.Avatar) > 0 { @@ -165,22 +167,6 @@ func PutUserAvatar(c *gin.Context) { }) } -/** - * @description: get user avatar by user id - * @param {query} id string user id - * @method: GET - */ -func GetUserAvatar(c *gin.Context) { - id := c.Param("id") - user := service.MyService.User().GetUserInfoById(id) - - path := "default.png" - if user.Id > 0 { - path = user.Avatar - } - c.File(path) -} - // @Summary edit user name // @Produce application/json // @Accept application/json @@ -189,27 +175,42 @@ func GetUserAvatar(c *gin.Context) { // @Security ApiKeyAuth // @Success 200 {string} string "ok" // @Router /user/name/:id [put] -func PutUserName(c *gin.Context) { - //id := c.GetHeader("user_id") - json := make(map[string]string) - c.BindJSON(&json) - //userName := json["user_name"] - username := json["username"] - id := json["user_id"] - if len(username) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR)}) - return - } +func PutUserInfo(c *gin.Context) { + id := c.GetHeader("user_id") + json := model2.UserDBModel{} + c.ShouldBind(&json) user := service.MyService.User().GetUserInfoById(id) - if user.Id == 0 { - c.JSON(http.StatusOK, + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) return } - user.UserName = username - service.MyService.User().UpdateUser(user) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user}) + if len(json.Username) > 0 { + u := service.MyService.User().GetUserInfoByUserName(json.Username) + if u.Id > 0 { + c.JSON(common_err.CLIENT_ERROR, + model.Result{Success: common_err.USER_EXIST, Message: common_err.GetMsg(common_err.USER_EXIST)}) + return + } + } + + if len(json.Email) == 0 { + json.Email = user.Email + } + if len(json.Avatar) == 0 { + json.Avatar = user.Avatar + } + if len(json.Role) == 0 { + json.Role = user.Role + } + if len(json.Description) == 0 { + json.Description = user.Description + } + if len(json.Nickname) == 0 { + json.Nickname = user.Nickname + } + service.MyService.User().UpdateUser(json) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json}) } // @Summary edit user password @@ -219,31 +220,30 @@ func PutUserName(c *gin.Context) { // @Security ApiKeyAuth // @Success 200 {string} string "ok" // @Router /user/password/:id [put] -func PutUserPwd(c *gin.Context) { - //id := c.GetHeader("user_id") +func PutUserPassword(c *gin.Context) { + id := c.GetHeader("user_id") json := make(map[string]string) - c.BindJSON(&json) - oldPwd := json["old_pwd"] - pwd := json["pwd"] - id := json["user_id"] + c.ShouldBind(&json) + oldPwd := json["old_password"] + pwd := json["password"] if len(oldPwd) == 0 || len(pwd) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return } user := service.MyService.User().GetUserAllInfoById(id) if user.Id == 0 { - c.JSON(http.StatusOK, + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) return } if user.Password != encryption.GetMD5ByStr(oldPwd) { - c.JSON(http.StatusOK, model.Result{Success: common_err.PWD_INVALID_OLD, Message: common_err.GetMsg(common_err.PWD_INVALID_OLD)}) + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.PWD_INVALID_OLD, Message: common_err.GetMsg(common_err.PWD_INVALID_OLD)}) return } user.Password = encryption.GetMD5ByStr(pwd) service.MyService.User().UpdateUserPassword(user) user.Password = "" - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user}) } // @Summary edit user nick @@ -256,12 +256,11 @@ func PutUserPwd(c *gin.Context) { // @Router /user/nick [put] func PutUserNick(c *gin.Context) { - //id := c.GetHeader("user_id") + id := c.GetHeader("user_id") json := make(map[string]string) - c.BindJSON(&json) - nickName := json["nick_name"] - id := json["user_id"] - if len(nickName) == 0 { + c.ShouldBind(&json) + Nickname := json["nick_name"] + if len(Nickname) == 0 { c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return } @@ -271,10 +270,8 @@ func PutUserNick(c *gin.Context) { model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) return } - user.NickName = nickName + user.Nickname = Nickname service.MyService.User().UpdateUser(user) - //TODO:person remove together - go service.MyService.Casa().PushUserInfo() c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user}) } @@ -287,10 +284,9 @@ func PutUserNick(c *gin.Context) { // @Success 200 {string} string "ok" // @Router /user/desc [put] func PutUserDesc(c *gin.Context) { - // id := c.GetHeader("user_id") + id := c.GetHeader("user_id") json := make(map[string]string) - c.BindJSON(&json) - id := json["user_id"] + c.ShouldBind(&json) desc := json["description"] if len(desc) == 0 { c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) @@ -309,39 +305,6 @@ func PutUserDesc(c *gin.Context) { c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user}) } -// @Summary Modify user person information (Initialization use) -// @Produce application/json -// @Accept multipart/form-data -// @Tags user -// @Param nick_name formData string false "user nick name" -// @Param description formData string false "Description" -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /user/person/info [post] -func PostUserPersonInfo(c *gin.Context) { - json := make(map[string]string) - c.BindJSON(&json) - desc := json["description"] - nickName := json["nick_name"] - id := json["user_id"] - if len(desc) == 0 || len(nickName) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - user := service.MyService.User().GetUserInfoById(id) - if user.Id == 0 { - c.JSON(http.StatusOK, - model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) - return - } - //user_service.SetUser("", "", "", "", desc, nickName) - user.NickName = nickName - user.Description = desc - service.MyService.User().UpdateUser(user) - go service.MyService.Casa().PushUserInfo() - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user}) -} - // @Summary get user info // @Produce application/json // @Accept application/json @@ -349,51 +312,10 @@ func PostUserPersonInfo(c *gin.Context) { // @Success 200 {string} string "ok" // @Router /user/info/:id [get] func GetUserInfo(c *gin.Context) { - //id := c.GetHeader("user_id") - id := c.Param("id") + id := c.GetHeader("user_id") user := service.MyService.User().GetUserInfoById(id) - //***** - var u = make(map[string]string, 5) - u["user_name"] = user.UserName - u["head"] = user.Avatar - u["email"] = user.Email - u["description"] = user.NickName - u["nick_name"] = user.NickName - u["id"] = strconv.Itoa(user.Id) - - //** - - c.JSON(http.StatusOK, - model.Result{ - Success: common_err.SUCCESS, - Message: common_err.GetMsg(common_err.SUCCESS), - Data: u, - }) -} - -// @Summary get user info -// @Produce application/json -// @Accept application/json -// @Tags user -// @Success 200 {string} string "ok" -// @Router /user/info [get] -func GetUserInfoByUserName(c *gin.Context) { - json := make(map[string]string) - c.BindJSON(&json) - userName := json["user_name"] - if len(userName) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - user := service.MyService.User().GetUserInfoByUserName(userName) - if user.Id == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) - return - } - //** - - c.JSON(http.StatusOK, + c.JSON(common_err.SUCCESS, model.Result{ Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), @@ -401,29 +323,46 @@ func GetUserInfoByUserName(c *gin.Context) { }) } -// @Summary Get my shareId -// @Produce application/json -// @Accept application/json -// @Tags user -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /user/shareid [get] -func GetUserShareID(c *gin.Context) { - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: config.ServerInfo.Token}) +/** + * @description: + * @param {*gin.Context} c + * @param {string} Username + * @return {*} + * @method: + * @router: + */ +func GetUserInfoByUsername(c *gin.Context) { + username := c.Param("username") + if len(username) == 0 { + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + return + } + user := service.MyService.User().GetUserInfoByUserName(username) + if user.Id == 0 { + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) + return + } + + c.JSON(common_err.SUCCESS, + model.Result{ + Success: common_err.SUCCESS, + Message: common_err.GetMsg(common_err.SUCCESS), + Data: user, + }) } /** - * @description: get all user name + * @description: get all Usernames * @method:GET * @router:/user/all/name */ -func GetUserAllUserName(c *gin.Context) { +func GetUserAllUsername(c *gin.Context) { users := service.MyService.User().GetAllUserName() names := []string{} for _, v := range users { - names = append(names, v.UserName) + names = append(names, v.Username) } - c.JSON(http.StatusOK, + c.JSON(common_err.SUCCESS, model.Result{ Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), @@ -440,25 +379,26 @@ func GetUserAllUserName(c *gin.Context) { func GetUserCustomConf(c *gin.Context) { name := c.Param("key") if len(name) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return } - //id := c.GetHeader("user_id") - id := c.Param("id") + id := c.GetHeader("user_id") + user := service.MyService.User().GetUserInfoById(id) - // user := service.MyService.User().GetUserInfoByUserName(userName) + // user := service.MyService.User().GetUserInfoByUsername(Username) if user.Id == 0 { - c.JSON(http.StatusOK, + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) return } filePath := config.AppInfo.UserDataPath + "/" + id + "/" + name + ".json" + data := file.ReadFullFile(filePath) if !gjson.ValidBytes(data) { - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: string(data)}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: string(data)}) return } - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json2.RawMessage(string(data))}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json2.RawMessage(string(data))}) } /** @@ -468,16 +408,16 @@ func GetUserCustomConf(c *gin.Context) { * @router:/user/custom/:key */ func PostUserCustomConf(c *gin.Context) { + name := c.Param("key") if len(name) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return } - //id := c.GetHeader("user_id") - id := c.Param("id") + id := c.GetHeader("user_id") user := service.MyService.User().GetUserInfoById(id) if user.Id == 0 { - c.JSON(http.StatusOK, + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) return } @@ -485,7 +425,7 @@ func PostUserCustomConf(c *gin.Context) { filePath := config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id) file.WriteToPath(data, filePath, name+".json") - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json2.RawMessage(string(data))}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json2.RawMessage(string(data))}) } /** @@ -497,20 +437,23 @@ func PostUserCustomConf(c *gin.Context) { func DeleteUserCustomConf(c *gin.Context) { name := c.Param("key") if len(name) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return } - //id := c.GetHeader("user_id") - id := c.Param("id") + id := c.GetHeader("user_id") user := service.MyService.User().GetUserInfoById(id) if user.Id == 0 { - c.JSON(http.StatusOK, + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) return } filePath := config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id) + "/" + name + ".json" - os.Remove(filePath) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) + err := os.Remove(filePath) + if err != nil { + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)}) + return + } + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) } /** @@ -522,19 +465,18 @@ func DeleteUserCustomConf(c *gin.Context) { func DeleteUser(c *gin.Context) { id := c.Param("id") service.MyService.User().DeleteUserById(id) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: id}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: id}) } /** * @description:update user image * @method:POST - * @router:/user/file/image/:key + * @router:/user/current/image/:key */ -func PostUserFileImage(c *gin.Context) { - //id := c.GetHeader("user_id") - id := c.Param("id") +func PutUserImage(c *gin.Context) { + id := c.GetHeader("user_id") json := make(map[string]string) - c.BindJSON(&json) + c.ShouldBind(&json) path := json["path"] key := c.Param("key") @@ -571,50 +513,57 @@ func PostUserFileImage(c *gin.Context) { data := make(map[string]string, 3) data["path"] = filePath data["file_name"] = key + ext - data["online_path"] = "/v1/user/image?path=" + filePath + data["online_path"] = "/v1/users/image?path=" + filePath c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) } /** - * @description:create or update user's custom image - * @param {formData} file file "a file to be uploaded" - * @param {path} key string "file name" - * @method:POST - * @router:/user/upload/image/:key +* @description: +* @param {*gin.Context} c +* @param {file} file +* @param {string} key +* @param {string} type:avatar,background +* @return {*} +* @method: +* @router: */ func PostUserUploadImage(c *gin.Context) { - //id := c.GetHeader("user_id") - id := c.Param("id") + id := c.GetHeader("user_id") f, err := c.FormFile("file") key := c.Param("key") + t := c.PostForm("type") if len(key) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return } if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: err.Error()}) return } _, err = file.GetImageExtByName(f.Filename) if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.NOT_IMAGE, Message: common_err.GetMsg(common_err.NOT_IMAGE)}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.NOT_IMAGE, Message: common_err.GetMsg(common_err.NOT_IMAGE)}) return } ext := filepath.Ext(f.Filename) user := service.MyService.User().GetUserInfoById(id) if user.Id == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) return } + if t == "avatar" { + key = "avatar" + } path := config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id) + "/" + key + ext + c.SaveUploadedFile(f, path) data := make(map[string]string, 3) data["path"] = path data["file_name"] = key + ext - data["online_path"] = "/v1/user/image?path=" + path - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) + data["online_path"] = "/v1/users/image?path=" + path + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) } /** @@ -641,95 +590,94 @@ func GetUserImage(c *gin.Context) { defer fileTmp.Close() fileName := path.Base(filePath) + + // @tiger - RESTful 规范下不应该返回文件本身内容,而是返回文件的静态URL,由前端去解析 c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(fileName)) c.File(filePath) } func DeleteUserImage(c *gin.Context) { - // id := c.GetHeader("user_id") - id := c.Param("id") + id := c.GetHeader("user_id") path := c.Query("path") if len(path) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return } user := service.MyService.User().GetUserInfoById(id) if user.Id == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) return } if !file.Exists(path) { - c.JSON(http.StatusOK, model.Result{Success: common_err.FILE_DOES_NOT_EXIST, Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST)}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_DOES_NOT_EXIST, Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST)}) return } if !strings.Contains(path, config.AppInfo.UserDataPath+"/"+strconv.Itoa(user.Id)) { - c.JSON(http.StatusOK, model.Result{Success: common_err.INSUFFICIENT_PERMISSIONS, Message: common_err.GetMsg(common_err.INSUFFICIENT_PERMISSIONS)}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.INSUFFICIENT_PERMISSIONS, Message: common_err.GetMsg(common_err.INSUFFICIENT_PERMISSIONS)}) return } os.Remove(path) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) } -////refresh token -// func PostUserRefreshToken(c *gin.Context) { -// json := make(map[string]string) -// c.BindJSON(&json) -// refresh := json["refresh_token"] -// claims, err := jwt.ParseToken(refresh) -// if err != nil { -// c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.VERIFICATION_FAILURE), Data: err.Error()}) -// return -// } -// if claims.VerifyExpiresAt(time.Now(), true) || claims.VerifyIssuer("refresh", true) { -// c.JSON(http.StatusOK, model.Result{Success: common_err.VERIFICATION_FAILURE, Message: common_err.GetMsg(common_err.VERIFICATION_FAILURE)}) -// return -// } -// newToken := jwt.GetAccessToken(claims.UserName, claims.PassWord, claims.Id) -// if err != nil { -// c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) -// return -// } -// 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() +/** + * @description: + * @param {*gin.Context} c + * @param {string} refresh_token + * @return {*} + * @method: + * @router: + */ +func PostUserRefreshToken(c *gin.Context) { + js := make(map[string]string) + c.ShouldBind(&js) + refresh := js["refresh_token"] + claims, err := jwt.ParseToken(refresh, true) + 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()}) + 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)}) + 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() -// c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: verifyInfo}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: verifyInfo}) -// } +} -//******** soon to be removed ******** +func DeleteUserAll(c *gin.Context) { + service.MyService.User().DeleteAllUser() + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) +} -// @Summary 设置用户名和密码 +// @Summary 检查是否进入引导状态 // @Produce application/json -// @Accept multipart/form-data -// @Tags user -// @Param username formData string true "User name" -// @Param pwd formData string true "password" +// @Accept application/json +// @Tags sys // @Security ApiKeyAuth // @Success 200 {string} string "ok" -// @Router /user/setusernamepwd [post] -func Set_Name_Pwd(c *gin.Context) { - json := make(map[string]string) - c.BindJSON(&json) - username := json["username"] - pwd := json["pwd"] - if service.MyService.User().GetUserCount() > 0 || len(username) == 0 || len(pwd) == 0 { - c.JSON(http.StatusOK, - model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return +// @Router /sys/init/check [get] +func GetUserStatus(c *gin.Context) { + data := make(map[string]interface{}, 2) + + if service.MyService.User().GetUserCount() > 0 { + data["initialized"] = true + data["key"] = "" + } else { + key := uuid.NewV4().String() + service.UserRegisterHash[key] = key + data["key"] = key + data["initialized"] = false } - user := model2.UserDBModel{} - user.UserName = username - user.Password = encryption.GetMD5ByStr(pwd) - user.Role = "admin" - - user = service.MyService.User().CreateUser(user) - if user.Id == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR)}) - return - } - file.MkDir(config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id)) - - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user}) - + c.JSON(common_err.SUCCESS, + model.Result{ + Success: common_err.SUCCESS, + Message: common_err.GetMsg(common_err.SUCCESS), + Data: data, + }) } diff --git a/service/app.go b/service/app.go index 98fa30a..965c59c 100644 --- a/service/app.go +++ b/service/app.go @@ -30,13 +30,13 @@ type AppService interface { SaveContainer(m model2.AppListDBModel) GetUninstallInfo(id string) model2.AppListDBModel DeleteApp(id string) - GetContainerInfo(name string) (types.Container, error) + GetContainerInfo(id string) (types.Container, error) GetAppDBInfo(id string) model2.AppListDBModel UpdateApp(m model2.AppListDBModel) - GetSimpleContainerInfo(name string) (types.Container, error) + GetSimpleContainerInfo(id string) (types.Container, error) DelAppConfigDir(path string) GetSystemAppList() []types.Container - GetHardwareUsageSteam() + GetHardwareUsageStream() GetHardwareUsage() []model.DockerStatsModel GetAppStats(id string) string GetAllDBApps() []model2.AppListDBModel @@ -156,22 +156,32 @@ func (a *appStruct) GetMyList(index, size int, position bool) (*[]model2.MyAppLi for _, m := range containers { if m.Labels["casaos"] == "casaos" { - if m.Labels["origin"] == "system" { - continue - } + _, newVersion := NewVersionApp[m.ID] + name := strings.ReplaceAll(m.Names[0], "/", "") + icon := m.Labels["icon"] + if len(m.Labels["name"]) > 0 { + name = m.Labels["name"] + } + if m.Labels["origin"] == "system" { + name = strings.Split(m.Image, ":")[0] + if len(strings.Split(name, "/")) > 1 { + icon = "https://icon.casaos.io/main/all/" + strings.Split(name, "/")[1] + ".png" + } + } + list = append(list, model2.MyAppList{ - Name: strings.ReplaceAll(m.Names[0], "/", ""), - Icon: m.Labels["icon"], + Name: name, + Icon: icon, State: m.State, CustomId: m.Labels["custom_id"], Id: m.ID, Port: m.Labels["web"], Index: m.Labels["index"], //Order: m.Labels["order"], - Image: m.Image, - NewVersion: newVersion, - Type: m.Labels["origin"], + Image: m.Image, + Latest: newVersion, + //Type: m.Labels["origin"], //Slogan: m.Slogan, //Rely: m.Rely, Host: m.Labels["host"], @@ -179,16 +189,16 @@ func (a *appStruct) GetMyList(index, size int, position bool) (*[]model2.MyAppLi }) } else { unTranslation = append(unTranslation, model2.MyAppList{ - Name: strings.ReplaceAll(m.Names[0], "/", ""), - Icon: "", - State: m.State, - CustomId: m.ID, - Id: m.ID, - Port: "", - NewVersion: false, - Host: "", - Protocol: "", - Image: m.Image, + Name: strings.ReplaceAll(m.Names[0], "/", ""), + Icon: "", + State: m.State, + CustomId: m.ID, + Id: m.ID, + Port: "", + Latest: false, + Host: "", + Protocol: "", + Image: m.Image, }) } } @@ -274,14 +284,14 @@ func (a *appStruct) GetAllDBApps() []model2.AppListDBModel { } //获取我的应用列表 -func (a *appStruct) GetContainerInfo(name string) (types.Container, error) { +func (a *appStruct) GetContainerInfo(id string) (types.Container, error) { //获取docker应用 cli, err := client2.NewClientWithOpts(client2.FromEnv) if err != nil { loger.Error("Failed to init client", zap.Any("err", err)) } filters := filters.NewArgs() - filters.Add("name", name) + filters.Add("id", id) containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true, Filters: filters}) if err != nil { loger.Error("Failed to get container_list", zap.Any("err", err)) @@ -294,7 +304,7 @@ func (a *appStruct) GetContainerInfo(name string) (types.Container, error) { } -func (a *appStruct) GetSimpleContainerInfo(name string) (types.Container, error) { +func (a *appStruct) GetSimpleContainerInfo(id string) (types.Container, error) { //获取docker应用 cli, err := client2.NewClientWithOpts(client2.FromEnv) if err != nil { @@ -302,7 +312,7 @@ func (a *appStruct) GetSimpleContainerInfo(name string) (types.Container, error) } defer cli.Close() filters := filters.NewArgs() - filters.Add("name", name) + filters.Add("id", id) containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true, Filters: filters}) if err != nil { return types.Container{}, err @@ -366,12 +376,12 @@ func (a *appStruct) GetAppStats(id string) string { func (a *appStruct) GetHardwareUsage() []model.DockerStatsModel { - steam := true + stream := true for !isFinish { - if steam { - steam = false + if stream { + stream = false go func() { - a.GetHardwareUsageSteam() + a.GetHardwareUsageStream() }() } runtime.Gosched() @@ -386,7 +396,7 @@ func (a *appStruct) GetHardwareUsage() []model.DockerStatsModel { } -func (a *appStruct) GetHardwareUsageSteam() { +func (a *appStruct) GetHardwareUsageStream() { cli, err := client2.NewClientWithOpts(client2.FromEnv) if err != nil { @@ -400,20 +410,26 @@ func (a *appStruct) GetHardwareUsageSteam() { fts := filters.NewArgs() fts.Add("label", "casaos=casaos") //fts.Add("status", "running") - + containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true, Filters: fts}) + if err != nil { + loger.Error("Failed to get container_list", zap.Any("err", err)) + } for i := 0; i < 100; i++ { + if i%10 == 0 { + containers, err = cli.ContainerList(context.Background(), types.ContainerListOptions{All: true, Filters: fts}) + if err != nil { + loger.Error("Failed to get container_list", zap.Any("err", err)) + continue + } + } if config.CasaOSGlobalVariables.AppChange { config.CasaOSGlobalVariables.AppChange = false - dataStats.Range(func(key, value interface{}) bool { dataStats.Delete(key) return true }) } - containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true, Filters: fts}) - if err != nil { - loger.Error("Failed to get container_list", zap.Any("err", err)) - } + var temp sync.Map var wg sync.WaitGroup for _, v := range containers { @@ -435,12 +451,14 @@ func (a *appStruct) GetHardwareUsageSteam() { m, _ := dataStats.Load(v.ID) dockerStats := model.DockerStatsModel{} if m != nil { - dockerStats.Pre = m.(model.DockerStatsModel).Data + dockerStats.Previous = m.(model.DockerStatsModel).Data } dockerStats.Data = data dockerStats.Icon = v.Labels["icon"] dockerStats.Title = strings.ReplaceAll(v.Names[0], "/", "") + // @tiger - 不建议直接把依赖的数据结构封装返回。 + // 如果依赖的数据结构有变化,应该在这里适配或者保存,这样更加对客户端负责 temp.Store(v.ID, dockerStats) if i == 99 { stats.Body.Close() diff --git a/service/casa.go b/service/casa.go index 0216319..f628c77 100644 --- a/service/casa.go +++ b/service/casa.go @@ -14,24 +14,19 @@ import ( "github.com/IceWhaleTech/CasaOS/pkg/utils/httper" httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper" "github.com/IceWhaleTech/CasaOS/pkg/utils/loger" + "github.com/pkg/errors" "github.com/tidwall/gjson" "go.uber.org/zap" ) type CasaService interface { - GetServerList(index, size, tp, categoryId, key string) model.ServerAppListCollection - GetServerCategoryList() []model.CategoryList - GetServerAppInfo(id, t string, language string) model.ServerAppList + GetServerList(index, size, tp, categoryId, key string) (model.ServerAppListCollection, error) + GetServerCategoryList() (list []model.CategoryList, err error) + GetServerAppInfo(id, t string, language string) (model.ServerAppList, error) ShareAppFile(body []byte) string - PushHeart(id, t string, language string) - - PushConnectionStatus(uuid, err string, from, to, event string) - PushUserInfo() - GetUserInfoByShareId(shareId string) model.UserInfo - GetPersonPublic() (list []model.FriendsModel) GetCasaosVersion() model.Version - AsyncGetServerList() (collection model.ServerAppListCollection) - AsyncGetServerCategoryList() []model.CategoryList + AsyncGetServerList() (collection model.ServerAppListCollection, err error) + AsyncGetServerCategoryList() ([]model.CategoryList, error) } type casaService struct { @@ -46,7 +41,7 @@ func (o *casaService) ShareAppFile(body []byte) string { return content } -func (o *casaService) GetServerList(index, size, tp, categoryId, key string) model.ServerAppListCollection { +func (o *casaService) GetServerList(index, size, tp, categoryId, key string) (model.ServerAppListCollection, error) { keyName := fmt.Sprintf("list_%s_%s_%s_%s_%s", index, size, tp, categoryId, "en") collection := model.ServerAppListCollection{} @@ -54,7 +49,7 @@ func (o *casaService) GetServerList(index, size, tp, categoryId, key string) mod res, ok := result.(string) if ok { json2.Unmarshal([]byte(res), &collection) - return collection + return collection, nil } } @@ -63,7 +58,10 @@ func (o *casaService) GetServerList(index, size, tp, categoryId, key string) mod err := json2.Unmarshal(collectionStr, &collection) if err != nil { loger.Error("marshal error", zap.Any("err", err), zap.Any("content", string(collectionStr))) - collection = o.AsyncGetServerList() + collection, err = o.AsyncGetServerList() + if err != nil { + return collection, err + } } go o.AsyncGetServerList() @@ -122,20 +120,20 @@ func (o *casaService) GetServerList(index, size, tp, categoryId, key string) mod Cache.Set(keyName, string(by), time.Minute*10) } - return collection + return collection, nil } -func (o *casaService) AsyncGetServerList() (collection model.ServerAppListCollection) { +func (o *casaService) AsyncGetServerList() (collection model.ServerAppListCollection, err error) { results := file.ReadFullFile(config.AppInfo.DBPath + "/app_list.json") - err := json2.Unmarshal(results, &collection) + err = json2.Unmarshal(results, &collection) if err != nil { loger.Error("marshal error", zap.Any("err", err), zap.Any("content", string(results))) } if collection.Version == o.GetCasaosVersion().Version { - return collection + return collection, err } head := make(map[string]string) @@ -187,33 +185,36 @@ func (o *casaService) AsyncGetServerList() (collection model.ServerAppListCollec // return list // } -func (o *casaService) GetServerCategoryList() (list []model.CategoryList) { +func (o *casaService) GetServerCategoryList() (list []model.CategoryList, err error) { category := model.ServerCategoryList{} results := file.ReadFullFile(config.AppInfo.DBPath + "/app_category.json") - err := json2.Unmarshal(results, &category) + err = json2.Unmarshal(results, &category) if err != nil { loger.Error("marshal error", zap.Any("err", err), zap.Any("content", string(results))) return o.AsyncGetServerCategoryList() } go o.AsyncGetServerCategoryList() - return category.Item + return category.Item, err } -func (o *casaService) AsyncGetServerCategoryList() []model.CategoryList { +func (o *casaService) AsyncGetServerCategoryList() ([]model.CategoryList, error) { list := model.ServerCategoryList{} results := file.ReadFullFile(config.AppInfo.DBPath + "/app_category.json") err := json2.Unmarshal(results, &list) if err != nil { loger.Error("marshal error", zap.Any("err", err), zap.Any("content", string(results))) - } - - if list.Version == o.GetCasaosVersion().Version { - return nil + } else { + if list.Version == o.GetCasaosVersion().Version { + return list.Item, nil + } } item := []model.CategoryList{} head := make(map[string]string) head["Authorization"] = GetToken() listS := httper2.Get(config.ServerInfo.ServerApi+"/v2/app/category", head) + if len(listS) == 0 { + return item, errors.New("server error") + } json2.Unmarshal([]byte(gjson.Get(listS, "data").String()), &item) if len(item) > 0 { list.Version = o.GetCasaosVersion().Version @@ -224,10 +225,10 @@ func (o *casaService) AsyncGetServerCategoryList() []model.CategoryList { } file.WriteToPath(by, config.AppInfo.DBPath, "app_category.json") } - return item + return item, nil } -func (o *casaService) GetServerAppInfo(id, t string, language string) model.ServerAppList { +func (o *casaService) GetServerAppInfo(id, t string, language string) (model.ServerAppList, error) { head := make(map[string]string) @@ -235,9 +236,12 @@ func (o *casaService) GetServerAppInfo(id, t string, language string) model.Serv infoS := httper2.Get(config.ServerInfo.ServerApi+"/v2/app/info/"+id+"?t="+t+"&language="+language, head) info := model.ServerAppList{} + if infoS == "" { + return info, errors.New("server error") + } json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info) - return info + return info, nil } func GetToken() string { t := make(chan string) @@ -289,86 +293,6 @@ func (o *casaService) GetCasaosVersion() model.Version { return version } -func (o *casaService) PushHeart(id, t string, language string) { - - m := model.CasaOSHeart{} - m.UuId = id - m.Type = t - b, _ := json.Marshal(m) - - head := make(map[string]string) - - head["Authorization"] = GetToken() - - infoS := httper2.Post(config.ServerInfo.ServerApi+"/v1/analyse/heart", b, "application/json", head) - - info := model.ServerAppList{} - json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info) - -} - -func (o *casaService) PushConnectionStatus(uuid, err string, from, to, event string) { - - m := model.ConnectionStatus{} - m.UUId = uuid - m.Error = err - m.From = from - m.To = to - m.Event = event - b, _ := json.Marshal(m) - - head := make(map[string]string) - - head["Authorization"] = GetToken() - - infoS := httper2.Post(config.ServerInfo.ServerApi+"/v1/analyse/connect", b, "application/json", head) - - info := model.ServerAppList{} - json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info) - -} -func (o *casaService) PushUserInfo() { - m := model.UserInfo{} - m.Desc = config.UserInfo.Description - m.Avatar = config.UserInfo.Avatar - m.NickName = config.UserInfo.NickName - m.ShareId = config.ServerInfo.Token - b, _ := json.Marshal(m) - - head := make(map[string]string) - - head["Authorization"] = GetToken() - - infoS := httper2.Post(config.ServerInfo.ServerApi+"/v1/user/info", b, "application/json", head) - - info := model.ServerAppList{} - json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info) - -} - -func (o *casaService) GetUserInfoByShareId(shareId string) model.UserInfo { - - head := make(map[string]string) - - head["Authorization"] = GetToken() - - infoS := httper2.Get(config.ServerInfo.ServerApi+"/v1/user/info/"+shareId, head) - - info := model.UserInfo{} - json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info) - return info -} -func (o *casaService) GetPersonPublic() (list []model.FriendsModel) { - head := make(map[string]string) - - head["Authorization"] = GetToken() - - listS := httper2.Get(config.ServerInfo.ServerApi+"/v1/person/public", head) - - json2.Unmarshal([]byte(gjson.Get(listS, "data").String()), &list) - - return list -} func NewCasaService() CasaService { return &casaService{} } diff --git a/service/docker.go b/service/docker.go index 88dc966..4501345 100644 --- a/service/docker.go +++ b/service/docker.go @@ -540,6 +540,7 @@ func (ds *dockerService) DockerContainerCreate(imageName string, m model.Customi config.Labels["show_env"] = strings.Join(showENV, ",") config.Labels["protocol"] = m.Protocol config.Labels["host"] = m.Host + config.Labels["name"] = m.Label hostConfig := &container.HostConfig{Resources: res, Mounts: volumes, RestartPolicy: rp, NetworkMode: container.NetworkMode(m.NetworkModel), Privileged: m.Privileged, CapAdd: m.CapAdd} //if net != "host" { config.ExposedPorts = ports @@ -551,7 +552,7 @@ func (ds *dockerService) DockerContainerCreate(imageName string, m model.Customi hostConfig, &network.NetworkingConfig{EndpointsConfig: map[string]*network.EndpointSettings{m.NetworkModel: {NetworkID: "", Aliases: []string{}}}}, nil, - m.Label) + m.ContainerName) if err != nil { return "", err } diff --git a/service/down_record.go b/service/down_record.go deleted file mode 100644 index dfeae97..0000000 --- a/service/down_record.go +++ /dev/null @@ -1,33 +0,0 @@ -package service - -import ( - model2 "github.com/IceWhaleTech/CasaOS/service/model" - "gorm.io/gorm" -) - -type DownRecordService interface { - AddDownRecord(m model2.PersonDownRecordDBModel) - GetDownloadListByFrom(id string) []model2.PersonDownRecordDBModel - GetDownloadListByPath(path string) (list []model2.PersonDownRecordDBModel) -} -type downRecordService struct { - db *gorm.DB -} - -func (d *downRecordService) AddDownRecord(m model2.PersonDownRecordDBModel) { - d.db.Create(&m) -} - -func (d *downRecordService) GetDownloadListByFrom(id string) []model2.PersonDownRecordDBModel { - var m []model2.PersonDownRecordDBModel - d.db.Model(m).Where("from = ?", id).Find(&m) - return m -} -func (d *downRecordService) GetDownloadListByPath(path string) (list []model2.PersonDownRecordDBModel) { - d.db.Where("path = ?", path).Find(&list) - return -} - -func NewDownRecordService(db *gorm.DB) DownRecordService { - return &downRecordService{db: db} -} diff --git a/service/download.go b/service/download.go deleted file mode 100644 index 8a2ef8f..0000000 --- a/service/download.go +++ /dev/null @@ -1,66 +0,0 @@ -package service - -import ( - model2 "github.com/IceWhaleTech/CasaOS/service/model" - "gorm.io/gorm" -) - -type DownloadService interface { - AddDownloadTask(m model2.PersonDownloadDBModel) //添加下载任务 - EditDownloadState(m model2.PersonDownloadDBModel) //只修改状态 - SaveDownload(m model2.PersonDownloadDBModel) - DelDownload(uuid string) - GetDownloadById(uuid string) model2.PersonDownloadDBModel - GetDownloadListByState(state string, t int) []model2.PersonDownloadDBModel - SetDownloadError(m model2.PersonDownloadDBModel) - GetDownloadListByPath(m model2.PersonDownloadDBModel) int -} -type downloadService struct { - db *gorm.DB -} - -func (d *downloadService) GetDownloadListByPath(m model2.PersonDownloadDBModel) int { - var list []model2.PersonDownloadDBModel - d.db.Select("path").Where("path = ? AND `from` = ? AND state = 0", m.Path, m.From).Find(&list) - return len(list) -} - -func (d *downloadService) AddDownloadTask(m model2.PersonDownloadDBModel) { - - d.db.Create(&m) -} -func (d *downloadService) EditDownloadState(m model2.PersonDownloadDBModel) { - - d.db.Model(&m).Where("uuid = ?", m.UUID).Update("state", m.State) -} - -//failed during download -func (d *downloadService) SetDownloadError(m model2.PersonDownloadDBModel) { - d.db.Model(&m).Updates(m) -} - -func (d *downloadService) DelDownload(uuid string) { - var m model2.PersonDownloadDBModel - d.db.Where("uuid = ?", uuid).Delete(&m) -} -func (d *downloadService) GetDownloadById(uuid string) model2.PersonDownloadDBModel { - var m model2.PersonDownloadDBModel - d.db.Model(m).Where("uuid = ?", uuid).First(&m) - return m -} -func (d *downloadService) GetDownloadListByState(state string, t int) (list []model2.PersonDownloadDBModel) { - if len(state) == 0 { - d.db.Where("type = ?", t).Find(&list) - } else { - d.db.Where("state = ? AND type= ?", state, t).Find(&list) - } - - return -} - -func (d *downloadService) SaveDownload(m model2.PersonDownloadDBModel) { - d.db.Save(&m) -} -func NewDownloadService(db *gorm.DB) DownloadService { - return &downloadService{db: db} -} diff --git a/service/friend.go b/service/friend.go deleted file mode 100644 index f81cb03..0000000 --- a/service/friend.go +++ /dev/null @@ -1,155 +0,0 @@ -package service - -import ( - "context" - "fmt" - "net" - "reflect" - "strconv" - "time" - - "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/pkg/config" - "github.com/IceWhaleTech/CasaOS/pkg/quic_helper" - model2 "github.com/IceWhaleTech/CasaOS/service/model" - "github.com/IceWhaleTech/CasaOS/types" - "github.com/lucas-clemente/quic-go" - uuid "github.com/satori/go.uuid" - "gorm.io/gorm" -) - -type FriendService interface { - AddFriend(m model2.FriendModel) - DeleteFriend(m model2.FriendModel) - EditFriendMark(m model2.FriendModel) - EditFriendWrite(m model2.FriendModel) - EditFriendBlock(m model2.FriendModel) - GetFriendById(m model2.FriendModel) model2.FriendModel - GetFriendList() (list []model2.FriendModel) - GetFriendListRemote() (list []model2.FriendModel) - UpdateAddFriendType(m model2.FriendModel) - AgreeFrined(id string) - GetFriendByToken(token string) model2.FriendModel - UpdateOrCreate(m model2.FriendModel) - InternalInspection(ips []string, token string) -} - -type friendService struct { - db *gorm.DB -} - -func (p *friendService) AgreeFrined(id string) { - var m model2.FriendModel - p.db.Model(&m).Where("token = ?", id).Update("state", types.FRIENDSTATEDEFAULT) -} -func (p *friendService) AddFriend(m model2.FriendModel) { - p.db.Create(&m) -} -func (p *friendService) DeleteFriend(m model2.FriendModel) { - p.db.Where("token = ?", m.Token).Delete(&m) -} -func (p *friendService) EditFriendMark(m model2.FriendModel) { - p.db.Model(&m).Where("token = ?", m.Token).Update("mark", m.Mark) -} -func (p *friendService) EditFriendWrite(m model2.FriendModel) { - p.db.Model(&m).Where("token = ?", m.Token).Update("write", m.Write) -} -func (p *friendService) EditFriendBlock(m model2.FriendModel) { - p.db.Model(&m).Where("token = ?", m.Token).Update("block", m.Block) -} -func (p *friendService) GetFriendById(m model2.FriendModel) model2.FriendModel { - p.db.Model(m).Where("token = ?", m.Token).First(&m) - return m -} - -func (p *friendService) GetFriendList() (list []model2.FriendModel) { - p.db.Select("nick_name", "avatar", "profile", "token", "state", "mark", "block", "version").Find(&list) - return list -} -func (p *friendService) GetFriendListRemote() (list []model2.FriendModel) { - p.db.Select("nick_name", "avatar", "profile", "token", "state", "mark", "block", "version").Where("internal_ip == '' OR internal_ip is null").Find(&list) - return list -} -func (p *friendService) GetFriendListInternal() (list []model2.FriendModel) { - p.db.Select("nick_name", "avatar", "profile", "token", "state", "mark", "block", "version").Where("internal_ip != ''").Find(&list) - return list -} -func (p *friendService) UpdateOrCreate(m model2.FriendModel) { - friend := model2.FriendModel{} - p.db.Where("token = ?", m.Token).First(&friend) - if reflect.DeepEqual(friend, model2.FriendModel{}) { - p.db.Create(&m) - } else { - p.db.Model(&m).Updates(m) - } - -} - -func (p *friendService) UpdateAddFriendType(m model2.FriendModel) { - p.db.Model(&m).Updates(m) -} - -func (p *friendService) GetFriendByToken(token string) model2.FriendModel { - var m model2.FriendModel - p.db.Model(&m).Where("token = ?", token).First(&m) - return m -} - -func (p *friendService) InternalInspection(ips []string, token string) { - for _, v := range ips { - fmt.Println("开始遍历 ip:", v) - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - dstAddr, err := net.ResolveUDPAddr("udp", v) - if err != nil { - fmt.Println("1", err.Error()) - continue - } - port, err := strconv.Atoi(config.ServerInfo.UDPPort) - if err != nil { - fmt.Println("2", err) - continue - } - srcAddr := &net.UDPAddr{ - IP: net.IPv4zero, Port: port} - ticket := token - session, err := quic.DialContext(ctx, UDPConn, dstAddr, srcAddr.String(), quic_helper.GetClientTlsConfig(ticket), quic_helper.GetQUICConfig()) - if err != nil { - fmt.Println("3", err, v) - continue - } - - stream, err := session.OpenStreamSync(ctx) - if err != nil { - fmt.Println("4", err) - continue - } - uuid := uuid.NewV4().String() - SayHello(stream, token) - msg := model.MessageModel{ - Type: types.PERSONPING, - Data: "", - From: config.ServerInfo.Token, - To: token, - UUId: uuid, - } - - SendData(stream, msg) - - go ReadContent(stream) - result := <-Message - fmt.Println("ping返回结果:", result, msg) - stream.Close() - if !reflect.DeepEqual(result, model.MessageModel{}) && result.Data.(string) == token && result.From == token { - fmt.Println("获取到正确的ip", v) - UDPAddressMap[result.From] = v - p.db.Model(&model2.FriendModel{}).Where("token = ?", token).Update("internal_ip", v) - return - } - } -} - -func NewFriendService(db *gorm.DB) FriendService { - return &friendService{db: db} -} diff --git a/service/model/o_container.go b/service/model/o_container.go index 5d4de3a..69c32f7 100644 --- a/service/model/o_container.go +++ b/service/model/o_container.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2022-05-13 18:15:46 * @LastEditors: LinkLeong - * @LastEditTime: 2022-05-30 17:33:21 + * @LastEditTime: 2022-07-13 10:56:34 * @FilePath: /CasaOS/service/model/o_container.go * @Description: * @Website: https://www.casaos.io @@ -67,13 +67,12 @@ type MyAppList struct { Index string `json:"index"` //Order string `json:"order"` Port string `json:"port"` - UpTime string `json:"up_time"` Slogan string `json:"slogan"` Type string `json:"type"` //Rely model.MapStrings `json:"rely"` //[{"mysql":"id"},{"mysql":"id"}] - Image string `json:"image"` - Volumes string `json:"volumes"` - NewVersion bool `json:"new_version"` - Host string `json:"host"` - Protocol string `json:"protocol"` + Image string `json:"image"` + Volumes string `json:"volumes"` + Latest bool `json:"latest"` + Host string `json:"host"` + Protocol string `json:"protocol"` } diff --git a/service/model/o_down_record.go b/service/model/o_down_record.go deleted file mode 100644 index 37a5966..0000000 --- a/service/model/o_down_record.go +++ /dev/null @@ -1,16 +0,0 @@ -package model - -type PersonDownRecordDBModel struct { - UUID string `gorm:"column:uuid;primary_key" json:"uuid"` - Name string `json:"name"` //file name - Type int `json:"type"` - Size int64 `json:"size"` //file size - Downloader string `json:"downloader"` //Error message - Path string `json:"path"` - Created int64 `gorm:"autoCreateTime" json:"created"` - Updated int64 `gorm:"autoCreateTime;autoUpdateTime" json:"updated"` -} - -func (p *PersonDownRecordDBModel) TableName() string { - return "o_person_down_record" -} diff --git a/service/model/o_download.go b/service/model/o_download.go deleted file mode 100644 index af0b2d3..0000000 --- a/service/model/o_download.go +++ /dev/null @@ -1,24 +0,0 @@ -package model - -type PersonDownloadDBModel struct { - UUID string `gorm:"column:uuid;primary_key" json:"uuid"` - State int `json:"state"` // - Type int `json:"type"` //defult 0 - Name string `json:"name"` //file name - Size int64 `json:"size"` //file size - BlockSize int `json:"block_size"` //Size of each file block - Length int `json:"length"` //slice length - Hash string `json:"hash"` //File hash value - Error string `json:"error"` // - From string `json:"from"` //Error message - Path string `json:"path"` //Full path to the file - Already int `json:"already" gorm:"-"` //Folder blocks that have been downloaded - LocalPath string `json:"local_path"` //The address where the file is saved after download - Duration int64 `json:"duration" gorm:"-"` //Length of time - Created int64 `gorm:"autoCreateTime" json:"created"` - Updated int64 `gorm:"autoCreateTime;autoUpdateTime" json:"updated"` -} - -func (p *PersonDownloadDBModel) TableName() string { - return "o_person_download" -} diff --git a/service/model/o_friend.go b/service/model/o_friend.go deleted file mode 100644 index daea6a9..0000000 --- a/service/model/o_friend.go +++ /dev/null @@ -1,21 +0,0 @@ -package model - -type FriendModel struct { - State int `json:"state"` - CreatedAt int64 `gorm:"autoCreateTime" json:"created_at"` - UpdatedAt int64 `gorm:"autoCreateTime;autoUpdateTime" json:"updated_at"` - NickName string `json:"nick_name"` - Mark string `json:"mark"` //Remarks - Block bool `json:"block"` //Disable or not - Avatar string `json:"avatar"` //User avatar - Token string `gorm:"column:token;primary_key" json:"token"` - Profile string `json:"profile"` //Description - OnLine bool `json:"on_line" gorm:"-"` - Version int `json:"version"` - Write bool `json:"write"` - LocalIP string `json:"local_ip"` -} - -func (p *FriendModel) TableName() string { - return "o_friend" -} diff --git a/service/model/o_shortcuts.go b/service/model/o_shortcuts.go deleted file mode 100644 index f0fb444..0000000 --- a/service/model/o_shortcuts.go +++ /dev/null @@ -1,17 +0,0 @@ -package model - -import "time" - -type ShortcutsDBModel struct { - Id uint `gorm:"column:id;primary_key" json:"id"` - Title string `json:"title"` - Url string `json:"url"` - Icon string `json:"icon"` - Sort int `json:"sort"` - CreatedAt time.Time `gorm:"<-:create" json:"created_at"` - UpdatedAt time.Time `gorm:"<-:create;<-:update" json:"updated_at"` -} - -func (p *ShortcutsDBModel) TableName() string { - return "o_shortcuts" -} diff --git a/service/model/o_user.go b/service/model/o_user.go index d66895d..1309629 100644 --- a/service/model/o_user.go +++ b/service/model/o_user.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2022-05-13 18:15:46 * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-23 15:43:07 + * @LastEditTime: 2022-07-11 17:57:00 * @FilePath: /CasaOS/service/model/o_user.go * @Description: * @Website: https://www.casaos.io @@ -15,11 +15,11 @@ import "time" //Soon to be removed type UserDBModel struct { Id int `gorm:"column:id;primary_key" json:"id"` - UserName string `json:"user_name"` + Username string `json:"username"` Password string `json:"password,omitempty"` Role string `json:"role"` Email string `json:"email"` - NickName string `json:"nick_name"` + Nickname string `json:"nickname"` Avatar string `json:"avatar"` Description string `json:"description"` CreatedAt time.Time `gorm:"<-:create;autoCreateTime" json:"created_at,omitempty"` @@ -27,5 +27,5 @@ type UserDBModel struct { } func (p *UserDBModel) TableName() string { - return "o_user" + return "o_users" } diff --git a/service/notify.go b/service/notify.go index b68532a..3981e55 100644 --- a/service/notify.go +++ b/service/notify.go @@ -33,16 +33,31 @@ type NotifyServer interface { SendMemInfoBySocket(mem map[string]interface{}) SendUSBInfoBySocket(list []model2.DriveUSB) SendDiskInfoBySocket(disk model2.Summary) - SendPersonStatusBySocket(status notify.Person) SendFileOperateNotify(nowSend bool) SendInstallAppBySocket(app notify.Application) SendAllHardwareStatusBySocket(disk model2.Summary, list []model2.DriveUSB, mem map[string]interface{}, cpu map[string]interface{}, netList []model2.IOCountersStat) + SendStorageBySocket(message notify.StorageMessage) } type notifyServer struct { db *gorm.DB } +func (i *notifyServer) SendStorageBySocket(message notify.StorageMessage) { + body := make(map[string]interface{}) + body["data"] = message + + msg := gosf.Message{} + msg.Body = body + msg.Success = true + msg.Text = "storage_status" + + notify := notify.Message{} + notify.Path = "storage_status" + notify.Msg = msg + + NotifyMsg <- notify +} func (i *notifyServer) SendAllHardwareStatusBySocket(disk model2.Summary, list []model2.DriveUSB, mem map[string]interface{}, cpu map[string]interface{}, netList []model2.IOCountersStat) { body := make(map[string]interface{}) @@ -224,22 +239,6 @@ func (i *notifyServer) SendFileOperateNotify(nowSend bool) { } -func (i *notifyServer) SendPersonStatusBySocket(status notify.Person) { - body := make(map[string]interface{}) - body["data"] = status - - msg := gosf.Message{} - msg.Body = body - msg.Success = true - msg.Text = "person_status" - - notify := notify.Message{} - notify.Path = "person_status" - notify.Msg = msg - - NotifyMsg <- notify -} - func (i *notifyServer) SendDiskInfoBySocket(disk model2.Summary) { body := make(map[string]interface{}) body["data"] = disk diff --git a/service/person.go b/service/person.go deleted file mode 100644 index a4aa9e6..0000000 --- a/service/person.go +++ /dev/null @@ -1,482 +0,0 @@ -package service - -import ( - "bufio" - "context" - "encoding/json" - "fmt" - "io" - "net" - "os" - "reflect" - "strconv" - "time" - - "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/pkg/config" - "github.com/IceWhaleTech/CasaOS/pkg/quic_helper" - "github.com/IceWhaleTech/CasaOS/pkg/utils" - "github.com/IceWhaleTech/CasaOS/pkg/utils/file" - httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper" - "github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper" - port2 "github.com/IceWhaleTech/CasaOS/pkg/utils/port" - model2 "github.com/IceWhaleTech/CasaOS/service/model" - "github.com/IceWhaleTech/CasaOS/types" - "github.com/lucas-clemente/quic-go" - "gorm.io/gorm" -) - -type PersonService interface { - GetPersionInfo(token string) (m model.PersionModel, err error) - GetPersionNetWorkTypeDetection() string -} - -type personService struct { - db *gorm.DB -} - -var IpInfo model.PersionModel -var CancelList map[string]string -var InternalInspection map[string][]string - -func PushIpInfo(token string) { - - m := model.PersionModel{} - m.Ips = ip_helper.GetDeviceAllIP("") - m.Token = token - b, _ := json.Marshal(m) - - if reflect.DeepEqual(IpInfo, m) { - return - } - head := make(map[string]string) - infoS := httper2.Post(config.ServerInfo.Handshake+"/v1/update", b, "application/json", head) - fmt.Println(infoS) -} -func (p *personService) GetPersionInfo(token string) (m model.PersionModel, err error) { - infoS := httper2.Get(config.ServerInfo.Handshake+"/v1/ips/"+token, nil) - err = json.Unmarshal([]byte(infoS), &m) - return -} -func (p *personService) GetPersionNetWorkTypeDetection() string { - data := make(chan string) - list := []string{"stun.l.google.com", "stun1.l.google.com", "stun2.l.google.com", "stun.sipgate.net"} - for _, v := range list { - go utils.GetNetWorkTypeDetection(data, v) - } - result := <-data - close(data) - return result -} - -func NewPersonService(db *gorm.DB) PersonService { - return &personService{db: db} -} - -//======================================================================================================================================================================= - -var StreamList map[string]quic.Stream -var ServiceMessage chan model.MessageModel - -func UDPService() { - port := 0 - if len(config.ServerInfo.UDPPort) > 0 { - port, _ = strconv.Atoi(config.ServerInfo.UDPPort) - if port != 0 && !port2.IsPortAvailable(port, "udp") { - port = 0 - } - } - - srcAddr := &net.UDPAddr{ - IP: net.IPv4zero, Port: port} - var err error - UDPConn, err = net.ListenUDP("udp", srcAddr) - if err != nil { - fmt.Println(err) - } - listener, err := quic.Listen(UDPConn, quic_helper.GetGenerateTLSConfig(config.ServerInfo.Token), quic_helper.GetQUICConfig()) - if err != nil { - fmt.Println(err) - } - defer listener.Close() - ctx := context.Background() - acceptFailures := 0 - const maxAcceptFailures = 10 - if err != nil { - panic(err) - } - - for { - select { - case <-ctx.Done(): - fmt.Println(ctx.Err()) - return - default: - } - - session, err := listener.Accept(ctx) - if err != nil { - fmt.Println("Listen (BEP/quic): Accepting connection:", err) - - acceptFailures++ - if acceptFailures > maxAcceptFailures { - // Return to restart the listener, because something - // seems permanently damaged. - fmt.Println(err) - return - } - - // Slightly increased delay for each failure. - time.Sleep(time.Duration(acceptFailures) * time.Second) - - continue - } - - acceptFailures = 0 - - streamCtx, cancel := context.WithTimeout(ctx, time.Second*10) - stream, err := session.AcceptStream(streamCtx) - cancel() - if err != nil { - fmt.Println("failed to accept stream from %s: %v", session.RemoteAddr(), err) - _ = session.CloseWithError(1, err.Error()) - continue - } - - // prefixByte := make([]byte, 4) - // c1, err := io.ReadFull(stream, prefixByte) - // fmt.Println(c1, err) - // prefixLength, err := strconv.Atoi(string(prefixByte)) - // if err != nil { - // fmt.Println(err) - // } - // messageByte := make([]byte, prefixLength) - // t, err := io.ReadFull(stream, messageByte) - // fmt.Println(t, err) - // m := model.MessageModel{} - // err = json.Unmarshal(messageByte, &m) - // if err != nil { - // fmt.Println(err) - // } - - go ProcessingContent(stream) - } -} - -//处理内容 -func ProcessingContent(stream quic.Stream) { - for { - prefixByte := make([]byte, 6) - _, err := io.ReadFull(stream, prefixByte) - if err != nil { - fmt.Println(err) - return - } - prefixLength, err := strconv.Atoi(string(prefixByte)) - if err != nil { - fmt.Println(err) - } - messageByte := make([]byte, prefixLength) - _, err = io.ReadFull(stream, messageByte) - if err != nil { - return - } - m := model.MessageModel{} - err = json.Unmarshal(messageByte, &m) - if err != nil { - fmt.Println(err) - } - if m.Type == types.PERSONHELLO { - //nothing - continue - } else if m.Type == types.PERSONDIRECTORY { - friend := model2.FriendModel{} - friend.Token = m.From - var list []model.Path - rFriend := MyService.Friend().GetFriendById(friend) - if !reflect.DeepEqual(rFriend, model2.FriendModel{Token: m.From}) && !rFriend.Block { - if m.Data.(string) == "" || m.Data.(string) == "/" { - for _, v := range config.FileSettingInfo.ShareDir { - //tempList := MyService.ZiMa().GetDirPath(v) - temp := MyService.System().GetDirPathOne(v) - list = append(list, temp) - } - } else { - list = MyService.System().GetDirPath(m.Data.(string)) - } - } else { - list = []model.Path{} - } - if rFriend.Write { - for i := 0; i < len(list); i++ { - list[i].Write = true - } - } - m.To = m.From - m.Data = list - m.From = config.ServerInfo.Token - SendData(stream, m) - break - } else if m.Type == types.PERSONDOWNLOAD { - - SendFileData(stream, m.Data.(string), m.From, m.UUId, types.PERSONDOWNLOAD) - break - } else if m.Type == types.PERSONADDFRIEND { - friend := model2.FriendModel{} - dataModelByte, _ := json.Marshal(m.Data) - err := json.Unmarshal(dataModelByte, &friend) - if err != nil { - fmt.Println(err) - continue - } - go MyService.Friend().UpdateOrCreate(friend) - mi := model2.FriendModel{} - mi.Avatar = config.UserInfo.Avatar - mi.Profile = config.UserInfo.Description - mi.NickName = config.UserInfo.NickName - m.To = m.From - m.Data = mi - m.Type = types.PERSONADDFRIEND - m.From = config.ServerInfo.Token - - SendData(stream, m) - break - } else if m.Type == types.PERSONCONNECTION { - if len(m.Data.(string)) > 0 { - fmt.Println("设置ip", m.Data.(string)) - UDPAddressMap[m.From] = m.Data.(string) - } else { - delete(UDPAddressMap, m.From) - } - // mi := model2.FriendModel{} - // mi.Avatar = config.UserInfo.Avatar - // mi.Profile = config.UserInfo.Description - // mi.NickName = config.UserInfo.NickName - // mi.Token = config.ServerInfo.Token - - user := MyService.Casa().GetUserInfoByShareId(m.From) - //好友申请 //不是好友 - friend := model2.FriendModel{} - friend.Token = m.From - friend.Avatar = user.Avatar - friend.Block = false - friend.NickName = user.NickName - friend.Profile = user.Avatar - friend.Write = false - friend.Version = user.Version - if len(config.UserInfo.Public) > 0 { - friend.State = types.FRIENDSTATEREQUEST - } - MyService.Friend().AddFriend(friend) - - msg := model.MessageModel{} - msg.Type = types.PERSONHELLO - msg.Data = "" - msg.To = m.From - msg.From = config.ServerInfo.Token - msg.UUId = m.UUId - Dial(msg, false) - - //agree user - if len(config.UserInfo.Public) == 0 { - msg.Type = types.PERSONAGREEFRIEND - msg.Data = "" - msg.To = m.From - msg.From = config.ServerInfo.Token - msg.UUId = m.UUId - Dial(msg, true) - } - break - } else if m.Type == types.PERSONAGREEFRIEND { - MyService.Friend().AgreeFrined(m.From) - break - } else if m.Type == types.PERSONCANCEL { - CancelList[m.UUId] = "cancel" - break - } else if m.Type == types.PERSONSUMMARY { - Summary(m, "upload") - continue - } else if m.Type == types.PERSONUPLOAD { - //TODO:检查是否存在如果存在直接结束 - task := model2.PersonDownloadDBModel{} - task.UUID = m.UUId - task.LocalPath = m.Data.(string) - MyService.Download().AddDownloadTask(task) - friend := MyService.Friend().GetFriendById(model2.FriendModel{Token: m.From}) - if friend.Write { - continue - } else { - break - } - } else if m.Type == types.PERSONUPLOADDATA { - r := SaveFile(m, stream) - if r { - break - } - continue - } else if m.Type == types.PERSONINTERNALINSPECTION { - fmt.Println("内网测试") - var ips []string - dataModelByte, _ := json.Marshal(m.Data) - err := json.Unmarshal(dataModelByte, &ips) - if err != nil { - fmt.Println(err) - break - } - - go MyService.Friend().InternalInspection(ips, m.From) - - } else if m.Type == types.PERSONPING { - fmt.Println("来自", m.From, "的ping", m.Data) - msg := m - m.To = m.From - m.Data = config.ServerInfo.Token - m.From = config.ServerInfo.Token - SendData(stream, m) - - var ips []string - dataModelByte, _ := json.Marshal(msg.Data) - err := json.Unmarshal(dataModelByte, &ips) - if err != nil { - fmt.Println(err) - break - } - backIP := false - if v, ok := UDPAddressMap[msg.From]; ok { - for _, ip := range ips { - if ip == v { - backIP = true - break - } - } - } - if !backIP { - fmt.Println("检测需要查询ip", msg.From) - go MyService.Friend().InternalInspection(ips, msg.From) - } - - break - } else if m.Type == types.PERSONIMAGETHUMBNAIL { - m.To = m.From - - if data, err := file.GetImage(m.Data.(string), 100, 0); err == nil { - m.Data = data - } else { - m.Data = "" - } - m.From = config.ServerInfo.Token - SendData(stream, m) - break - } else { - //不应有不做返回的数据 - //ServiceMessage <- m - break - } - } - stream.Close() - -} - -//文件分片发送 -func SendFileData(stream quic.Stream, filePath, to, uuid, t string) error { - summary := model.FileSummaryModel{} - - msg := model.MessageModel{} - msg.Type = types.PERSONSUMMARY - msg.From = config.ServerInfo.Token - msg.To = to - msg.UUId = uuid - - fStat, err := os.Stat(filePath) - if err != nil { - - summary.Message = err.Error() - - msg.Data = summary - - summaryByte, _ := json.Marshal(msg) - summaryPrefixLength := file.PrefixLength(len(summaryByte)) - summaryData := append(summaryPrefixLength, summaryByte...) - stream.Write(summaryData) - return err - } - - blockSize, length := file.GetBlockInfo(fStat.Size()) - - f, err := os.Open(filePath) - if err != nil { - - summary.Message = err.Error() - msg.Data = summary - - summaryByte, _ := json.Marshal(msg) - summaryPrefixLength := file.PrefixLength(len(summaryByte)) - summaryData := append(summaryPrefixLength, summaryByte...) - stream.Write(summaryData) - return err - } - - //send file summary first - summary.BlockSize = blockSize - summary.Hash = file.GetHashByPath(filePath) - summary.Length = length - summary.Name = fStat.Name() - summary.Size = fStat.Size() - - msg.Data = summary - - summaryByte, _ := json.Marshal(msg) - summaryPrefixLength := file.PrefixLength(len(summaryByte)) - summaryData := append(summaryPrefixLength, summaryByte...) - stream.Write(summaryData) - - bufferedReader := bufio.NewReader(f) - buf := make([]byte, blockSize) - - defer stream.Close() - - for i := 0; i < length; i++ { - - tran := model.TranFileModel{} - - n, err := bufferedReader.Read(buf) - - if err == io.EOF { - fmt.Println("读取完毕", err) - } - - tran.Hash = file.GetHashByContent(buf[:n]) - tran.Index = i - tran.Length = length - - fileMsg := model.MessageModel{} - fileMsg.Type = t - fileMsg.Data = tran - fileMsg.From = config.ServerInfo.Token - fileMsg.To = to - fileMsg.UUId = uuid - b, _ := json.Marshal(fileMsg) - prefixLength := file.PrefixLength(len(b)) - dataLength := file.DataLength(len(buf[:n])) - data := append(append(append(prefixLength, b...), dataLength...), buf[:n]...) - if _, ok := CancelList[uuid]; ok { - delete(CancelList, uuid) - return nil - } - stream.Write(data) - } - record := model2.PersonDownRecordDBModel{} - record.UUID = uuid - record.Name = f.Name() - record.Downloader = to - record.Path = filePath - record.Size = fStat.Size() - record.Type = types.PERSONFILEDOWNLOAD - if t == types.PERSONUPLOADDATA { - record.Type = types.PERSONFILEUPLOAD - } - - MyService.DownRecord().AddDownRecord(record) - - return nil -} diff --git a/service/rely.go b/service/rely.go index 9c6bd3e..26037fe 100644 --- a/service/rely.go +++ b/service/rely.go @@ -35,6 +35,8 @@ func (r *relyService) Create(rely model2.RelyDBModel) { func (r *relyService) GetInfo(id string) model2.RelyDBModel { var m model2.RelyDBModel r.db.Where("custom_id = ?", id).First(&m) + + // @tiger - 作为出参不应该直接返回数据库内的格式(见类似问题的注释) return m } diff --git a/service/service.go b/service/service.go index 1087d94..2f348fc 100644 --- a/service/service.go +++ b/service/service.go @@ -1,3 +1,13 @@ +/* + * @Author: LinkLeong link@icewhale.com + * @Date: 2022-07-12 09:48:56 + * @LastEditors: LinkLeong + * @LastEditTime: 2022-07-15 10:58:54 + * @FilePath: /CasaOS/service/service.go + * @Description: + * @Website: https://www.casaos.io + * Copyright (c) 2022 by icewhale, All Rights Reserved. + */ package service import ( @@ -23,68 +33,37 @@ type Repository interface { Notify() NotifyServer Rely() RelyService System() SystemService - Shortcuts() ShortcutsService - Person() PersonService - Friend() FriendService - Download() DownloadService - DownRecord() DownRecordService } func NewService(db *gorm.DB) Repository { - return &store{ - app: NewAppService(db), - user: NewUserService(db), - docker: NewDockerService(), - casa: NewCasaService(), - disk: NewDiskService(db), - notify: NewNotifyService(db), - rely: NewRelyService(db), - system: NewSystemService(), - shortcuts: NewShortcutsService(db), - person: NewPersonService(db), - friend: NewFriendService(db), - download: NewDownloadService(db), - downrecord: NewDownRecordService(db), + app: NewAppService(db), + user: NewUserService(db), + docker: NewDockerService(), + casa: NewCasaService(), + disk: NewDiskService(db), + notify: NewNotifyService(db), + rely: NewRelyService(db), + system: NewSystemService(), } } type store struct { - db *gorm.DB - app AppService - user UserService - docker DockerService - casa CasaService - disk DiskService - notify NotifyServer - rely RelyService - system SystemService - shortcuts ShortcutsService - person PersonService - friend FriendService - download DownloadService - downrecord DownRecordService + db *gorm.DB + app AppService + user UserService + docker DockerService + casa CasaService + disk DiskService + notify NotifyServer + rely RelyService + system SystemService } -func (c *store) DownRecord() DownRecordService { - return c.downrecord -} - -func (c *store) Download() DownloadService { - return c.download -} -func (c *store) Friend() FriendService { - return c.friend -} func (c *store) Rely() RelyService { return c.rely } -func (c *store) Shortcuts() ShortcutsService { - return c.shortcuts -} -func (c *store) Person() PersonService { - return c.person -} + func (c *store) System() SystemService { return c.system } diff --git a/service/shortcuts.go b/service/shortcuts.go deleted file mode 100644 index f57404a..0000000 --- a/service/shortcuts.go +++ /dev/null @@ -1,34 +0,0 @@ -package service - -import ( - model2 "github.com/IceWhaleTech/CasaOS/service/model" - "gorm.io/gorm" -) - -type ShortcutsService interface { - DeleteData(id string) - AddData(m model2.ShortcutsDBModel) - EditData(m model2.ShortcutsDBModel) - GetList() (list []model2.ShortcutsDBModel) -} -type shortcutsService struct { - db *gorm.DB -} - -func (s *shortcutsService) AddData(m model2.ShortcutsDBModel) { - s.db.Create(&m) -} -func (s *shortcutsService) EditData(m model2.ShortcutsDBModel) { - s.db.Save(&m) -} -func (s *shortcutsService) DeleteData(id string) { - var m model2.ShortcutsDBModel - s.db.Where("id=?", id).Delete(&m) -} -func (s *shortcutsService) GetList() (list []model2.ShortcutsDBModel) { - s.db.Order("sort desc,id").Find(&list) - return list -} -func NewShortcutsService(db *gorm.DB) ShortcutsService { - return &shortcutsService{db: db} -} diff --git a/service/system.go b/service/system.go index 7d693e3..ba9ff44 100644 --- a/service/system.go +++ b/service/system.go @@ -24,7 +24,6 @@ import ( ) type SystemService interface { - UpSystemConfig(str string, widget string) UpdateSystemVersion(version string) GetSystemConfigDebug() []string GetCasaOSLogs(lineNumber int) string @@ -54,6 +53,12 @@ type SystemService interface { type systemService struct { } +func (s *systemService) UpdateUSBAutoMount(state string) { + config.ServerInfo.USBAutoMount = state + config.Cfg.Section("server").Key("USBAutoMount").SetValue(state) + config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath) +} + func (c *systemService) MkdirAll(path string) (int, error) { _, err := os.Stat(path) if err == nil { @@ -66,7 +71,7 @@ func (c *systemService) MkdirAll(path string) (int, error) { return common_err.FILE_OR_DIR_EXISTS, err } } - return common_err.ERROR, err + return common_err.SERVICE_ERROR, err } func (c *systemService) RenameFile(oldF, newF string) (int, error) { @@ -77,12 +82,12 @@ func (c *systemService) RenameFile(oldF, newF string) (int, error) { if os.IsNotExist(err) { err := os.Rename(oldF, newF) if err != nil { - return common_err.ERROR, err + return common_err.SERVICE_ERROR, err } return common_err.SUCCESS, nil } } - return common_err.ERROR, err + return common_err.SERVICE_ERROR, err } func (c *systemService) CreateFile(path string) (int, error) { _, err := os.Stat(path) @@ -94,7 +99,7 @@ func (c *systemService) CreateFile(path string) (int, error) { return common_err.SUCCESS, nil } } - return common_err.ERROR, err + return common_err.SERVICE_ERROR, err } func (c *systemService) GetDeviceTree() string { return command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;GetDeviceTree") @@ -232,28 +237,13 @@ func (s *systemService) ExecUSBAutoMountShell(state string) { func (s *systemService) GetSystemConfigDebug() []string { return command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/helper.sh ;GetSysInfo") } -func (s *systemService) UpSystemConfig(str string, widget string) { - if len(str) > 0 && str != config.SystemConfigInfo.ConfigStr { - config.Cfg.Section("system").Key("ConfigStr").SetValue(str) - config.SystemConfigInfo.ConfigStr = str - } - if len(widget) > 0 && widget != config.SystemConfigInfo.WidgetList { - config.Cfg.Section("system").Key("WidgetList").SetValue(widget) - config.SystemConfigInfo.WidgetList = widget - } - config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath) -} + func (s *systemService) UpAppOrderFile(str, id string) { file.WriteToPath([]byte(str), config.AppInfo.DBPath+"/"+id, "app_order.json") } func (s *systemService) GetAppOrderFile(id string) []byte { return file.ReadFullFile(config.AppInfo.UserDataPath + "/" + id + "/app_order.json") } -func (s *systemService) UpdateUSBAutoMount(state string) { - config.ServerInfo.USBAutoMount = state - config.Cfg.Section("server").Key("USBAutoMount").SetValue(state) - config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath) -} func (s *systemService) UpSystemPort(port string) { if len(port) > 0 && port != config.ServerInfo.HttpPort { config.Cfg.Section("server").Key("HttpPort").SetValue(port) diff --git a/service/udpconn.go b/service/udpconn.go deleted file mode 100644 index 20adb01..0000000 --- a/service/udpconn.go +++ /dev/null @@ -1,503 +0,0 @@ -package service - -import ( - "context" - "crypto/md5" - "encoding/hex" - "encoding/json" - "fmt" - "io" - "io/ioutil" - "net" - "os" - path2 "path" - "reflect" - "strconv" - "strings" - "time" - - "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/model/notify" - "github.com/IceWhaleTech/CasaOS/pkg/config" - "github.com/IceWhaleTech/CasaOS/pkg/quic_helper" - "github.com/IceWhaleTech/CasaOS/pkg/utils/file" - "github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper" - model2 "github.com/IceWhaleTech/CasaOS/service/model" - "github.com/IceWhaleTech/CasaOS/types" - "github.com/lucas-clemente/quic-go" - uuid "github.com/satori/go.uuid" -) - -var UDPConn *net.UDPConn -var PeopleMap map[string]quic.Stream -var Message chan model.MessageModel -var UDPAddressMap map[string]string - -func UDPSendData(msg model.MessageModel, localFilePath string) error { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - Message = make(chan model.MessageModel) - _, port, err := net.SplitHostPort(UDPConn.LocalAddr().String()) - if config.ServerInfo.UDPPort != port { - config.ServerInfo.UDPPort = port - config.Cfg.Section("server").Key("UDPPort").SetValue(port) - config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath) - } - p, err := strconv.Atoi(port) - srcAddr := &net.UDPAddr{ - IP: net.IPv4zero, Port: p} //注意端口必须固定 - addr := UDPAddressMap[msg.To] - ticket := msg.To - dstAddr, err := net.ResolveUDPAddr("udp", addr) - - session, err := quic.DialContext(ctx, UDPConn, dstAddr, srcAddr.String(), quic_helper.GetClientTlsConfig(ticket), quic_helper.GetQUICConfig()) - if err != nil { - if msg.Type == types.PERSONDOWNLOAD { - task := MyService.Download().GetDownloadById(msg.UUId) - task.Error = err.Error() - task.State = types.DOWNLOADERROR - MyService.Download().SetDownloadError(task) - } - if config.SystemConfigInfo.Analyse != "False" { - go MyService.Casa().PushConnectionStatus(msg.UUId, err.Error(), msg.From, msg.To, msg.Type) - } - - return err - } - - stream, err := session.OpenStreamSync(ctx) - if err != nil { - if msg.Type == types.PERSONDOWNLOAD { - task := MyService.Download().GetDownloadById(msg.UUId) - task.Error = err.Error() - task.State = types.DOWNLOADERROR - MyService.Download().SetDownloadError(task) - } - if config.SystemConfigInfo.Analyse != "False" { - go MyService.Casa().PushConnectionStatus(msg.UUId, err.Error(), msg.From, msg.To, msg.Type) - } - session.CloseWithError(1, err.Error()) - return err - } - - SayHello(stream, msg.To) - //TODO:发送 - SendData(stream, msg) - SendFileData(stream, localFilePath, msg.To, msg.UUId, types.PERSONUPLOADDATA) - - stream.Close() - if config.SystemConfigInfo.Analyse != "False" { - go MyService.Casa().PushConnectionStatus(msg.UUId, "OK", msg.From, msg.To, msg.Type) - } - return nil -} - -func Dial(msg model.MessageModel, server bool) (m model.MessageModel, err error) { - ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second) - defer cancel() - Message = make(chan model.MessageModel) - _, port, err := net.SplitHostPort(UDPConn.LocalAddr().String()) - if config.ServerInfo.UDPPort != port { - config.ServerInfo.UDPPort = port - config.Cfg.Section("server").Key("UDPPort").SetValue(port) - config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath) - } - p, err := strconv.Atoi(port) - srcAddr := &net.UDPAddr{ - IP: net.IPv4zero, Port: p} //注意端口必须固定 - addr := UDPAddressMap[msg.To] - ticket := msg.To - if server { - addr = config.ServerInfo.Handshake + ":9527" - ticket = "bench" - } - dstAddr, err := net.ResolveUDPAddr("udp", addr) - - //DialTCP在网络协议net上连接本地地址laddr和远端地址raddr。net必须是"udp"、"udp4"、"udp6";如果laddr不是nil,将使用它作为本地地址,否则自动选择一个本地地址。 - //(conn)UDPConn代表一个UDP网络连接,实现了Conn和PacketConn接口 - - session, err := quic.DialContext(ctx, UDPConn, dstAddr, srcAddr.String(), quic_helper.GetClientTlsConfig(ticket), quic_helper.GetQUICConfig()) - if err != nil { - if msg.Type == types.PERSONDOWNLOAD { - task := MyService.Download().GetDownloadById(msg.UUId) - task.Error = err.Error() - task.State = types.DOWNLOADERROR - MyService.Download().SetDownloadError(task) - } - if config.SystemConfigInfo.Analyse != "False" { - go MyService.Casa().PushConnectionStatus(msg.UUId, err.Error(), msg.From, msg.To, msg.Type) - } - - return m, err - } - - stream, err := session.OpenStreamSync(ctx) - if err != nil { - if msg.Type == types.PERSONDOWNLOAD { - task := MyService.Download().GetDownloadById(msg.UUId) - task.Error = err.Error() - task.State = types.DOWNLOADERROR - MyService.Download().SetDownloadError(task) - } - if config.SystemConfigInfo.Analyse != "False" { - go MyService.Casa().PushConnectionStatus(msg.UUId, err.Error(), msg.From, msg.To, msg.Type) - } - session.CloseWithError(1, err.Error()) - return m, err - } - - SayHello(stream, msg.To) - - SendData(stream, msg) - - go ReadContent(stream) - result := <-Message - stream.Close() - if config.SystemConfigInfo.Analyse != "False" { - go MyService.Casa().PushConnectionStatus(msg.UUId, "OK", msg.From, msg.To, msg.Type) - } - return result, nil -} - -func SayHello(stream quic.Stream, to string) { - msg := model.MessageModel{} - msg.Type = types.PERSONHELLO - msg.Data = "hello" - msg.To = to - msg.From = config.ServerInfo.Token - msg.UUId = uuid.NewV4().String() - SendData(stream, msg) -} - -//发送数据 -func SendData(stream quic.Stream, m model.MessageModel) { - b, _ := json.Marshal(m) - prefixLength := file.PrefixLength(len(b)) - data := append(prefixLength, b...) - stream.Write(data) -} - -//读取数据 -func ReadContent(stream quic.Stream) { - for { - prefixByte := make([]byte, 6) - _, err := io.ReadFull(stream, prefixByte) - if err != nil { - fmt.Println(err) - time.Sleep(time.Second * 1) - for k, v := range CancelList { - tempPath := config.AppInfo.TempPath + "/" + v - fmt.Println(file.RMDir(tempPath)) - delete(CancelList, k) - } - break - } - prefixLength, err := strconv.Atoi(string(prefixByte)) - if err != nil { - fmt.Println(err) - break - } - messageByte := make([]byte, prefixLength) - _, err = io.ReadFull(stream, messageByte) - if err != nil { - fmt.Println(err) - break - } - m := model.MessageModel{} - err = json.Unmarshal(messageByte, &m) - if err != nil { - fmt.Println(err) - break - } - if m.Type == types.PERSONDOWNLOAD { - r := SaveFile(m, stream) - if r { - break - } - } else if m.Type == types.PERSONSUMMARY { - Summary(m, "download") - } else if m.Type == types.PERSONCONNECTION { - if len(m.Data.(string)) > 0 { - UDPAddressMap[m.From] = m.Data.(string) - } else { - delete(UDPAddressMap, m.From) - } - // mi := model2.FriendModel{} - // mi.Avatar = config.UserInfo.Avatar - // mi.Profile = config.UserInfo.Description - // mi.NickName = config.UserInfo.NickName - // mi.Token = config.ServerInfo.Token - msg := model.MessageModel{} - msg.Type = types.PERSONHELLO - msg.Data = "" - msg.To = m.From - msg.From = config.ServerInfo.Token - msg.UUId = m.UUId - go Dial(msg, false) - Message <- m - break - } else if m.Type == types.PERSONGETIP { - notify := notify.Person{} - notify.ShareId = m.From - if len(m.Data.(string)) == 0 { - if _, ok := UDPAddressMap[m.From]; ok { - notify.Type = "OFFLINE" - go MyService.Notify().SendPersonStatusBySocket(notify) - } - delete(UDPAddressMap, m.From) - Message <- m - break - } - if _, ok := UDPAddressMap[m.From]; !ok { - notify.Type = "ONLINE" - go MyService.Notify().SendPersonStatusBySocket(notify) - } - UDPAddressMap[m.From] = m.Data.(string) - if config.ServerInfo.Token != m.From && strings.Split(m.Data.(string), ":")[0] == strings.Split(UDPAddressMap[config.ServerInfo.Token], ":")[0] { - msg := model.MessageModel{} - msg.Type = types.PERSONINTERNALINSPECTION - msg.Data = ip_helper.GetDeviceAllIP(config.ServerInfo.UDPPort) - msg.To = m.From - msg.From = config.ServerInfo.Token - msg.UUId = m.UUId - go Dial(msg, true) - } - - Message <- m - break - } else if m.Type == types.PERSONINTERNALINSPECTION { - fmt.Println("接收到反验证") - var ips []string - dataModelByte, _ := json.Marshal(m.Data) - err := json.Unmarshal(dataModelByte, &ips) - if err != nil { - fmt.Println(err) - break - } - go MyService.Friend().InternalInspection(ips, m.From) - Message <- m - break - } else { - - Message <- m - } - } - Message <- model.MessageModel{} -} - -func SendIPToServer() { - msg := model.MessageModel{} - msg.Type = types.PERSONHELLO - msg.Data = "" - msg.From = config.ServerInfo.Token - msg.To = config.ServerInfo.Token - msg.UUId = uuid.NewV4().String() - - Dial(msg, true) -} - -func LoopFriend() { - list := MyService.Friend().GetFriendList() - msg := model.MessageModel{} - msg.Type = types.PERSONGETIP - msg.Data = "" - msg.From = config.ServerInfo.Token - msg.To = config.ServerInfo.Token - msg.UUId = uuid.NewV4().String() - Dial(msg, true) - - for i := 0; i < len(list); i++ { - if _, ok := UDPAddressMap[list[i].Token]; !ok { - msg := model.MessageModel{} - msg.Type = types.PERSONGETIP - msg.Data = "" - msg.From = config.ServerInfo.Token - msg.To = list[i].Token - msg.UUId = uuid.NewV4().String() - Dial(msg, true) - } - - msg.Type = types.PERSONPING - msg.Data = "" - msg.From = config.ServerInfo.Token - msg.To = list[i].Token - msg.UUId = uuid.NewV4().String() - - if v, ok := UDPAddressMap[list[i].Token]; ok { - if ip_helper.HasLocalIP(net.ParseIP(strings.Split(v, ":")[0])) { - msg.Data = ip_helper.GetDeviceAllIP(config.ServerInfo.UDPPort) - } - oldIP := UDPAddressMap[list[i].Token] - data, err := Dial(msg, false) - if err != nil || reflect.DeepEqual(data, model.MessageModel{}) || len(data.Data.(string)) == 0 { - if oldIP == UDPAddressMap[list[i].Token] { - notify := notify.Person{} - notify.ShareId = data.From - notify.Type = "LEAVE" - go MyService.Notify().SendPersonStatusBySocket(notify) - - delete(UDPAddressMap, list[i].Token) - - msg := model.MessageModel{} - msg.Type = types.PERSONGETIP - msg.Data = "" - msg.From = config.ServerInfo.Token - msg.To = list[i].Token - msg.UUId = uuid.NewV4().String() - Dial(msg, true) - } - } - } - go func(shareId string) { - user := MyService.Casa().GetUserInfoByShareId(shareId) - m := model2.FriendModel{} - m.Token = shareId - friend := MyService.Friend().GetFriendById(m) - if friend.Version != user.Version { - friend.Avatar = user.Avatar - friend.NickName = user.NickName - friend.Profile = user.Desc - friend.Version = user.Version - MyService.Friend().UpdateOrCreate(friend) - } - }(list[i].Token) - - } -} - -//file summary -func Summary(m model.MessageModel, t string) { - dataModel := model.FileSummaryModel{} - dataModelByte, _ := json.Marshal(m.Data) - err := json.Unmarshal(dataModelByte, &dataModel) - if err != nil { - fmt.Println(err) - } - - task := MyService.Download().GetDownloadById(m.UUId) - - task.State = types.DOWNLOADING - fullPath := path2.Join(task.LocalPath, task.Name) - - if len(dataModel.Message) > 0 { - task.State = types.DOWNLOADERROR - task.Error = dataModel.Message - } - //The file already exists and the file is the same, no need to download - if t != "upload" && file.Exists(fullPath) && file.GetHashByPath(fullPath) == dataModel.Hash { - task.State = types.DOWNLOADFINISHED - go func(from, uuid string) { - m := model.MessageModel{} - m.Data = "" - m.From = config.ServerInfo.Token - m.To = from - m.Type = types.PERSONCANCEL - m.UUId = uuid - CancelList[uuid] = uuid - Dial(m, false) - }(task.From, task.UUID) - - } - task.UUID = m.UUId - task.Name = dataModel.Name - task.Length = dataModel.Length - task.Size = dataModel.Size - task.BlockSize = dataModel.BlockSize - task.Hash = dataModel.Hash - task.Type = types.PERSONFILEDOWNLOAD - task.From = m.From - if t == "upload" { - task.Type = types.PERSONFILERECEIVEUPLOAD - } - MyService.Download().SaveDownload(task) -} - -//Save file fragment -func SaveFile(m model.MessageModel, stream quic.Stream) bool { - dataModelByte, _ := json.Marshal(m.Data) - dataModel := model.TranFileModel{} - err := json.Unmarshal(dataModelByte, &dataModel) - if err != nil { - fmt.Println(err) - return false - } - - dataLengthByte := make([]byte, 8) - _, err = io.ReadFull(stream, dataLengthByte) - if err != nil { - fmt.Println(err) - return false - } - dataLength, err := strconv.Atoi(string(dataLengthByte)) - if err != nil { - fmt.Println(err) - return false - } - dataByte := make([]byte, dataLength) - _, err = io.ReadFull(stream, dataByte) - if err != nil { - fmt.Println(err) - return false - } - sum := md5.Sum(dataByte) - hash := hex.EncodeToString(sum[:]) - if dataModel.Hash != hash { - fmt.Println("hash不匹配", hash, dataModel.Hash) - return false - } - tempPath := config.AppInfo.TempPath + "/" + m.UUId - file.IsNotExistMkDir(tempPath) - filepath := tempPath + "/" + strconv.Itoa(dataModel.Index) - _, err = os.Stat(filepath) - - if os.IsNotExist(err) { - err = ioutil.WriteFile(filepath, dataByte, 0644) - task := model2.PersonDownloadDBModel{} - task.UUID = m.UUId - if err != nil { - task.Error = err.Error() - task.State = types.DOWNLOADERROR - MyService.Download().SetDownloadError(task) - } - - } else { - if file.GetHashByPath(filepath) != dataModel.Hash { - os.Remove(filepath) - err = ioutil.WriteFile(filepath, dataByte, 0644) - task := model2.PersonDownloadDBModel{} - task.UUID = m.UUId - if err != nil { - task.Error = err.Error() - task.State = types.DOWNLOADERROR - MyService.Download().SetDownloadError(task) - } - } - } - - files, err := ioutil.ReadDir(tempPath) - if err != nil { - fmt.Println(err) - return false - } - if len(files) >= dataModel.Length { - summary := MyService.Download().GetDownloadById(m.UUId) - summary.State = types.DOWNLOADFINISH - MyService.Download().EditDownloadState(summary) - fullPath := file.GetNoDuplicateFileName(path2.Join(summary.LocalPath, summary.Name)) - file.SpliceFiles(tempPath, fullPath, dataModel.Length, 0) - if file.GetHashByPath(fullPath) == summary.Hash { - file.RMDir(tempPath) - summary.State = types.DOWNLOADFINISHED - MyService.Download().EditDownloadState(summary) - } else { - os.Remove(config.FileSettingInfo.DownloadDir + "/" + summary.Name) - - summary.State = types.DOWNLOADERROR - summary.Error = "hash mismatch" - MyService.Download().SetDownloadError(summary) - } - - return true - } - return false -} diff --git a/service/user.go b/service/user.go index e9f5930..d53667f 100644 --- a/service/user.go +++ b/service/user.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2022-03-18 11:40:55 * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-23 19:45:49 + * @LastEditTime: 2022-07-12 10:05:37 * @FilePath: /CasaOS/service/user.go * @Description: * @Website: https://www.casaos.io @@ -15,13 +15,11 @@ import ( "mime/multipart" "os" - "github.com/IceWhaleTech/CasaOS/pkg/config" "github.com/IceWhaleTech/CasaOS/service/model" "gorm.io/gorm" ) type UserService interface { - SetUser(username, pwd, token, email, desc, nickName string) error UpLoadFile(file multipart.File, name string) error CreateUser(m model.UserDBModel) model.UserDBModel GetUserCount() (userCount int64) @@ -31,6 +29,7 @@ type UserService interface { GetUserAllInfoById(id string) (m model.UserDBModel) GetUserAllInfoByName(userName string) (m model.UserDBModel) DeleteUserById(id string) + DeleteAllUser() GetUserInfoByUserName(userName string) (m model.UserDBModel) GetAllUserName() (list []model.UserDBModel) } @@ -41,12 +40,15 @@ type userService struct { 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{}) } func (u *userService) GetAllUserName() (list []model.UserDBModel) { - u.db.Select("user_name").Find(&list) + u.db.Select("username").Find(&list) return } func (u *userService) CreateUser(m model.UserDBModel) model.UserDBModel { @@ -70,47 +72,19 @@ func (u *userService) GetUserAllInfoById(id string) (m model.UserDBModel) { return } func (u *userService) GetUserAllInfoByName(userName string) (m model.UserDBModel) { - u.db.Where("user_name= ?", userName).First(&m) + u.db.Where("username= ?", userName).First(&m) return } func (u *userService) GetUserInfoById(id string) (m model.UserDBModel) { - u.db.Select("user_name", "id", "role", "nick_name", "description", "avatar").Where("id= ?", id).First(&m) + u.db.Select("username", "id", "role", "nickname", "description", "avatar", "email").Where("id= ?", id).First(&m) return } func (u *userService) GetUserInfoByUserName(userName string) (m model.UserDBModel) { - u.db.Select("user_name", "id", "role", "nick_name", "description", "avatar").Where("user_name= ?", userName).First(&m) + u.db.Select("username", "id", "role", "nickname", "description", "avatar", "email").Where("username= ?", userName).First(&m) return } -//设置用户名密码 -func (u *userService) SetUser(username, pwd, token, email, desc, nickName string) error { - if len(username) > 0 { - config.Cfg.Section("user").Key("UserName").SetValue(username) - config.UserInfo.UserName = username - config.Cfg.Section("user").Key("Initialized").SetValue("true") - config.UserInfo.Initialized = true - } - if len(pwd) > 0 { - config.Cfg.Section("user").Key("PWD").SetValue(pwd) - config.UserInfo.PWD = pwd - } - if len(email) > 0 { - config.Cfg.Section("user").Key("Email").SetValue(email) - config.UserInfo.Email = email - } - if len(desc) > 0 { - config.Cfg.Section("user").Key("Description").SetValue(desc) - config.UserInfo.Description = desc - } - if len(nickName) > 0 { - config.Cfg.Section("user").Key("NickName").SetValue(nickName) - config.UserInfo.NickName = nickName - } - config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath) - return nil -} - //上传文件 func (c *userService) UpLoadFile(file multipart.File, url string) error { out, _ := os.OpenFile(url, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644) diff --git a/types/system.go b/types/system.go index 32a4463..9a3d4e8 100644 --- a/types/system.go +++ b/types/system.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2022-02-17 18:53:22 * @LastEditors: LinkLeong - * @LastEditTime: 2022-07-01 15:15:09 + * @LastEditTime: 2022-07-18 18:47:15 * @FilePath: /CasaOS/types/system.go * @Description: * @Website: https://www.casaos.io @@ -10,6 +10,6 @@ */ package types -const CURRENTVERSION = "0.3.3" +const CURRENTVERSION = "0.3.4" const BODY = "" diff --git a/web/browserconfig.xml b/web/browserconfig.xml index a221792..a02d62e 100644 --- a/web/browserconfig.xml +++ b/web/browserconfig.xml @@ -1,9 +1,9 @@ - - - - - - #da532c - - - + + + + + + #da532c + + + diff --git a/web/favicon.svg b/web/favicon.svg index 9760ab7..8d176f0 100644 --- a/web/favicon.svg +++ b/web/favicon.svg @@ -1,14 +1,14 @@ - - - - - - - - + + + + + + + + diff --git a/web/img/1-small.1b74d2ba.png b/web/img/1-small.1b74d2ba.png deleted file mode 100644 index 406d0ba..0000000 Binary files a/web/img/1-small.1b74d2ba.png and /dev/null differ diff --git a/web/img/Android-DeviceID.b57fefc8.png b/web/img/Android-DeviceID.b57fefc8.png deleted file mode 100644 index 323d311..0000000 Binary files a/web/img/Android-DeviceID.b57fefc8.png and /dev/null differ diff --git a/web/img/Android-Menu.ed4df0da.png b/web/img/Android-Menu.ed4df0da.png deleted file mode 100644 index d41bef4..0000000 Binary files a/web/img/Android-Menu.ed4df0da.png and /dev/null differ diff --git a/web/img/Android-NewDevice.f00af2cb.png b/web/img/Android-NewDevice.f00af2cb.png deleted file mode 100644 index 5e36a2b..0000000 Binary files a/web/img/Android-NewDevice.f00af2cb.png and /dev/null differ diff --git a/web/img/Android-NewDeviceAdd.784d2f18.png b/web/img/Android-NewDeviceAdd.784d2f18.png deleted file mode 100644 index bd7ebfd..0000000 Binary files a/web/img/Android-NewDeviceAdd.784d2f18.png and /dev/null differ diff --git a/web/img/Android-NewFolder.d71dc444.png b/web/img/Android-NewFolder.d71dc444.png deleted file mode 100644 index c7a362f..0000000 Binary files a/web/img/Android-NewFolder.d71dc444.png and /dev/null differ diff --git a/web/img/Android-NewFolderCreate.b3521b45.png b/web/img/Android-NewFolderCreate.b3521b45.png deleted file mode 100644 index 35d04a8..0000000 Binary files a/web/img/Android-NewFolderCreate.b3521b45.png and /dev/null differ diff --git a/web/img/Android-ShowDeviceID.f7e46fb8.png b/web/img/Android-ShowDeviceID.f7e46fb8.png deleted file mode 100644 index de34139..0000000 Binary files a/web/img/Android-ShowDeviceID.f7e46fb8.png and /dev/null differ diff --git a/web/img/Windows-DeviceID.2e929f75.png b/web/img/Windows-DeviceID.2e929f75.png deleted file mode 100644 index 6222a12..0000000 Binary files a/web/img/Windows-DeviceID.2e929f75.png and /dev/null differ diff --git a/web/img/Windows-NewDevice.c9f2471d.png b/web/img/Windows-NewDevice.c9f2471d.png deleted file mode 100644 index 55367a9..0000000 Binary files a/web/img/Windows-NewDevice.c9f2471d.png and /dev/null differ diff --git a/web/img/Windows-NewDeviceSave.fe1078b1.png b/web/img/Windows-NewDeviceSave.fe1078b1.png deleted file mode 100644 index d75260e..0000000 Binary files a/web/img/Windows-NewDeviceSave.fe1078b1.png and /dev/null differ diff --git a/web/img/Windows-NewFolder.5305cc41.png b/web/img/Windows-NewFolder.5305cc41.png deleted file mode 100644 index 34503b0..0000000 Binary files a/web/img/Windows-NewFolder.5305cc41.png and /dev/null differ diff --git a/web/img/Windows-NewFolderSave.9ce2312f.png b/web/img/Windows-NewFolderSave.9ce2312f.png deleted file mode 100644 index 8ee1a2c..0000000 Binary files a/web/img/Windows-NewFolderSave.9ce2312f.png and /dev/null differ diff --git a/web/img/Windows-ShowID.1000f319.png b/web/img/Windows-ShowID.1000f319.png deleted file mode 100644 index d67fccc..0000000 Binary files a/web/img/Windows-ShowID.1000f319.png and /dev/null differ diff --git a/web/img/icon/safari-pinned-tab.svg b/web/img/icon/safari-pinned-tab.svg index af12e15..e750780 100644 --- a/web/img/icon/safari-pinned-tab.svg +++ b/web/img/icon/safari-pinned-tab.svg @@ -1,25 +1,25 @@ - - - - -Created by potrace 1.14, written by Peter Selinger 2001-2017 - - - - - + + + + +Created by potrace 1.14, written by Peter Selinger 2001-2017 + + + + + diff --git a/web/img/macOS-Config.f419628a.png b/web/img/macOS-Config.f419628a.png deleted file mode 100644 index 35f4991..0000000 Binary files a/web/img/macOS-Config.f419628a.png and /dev/null differ diff --git a/web/img/macOS-DeviceID.968cc84d.png b/web/img/macOS-DeviceID.968cc84d.png deleted file mode 100644 index 1b75247..0000000 Binary files a/web/img/macOS-DeviceID.968cc84d.png and /dev/null differ diff --git a/web/img/macOS-NewFolder.fa9e37d0.png b/web/img/macOS-NewFolder.fa9e37d0.png deleted file mode 100644 index 368236a..0000000 Binary files a/web/img/macOS-NewFolder.fa9e37d0.png and /dev/null differ diff --git a/web/img/macOS-NewFolderSave.6f3f247d.png b/web/img/macOS-NewFolderSave.6f3f247d.png deleted file mode 100644 index 1430d86..0000000 Binary files a/web/img/macOS-NewFolderSave.6f3f247d.png and /dev/null differ diff --git a/web/img/macOS-ShowID.c822acc3.png b/web/img/macOS-ShowID.c822acc3.png deleted file mode 100644 index 610aa10..0000000 Binary files a/web/img/macOS-ShowID.c822acc3.png and /dev/null differ diff --git a/web/img/macOS-icon.ae9e0906.png b/web/img/macOS-icon.ae9e0906.png deleted file mode 100644 index 499d6ea..0000000 Binary files a/web/img/macOS-icon.ae9e0906.png and /dev/null differ diff --git a/web/img/syncthing.257e4f51.svg b/web/img/syncthing.257e4f51.svg deleted file mode 100644 index e18d9ed..0000000 --- a/web/img/syncthing.257e4f51.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/web/img/windows.d98029c3.svg b/web/img/windows.d98029c3.svg deleted file mode 100644 index 6fac0df..0000000 --- a/web/img/windows.d98029c3.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/web/index.html b/web/index.html index 2ebe764..905d50c 100644 --- a/web/index.html +++ b/web/index.html @@ -20,7 +20,7 @@ CasaOS - +