diff --git a/.gitignore b/.gitignore index d9592b471..f2ceede70 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ # Dependency directories (remove the comment below to include it) # vendor/ .idea/ +*.db diff --git a/api/go.mod b/api/go.mod new file mode 100644 index 000000000..6ceb5579f --- /dev/null +++ b/api/go.mod @@ -0,0 +1,12 @@ +module mizuserver + +go 1.16 + +require ( + github.com/djherbis/atime v1.0.0 + github.com/gofiber/fiber/v2 v2.8.0 + github.com/google/martian v2.1.0+incompatible + go.mongodb.org/mongo-driver v1.5.1 + gorm.io/driver/sqlite v1.1.4 + gorm.io/gorm v1.21.8 +) diff --git a/api/go.sum b/api/go.sum new file mode 100644 index 000000000..b4a4894b1 --- /dev/null +++ b/api/go.sum @@ -0,0 +1,146 @@ +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc= +github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/djherbis/atime v1.0.0 h1:ySLvBAM0EvOGaX7TI4dAM5lWj+RdJUCKtGSEHN8SGBg= +github.com/djherbis/atime v1.0.0/go.mod h1:5W+KBIuTwVGcqjIfaTwt+KSYX1o6uep8dtevevQP/f8= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= +github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= +github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= +github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= +github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= +github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= +github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= +github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= +github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= +github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= +github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= +github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= +github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= +github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= +github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= +github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/gofiber/fiber/v2 v2.8.0 h1:BdWvZmg/WY/Vjtjm38aXOp1Lks1BhuyS2b7lSWSPAzk= +github.com/gofiber/fiber/v2 v2.8.0/go.mod h1:Ah3IJikrKNRepl/HuVawppS25X7FWohwfCSRn7kJG28= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI= +github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= +github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= +github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.11.8/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.13 h1:eSvu8Tmq6j2psUJqJrLcWH6K3w5Dwc+qipbaA6eVEN4= +github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +github.com/mattn/go-sqlite3 v1.14.5 h1:1IdxlwTNazvbKJQSxoJ5/9ECbEeaTTyeU7sEAZ5KKTQ= +github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +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/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.23.0 h1:0ufwSD9BhWa6f8HWdmdq4FHQ23peRo3Ng/Qs8m5NcFs= +github.com/valyala/fasthttp v1.23.0/go.mod h1:0mw2RjXGOzxf4NL2jni3gUQ7LfjjUSiG5sskOUUSEpU= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a h1:0R4NLDRDZX6JcmhJgXi5E4b8Wg84ihbmUKp/GvSPEzc= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= +github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +go.mongodb.org/mongo-driver v1.5.1 h1:9nOVLGDfOaZ9R0tBumx/BcuqkbFpyTCU2r/Po7A2azI= +go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226101413-39120d07d75e/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/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-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/sqlite v1.1.4 h1:PDzwYE+sI6De2+mxAneV9Xs11+ZyKV6oxD3wDGkaNvM= +gorm.io/driver/sqlite v1.1.4/go.mod h1:mJCeTFr7+crvS+TRnWc5Z3UvwxUN1BGBLMrf5LA9DYw= +gorm.io/gorm v1.20.7/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= +gorm.io/gorm v1.21.8 h1:2CEwZSzogdhsKPlJ9OvBKTdlWIpELXb6HbfLfMNhSYI= +gorm.io/gorm v1.21.8/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= diff --git a/api/sqlite_orm_testing/gorm.db b/api/sqlite_orm_testing/gorm.db new file mode 100644 index 000000000..93745bb85 Binary files /dev/null and b/api/sqlite_orm_testing/gorm.db differ diff --git a/api/sqlite_orm_testing/roee.go b/api/sqlite_orm_testing/roee.go new file mode 100644 index 000000000..107c15f0e --- /dev/null +++ b/api/sqlite_orm_testing/roee.go @@ -0,0 +1,55 @@ +package main + +import ( + "gorm.io/driver/sqlite" + _ "gorm.io/driver/sqlite" + "gorm.io/gorm" + "time" +) + +type User struct { + gorm.Model // this will add "id", "created updated inserted times" + + Name string + Age int + Birthday time.Time +} + +func main () { + // github.com/mattn/go-sqlite3 + db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{}) + if err != nil{ + panic("ff") + } + + // Run migrations + migErr := db.AutoMigrate(&User{}) + if migErr != nil { + panic("Cannot run migration") + } + + user := User{Name: "Jinzhu", Age: 18, Birthday: time.Now()} + db.Create(&user) // pass pointer of data to Create + +} + + + +//func main() { +// app := fiber.New() +// +// c := make(chan os.Signal, 1) +// signal.Notify(c, os.Interrupt) +// go func() { +// _ = <-c +// fmt.Println("Gracefully shutting down...") +// _ = app.Shutdown() +// }() +// +// if err := app.Listen(":3000"); err != nil { +// log.Panic(err) +// } +// +// fmt.Println("Running cleanup tasks...") +// // Your cleanup tasks go here +//} diff --git a/api/src/.dockerignore b/api/src/.dockerignore new file mode 100644 index 000000000..5f5b607e8 --- /dev/null +++ b/api/src/.dockerignore @@ -0,0 +1,16 @@ +# Files +.dockerignore +.editorconfig +.gitignore +.env.* +Dockerfile +Makefile +LICENSE +**/*.md +**/*_test.go +*.out + +# Folders +.git/ +.github/ +build/ diff --git a/api/src/Dockerfile b/api/src/Dockerfile new file mode 100644 index 000000000..443e010b6 --- /dev/null +++ b/api/src/Dockerfile @@ -0,0 +1,26 @@ +FROM golang:1.16-alpine AS builder + +# Move to working directory (/build). +WORKDIR /build + +# Copy and download dependency using go mod. +COPY go.mod go.sum ./ +RUN go mod download + +# Copy the code into the container. +COPY . . + +# Set necessary environmet variables needed for our image and build the API server. +ENV CGO_ENABLED=0 GOOS=linux GOARCH=amd64 +RUN go build -ldflags="-s -w" -o apiserver . + +FROM scratch + +# Copy binary and config files from /build to root folder of scratch container. +COPY --from=builder ["/build/apiserver", "/"] + +# Export necessary port. +EXPOSE 5000 + +# Command to run when starting the container. +ENTRYPOINT ["/apiserver"] diff --git a/api/src/main.go b/api/src/main.go new file mode 100644 index 000000000..076641162 --- /dev/null +++ b/api/src/main.go @@ -0,0 +1,30 @@ +package main + +import ( + "github.com/gofiber/fiber/v2" + "mizuserver/src/pkg/inserter" + "mizuserver/src/pkg/middleware" + "mizuserver/src/pkg/routes" + "mizuserver/src/pkg/utils" +) + +func main() { + // TODO: to generate data + //path := "/Users/roeegadot/Downloads/output2" + //api.TestHarSavingFromFolder(path) + go inserter.StartReadingFiles("/var/up9hars") + app := fiber.New() + + middleware.FiberMiddleware(app) // Register Fiber's middleware for app. + + // Simple route to know server is running + app.Get("/", func(c *fiber.Ctx) error { + return c.SendString("Hello, World 👋!") + }) + + routes.PublicRoutes(app) + routes.NotFoundRoute(app) + + utils.StartServer(app) +} + diff --git a/api/src/pkg/configs/fiber_config.go b/api/src/pkg/configs/fiber_config.go new file mode 100644 index 000000000..5fccb8ecf --- /dev/null +++ b/api/src/pkg/configs/fiber_config.go @@ -0,0 +1,21 @@ +package configs + +import ( + "os" + "strconv" + "time" + + "github.com/gofiber/fiber/v2" +) + +// FiberConfig func for configuration Fiber app. +// See: https://docs.gofiber.io/api/fiber#config +func FiberConfig() fiber.Config { + // Define server settings. + readTimeoutSecondsCount, _ := strconv.Atoi(os.Getenv("SERVER_READ_TIMEOUT")) + + // Return Fiber configuration. + return fiber.Config{ + ReadTimeout: time.Second * time.Duration(readTimeoutSecondsCount), + } +} diff --git a/api/src/pkg/controllers/entries_controller.go b/api/src/pkg/controllers/entries_controller.go new file mode 100644 index 000000000..727717fd3 --- /dev/null +++ b/api/src/pkg/controllers/entries_controller.go @@ -0,0 +1,63 @@ +package controllers + +import ( + "encoding/json" + "github.com/gofiber/fiber/v2" + "github.com/google/martian/har" + "mizuserver/src/pkg/database" + "mizuserver/src/pkg/models" + "mizuserver/src/pkg/utils" + "strconv" +) + +func GetEntries(c *fiber.Ctx) error { + limit, e := strconv.Atoi(c.Query("limit", "100")) + utils.CheckErr(e) + + var entries []models.MizuEntry + database.GetEntriesTable(). + Omit("entry"). // remove the "big" entry field + Limit(limit). + Find(&entries) + + // Convert to base entries + baseEntries := make([]models.BaseEntryDetails, 0) + for _, entry := range entries { + baseEntries = append(baseEntries, models.BaseEntryDetails{ + Id: entry.EntryId, + Url: entry.Url, + Service: entry.Service, + Path: entry.Path, + StatusCode: entry.Status, + Method: entry.Method, + Timestamp: entry.Timestamp, + }) + } + + return c.Status(fiber.StatusOK).JSON(baseEntries) +} + +func GetEntry(c *fiber.Ctx) error { + var entryData models.EntryData + database.GetEntriesTable(). + Select("entry"). + Where(map[string]string{"entryId": c.Params("entryId")}). + First(&entryData) + + var fullEntry har.Entry + unmarshallErr := json.Unmarshal([]byte(entryData.Entry), &fullEntry) + utils.CheckErr(unmarshallErr) + + return c.Status(fiber.StatusOK).JSON(fullEntry) +} + + +func DeleteAllEntries(c *fiber.Ctx) error { + database.GetEntriesTable(). + Where("1 = 1"). + Delete(&models.MizuEntry{}) + + return c.Status(fiber.StatusOK).JSON(fiber.Map{ + "msg": "Success", + }) +} \ No newline at end of file diff --git a/api/src/pkg/database/main.go b/api/src/pkg/database/main.go new file mode 100644 index 000000000..39b8bec75 --- /dev/null +++ b/api/src/pkg/database/main.go @@ -0,0 +1,25 @@ +package database + +import ( + "gorm.io/driver/sqlite" + "gorm.io/gorm" + "mizuserver/src/pkg/models" +) + +const ( + DBPath = "./entries.db" +) + +var ( + DB = initDataBase(DBPath) +) + +func GetEntriesTable() *gorm.DB { + return DB.Table("mizu_entries") +} + +func initDataBase(databasePath string) *gorm.DB { + temp, _ := gorm.Open(sqlite.Open(databasePath), &gorm.Config{}) + _ = temp.AutoMigrate(&models.MizuEntry{}) // this will ensure table is created + return temp +} diff --git a/api/src/pkg/inserter/main.go b/api/src/pkg/inserter/main.go new file mode 100644 index 000000000..7251b072d --- /dev/null +++ b/api/src/pkg/inserter/main.go @@ -0,0 +1,91 @@ +package inserter + +import ( + "bufio" + "encoding/json" + "fmt" + "github.com/google/martian/har" + "go.mongodb.org/mongo-driver/bson/primitive" + "io" + "io/fs" + "mizuserver/src/pkg/database" + "mizuserver/src/pkg/models" + "mizuserver/src/pkg/utils" + "net/url" + "os" + "path" + "sort" + "time" +) + + +func IsEmpty(name string) (bool) { + f, err := os.Open(name) + if err != nil { + return false + } + defer f.Close() + + _, err = f.Readdirnames(1) // Or f.Readdir(1) + if err == io.EOF { + return true + } + return false // Either not empty or error, suits both cases +} + +func StartReadingFiles(workingDir string) { + err := os.MkdirAll(workingDir, fs.ModeDir) + utils.CheckErr(err) + + for true { + if IsEmpty(workingDir) { + fmt.Printf("Waiting for new files\n") + time.Sleep(5 * time.Second) + continue + } + + dir, _ := os.Open(workingDir) + dirFiles, _ := dir.Readdir(-1) + sort.Sort(utils.ByModTime(dirFiles)) + + fileInfo := dirFiles[0] + inputFilePath := path.Join(workingDir, fileInfo.Name()) + file, err := os.Open(inputFilePath) + utils.CheckErr(err) + + var inputHar har.HAR + decErr := json.NewDecoder(bufio.NewReader(file)).Decode(&inputHar) + utils.CheckErr(decErr) + + for _, entry := range inputHar.Log.Entries { + fmt.Printf("Entry inserted") + SaveHarToDb(*entry, "") + } + rmErr := os.Remove(inputFilePath) + utils.CheckErr(rmErr) + } + +} + +func SaveHarToDb(entry har.Entry, source string) { + entryBytes, _ := json.Marshal(entry) + serviceName, urlPath := getServiceNameFromUrl(entry.Request.URL) + mizuEntry := models.MizuEntry{ + EntryId: primitive.NewObjectID().Hex(), + Entry: string(entryBytes), // simple way to store it and not convert to bytes + Service: serviceName, + Url: entry.Request.URL, + Path: urlPath, + Method: entry.Request.Method, + Status: entry.Response.Status, + Source: source, + Timestamp: entry.StartedDateTime.Unix(), + } + database.GetEntriesTable().Create(&mizuEntry) +} + +func getServiceNameFromUrl(inputUrl string) (string, string) { + parsed, err := url.Parse(inputUrl) + utils.CheckErr(err) + return fmt.Sprintf("%s://%s", parsed.Scheme, parsed.Host), parsed.Path +} diff --git a/api/src/pkg/middleware/fiber_middleware.go b/api/src/pkg/middleware/fiber_middleware.go new file mode 100644 index 000000000..24bc453a7 --- /dev/null +++ b/api/src/pkg/middleware/fiber_middleware.go @@ -0,0 +1,18 @@ +package middleware + +import ( + "github.com/gofiber/fiber/v2" + "github.com/gofiber/fiber/v2/middleware/cors" + "github.com/gofiber/fiber/v2/middleware/logger" +) + +// FiberMiddleware provide Fiber's built-in middlewares. +// See: https://docs.gofiber.io/api/middleware +func FiberMiddleware(a *fiber.App) { + a.Use( + // Add CORS to each route. + cors.New(), + // Add simple logger. + logger.New(), + ) +} diff --git a/api/src/pkg/models/mizuEntry.go b/api/src/pkg/models/mizuEntry.go new file mode 100644 index 000000000..1c14e6adc --- /dev/null +++ b/api/src/pkg/models/mizuEntry.go @@ -0,0 +1,32 @@ +package models + +import "time" + +type MizuEntry struct { + ID uint `gorm:"primarykey"` + CreatedAt time.Time + UpdatedAt time.Time + Entry string `json:"entry,omitempty" gorm:"column:entry"` + EntryId string `json:"entryId" gorm:"column:entryId"` + Url string `json:"url" gorm:"column:url"` + Method string `json:"method" gorm:"column:method"` + Status int `json:"status" gorm:"column:status"` + Source string `json:"source" gorm:"column:source"` + Service string `json:"service" gorm:"column:service"` + Timestamp int64 `json:"timestamp" gorm:"column:timestamp"` + Path string `json:"path" gorm:"column:path"` +} + +type BaseEntryDetails struct { + Id string `json:"id,omitempty"` + Url string `json:"url,omitempty"` + Service string `json:"service,omitempty"` + Path string `json:"path,omitempty"` + StatusCode int `json:"statusCode,omitempty"` + Method string `json:"method,omitempty"` + Timestamp int64 `json:"timestamp,omitempty"` +} + +type EntryData struct { + Entry string `json:"entry,omitempty"` +} diff --git a/api/src/pkg/routes/not_found_route.go b/api/src/pkg/routes/not_found_route.go new file mode 100644 index 000000000..1aa1e7da7 --- /dev/null +++ b/api/src/pkg/routes/not_found_route.go @@ -0,0 +1,15 @@ +package routes + +import "github.com/gofiber/fiber/v2" + +// NotFoundRoute func for describe 404 Error route. +func NotFoundRoute(fiberApp *fiber.App) { + fiberApp.Use( + func(c *fiber.Ctx) error { + return c.Status(fiber.StatusNotFound).JSON(fiber.Map{ + "error": true, + "msg": "sorry, endpoint is not found", + }) + }, + ) +} diff --git a/api/src/pkg/routes/public_routes.go b/api/src/pkg/routes/public_routes.go new file mode 100644 index 000000000..73e07bcca --- /dev/null +++ b/api/src/pkg/routes/public_routes.go @@ -0,0 +1,17 @@ +package routes + +import ( + "github.com/gofiber/fiber/v2" + "mizuserver/src/pkg/controllers" +) + +// PublicRoutes func for describe group of public routes. +func PublicRoutes(fiberApp *fiber.App) { + routeGroup := fiberApp.Group("/api") + + routeGroup.Get("/entries", controllers.GetEntries) // get entries (base/thin entries) + routeGroup.Get("/entries/:entryId", controllers.GetEntry) // get single (full) entry + + routeGroup.Get("/resetDB", controllers.DeleteAllEntries) // get single (full) entry + +} diff --git a/api/src/pkg/utils/pathUtils.go b/api/src/pkg/utils/pathUtils.go new file mode 100644 index 000000000..d936ecf81 --- /dev/null +++ b/api/src/pkg/utils/pathUtils.go @@ -0,0 +1,50 @@ +package utils + +import ( + "github.com/djherbis/atime" + "os" +) + +type ByModTime []os.FileInfo + +func (fis ByModTime) Len() int { + return len(fis) +} + +func (fis ByModTime) Swap(i, j int) { + fis[i], fis[j] = fis[j], fis[i] +} + +func (fis ByModTime) Less(i, j int) bool { + return fis[i].ModTime().Before(fis[j].ModTime()) +} + + +type ByName []os.FileInfo + +func (fis ByName) Len() int { + return len(fis) +} + +func (fis ByName) Swap(i, j int) { + fis[i], fis[j] = fis[j], fis[i] +} + +func (fis ByName) Less(i, j int) bool { + return fis[i].Name() < fis[j].Name() +} + + +type ByCreationTime []os.FileInfo + +func (fis ByCreationTime) Len() int { + return len(fis) +} + +func (fis ByCreationTime) Swap(i, j int) { + fis[i], fis[j] = fis[j], fis[i] +} + +func (fis ByCreationTime) Less(i, j int) bool { + return atime.Get(fis[i]).Unix() < atime.Get(fis[j]).Unix() +} \ No newline at end of file diff --git a/api/src/pkg/utils/randomString.go b/api/src/pkg/utils/randomString.go new file mode 100644 index 000000000..9bed7da59 --- /dev/null +++ b/api/src/pkg/utils/randomString.go @@ -0,0 +1,22 @@ +package utils + +import ( + "math/rand" + "time" +) + +const charset = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + +var seededRand = rand.New(rand.NewSource(time.Now().UnixNano())) + +func StringWithCharset(length int, charset string) string { + b := make([]byte, length) + for i := range b { + b[i] = charset[seededRand.Intn(len(charset))] + } + return string(b) +} + +func GetRandomString(length int) string { + return StringWithCharset(length, charset) +} diff --git a/api/src/pkg/utils/utils.go b/api/src/pkg/utils/utils.go new file mode 100644 index 000000000..789756bcb --- /dev/null +++ b/api/src/pkg/utils/utils.go @@ -0,0 +1,38 @@ +package utils + +import ( + "fmt" + "github.com/gofiber/fiber/v2" + "log" + "os" + "os/signal" + "syscall" +) + +// StartServer starts the server with a graceful shutdown +func StartServer(app *fiber.App) { + signals := make(chan os.Signal, 2) + signal.Notify(signals, + os.Interrupt, // this catch ctrl + c + syscall.SIGTSTP, // this catch ctrl + z + ) + + go func() { + _ = <-signals + fmt.Println("Shutting down...") + _ = app.Shutdown() + }() + + // Run server. + if err := app.Listen(":8899"); err != nil { + log.Printf("Oops... Server is not running! Reason: %v", err) + } +} + + +func CheckErr(e error) { + if e != nil { + log.Printf("%v", e) + //panic(e) + } +} \ No newline at end of file diff --git a/api/testing_from_file.go b/api/testing_from_file.go new file mode 100644 index 000000000..1b06a86a8 --- /dev/null +++ b/api/testing_from_file.go @@ -0,0 +1,59 @@ +package api + +import ( + "bufio" + "encoding/json" + "fmt" + "github.com/google/martian/har" + "go.mongodb.org/mongo-driver/bson/primitive" + "mizuserver/src/pkg/database" + "mizuserver/src/pkg/models" + "mizuserver/src/pkg/utils" + "net/url" + "os" + "path" + "sort" +) + +func TestHarSavingFromFolder(inputDir string) { + dir, _ := os.Open(inputDir) + dirFiles, _ := dir.Readdir(-1) + sort.Sort(utils.ByModTime(dirFiles)) + + for _, fileInfo := range dirFiles { + inputFilePath := path.Join(inputDir, fileInfo.Name()) + file, err := os.Open(inputFilePath) + utils.CheckErr(err) + + var inputHar har.HAR + decErr := json.NewDecoder(bufio.NewReader(file)).Decode(&inputHar) + utils.CheckErr(decErr) + + for _, entry := range inputHar.Log.Entries { + SaveHarToDb(*entry, "") + } + } +} + +func SaveHarToDb(entry har.Entry, source string) { + entryBytes, _ := json.Marshal(entry) + serviceName, urlPath := getServiceNameFromUrl(entry.Request.URL) + mizuEntry := models.MizuEntry{ + EntryId: primitive.NewObjectID().Hex(), + Entry: string(entryBytes), // simple way to store it and not convert to bytes + Service: serviceName, + Url: entry.Request.URL, + Path: urlPath, + Method: entry.Request.Method, + Status: entry.Response.Status, + Source: source, + Timestamp: entry.StartedDateTime.Unix(), + } + database.GetEntriesTable().Create(&mizuEntry) +} + +func getServiceNameFromUrl(inputUrl string) (string, string) { + parsed, err := url.Parse(inputUrl) + utils.CheckErr(err) + return fmt.Sprintf("%s://%s", parsed.Scheme, parsed.Host), parsed.Path +}