Compare commits
18 Commits
db138c6ae2
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 66ef9e6d0c | |||
| ed48629a61 | |||
| e48cbd396b | |||
| 6c2f8c286b | |||
| 113bef6582 | |||
| 1b7a9629d5 | |||
| 316fd60fc3 | |||
| 936f2ec6f5 | |||
| 41583afb47 | |||
| d788822b06 | |||
| 07a73fbeef | |||
| e557cfa257 | |||
| 4fc51f86e4 | |||
| 5db5b0aeba | |||
| 40dbf1123a | |||
| a3939cf2ea | |||
| 27f811236a | |||
| ea191fc036 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -16,3 +16,6 @@
|
|||||||
# vendor/
|
# vendor/
|
||||||
.idea
|
.idea
|
||||||
secrets.json
|
secrets.json
|
||||||
|
test
|
||||||
|
secrets_test.json
|
||||||
|
csrf-key
|
||||||
|
|||||||
@ -1,3 +1,8 @@
|
|||||||
# RBU_account
|
# RBU_account
|
||||||
|
|
||||||
RBU account system
|
RBU account system
|
||||||
|
|
||||||
|
# api
|
||||||
|
use `/login?redirect=someurl` to redirect the user after the login is finnished.
|
||||||
|
Use `api/accountinfo?accountkey=key&password=password` to get information about the user.
|
||||||
|
accountkey is the value of the cookie with the key "session".
|
||||||
|
|||||||
6
config.json
Normal file
6
config.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"createGiteaAccount": false,
|
||||||
|
"port": 8080,
|
||||||
|
"rootUrl": "http://localhost:8080",
|
||||||
|
"databaseType": "mysql"
|
||||||
|
}
|
||||||
6
config_test.json
Normal file
6
config_test.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"createGiteaAccount": false,
|
||||||
|
"port": 8080,
|
||||||
|
"rootUrl": "http://localhost:8080",
|
||||||
|
"databaseType": "sqlite3"
|
||||||
|
}
|
||||||
16
go.mod
16
go.mod
@ -3,18 +3,20 @@ module git.redstoneunion.de/MrGeorgen/RBU_account
|
|||||||
go 1.14
|
go 1.14
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/bwmarrin/discordgo v0.22.0
|
code.gitea.io/sdk/gitea v0.13.2
|
||||||
github.com/cornelk/hashmap v1.0.1
|
github.com/bwmarrin/discordgo v0.23.2
|
||||||
github.com/dlclark/regexp2 v1.4.0
|
github.com/dlclark/regexp2 v1.4.0
|
||||||
github.com/go-sql-driver/mysql v1.5.0
|
github.com/go-sql-driver/mysql v1.5.0
|
||||||
github.com/golang/protobuf v1.4.3 // indirect
|
github.com/golang/protobuf v1.4.3 // indirect
|
||||||
|
github.com/gorilla/csrf v1.7.0
|
||||||
|
github.com/gorilla/mux v1.8.0
|
||||||
github.com/gorilla/websocket v1.4.2 // indirect
|
github.com/gorilla/websocket v1.4.2 // indirect
|
||||||
github.com/tidwall/rhh v1.1.1 // indirect
|
github.com/mattn/go-sqlite3 v1.14.6
|
||||||
github.com/tidwall/shardmap v0.0.0-20190927132224-c190691bd211
|
github.com/mitchellh/mapstructure v1.4.1
|
||||||
github.com/zaddok/moodle v0.6.6
|
github.com/zaddok/moodle v0.6.6
|
||||||
golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392
|
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
|
||||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b // indirect
|
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 // indirect
|
||||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3 // indirect
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/protobuf v1.25.0 // indirect
|
google.golang.org/protobuf v1.25.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
80
go.sum
80
go.sum
@ -1,20 +1,13 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
code.gitea.io/sdk/gitea v0.13.2 h1:wAnT/J7Z62q3fJXbgnecoaOBh8CM1Qq0/DakWxiv4yA=
|
||||||
|
code.gitea.io/sdk/gitea v0.13.2/go.mod h1:lee2y8LeV3kQb2iK+hHlMqoadL4bp27QOkOV/hawLKg=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/bwmarrin/discordgo v0.23.2 h1:BzrtTktixGHIu9Tt7dEE6diysEF9HWnXeHuoJEt2fH4=
|
||||||
github.com/bwmarrin/discordgo v0.20.3 h1:AxjcHGbyBFSC0a3Zx5nDQwbOjU7xai5dXjRnZ0YB7nU=
|
github.com/bwmarrin/discordgo v0.23.2/go.mod h1:c1WtWUGN6nREDmzIpyTp/iD3VYt4Fpx+bVyfBG7JE+M=
|
||||||
github.com/bwmarrin/discordgo v0.20.3/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVOwN61zSZ0r4Q=
|
|
||||||
github.com/bwmarrin/discordgo v0.22.0 h1:uBxY1HmlVCsW1IuaPjpCGT6A2DBwRn0nvOguQIxDdFM=
|
|
||||||
github.com/bwmarrin/discordgo v0.22.0/go.mod h1:c1WtWUGN6nREDmzIpyTp/iD3VYt4Fpx+bVyfBG7JE+M=
|
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
|
||||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/cornelk/hashmap v1.0.1 h1:RXGcy29hEdLLV8T6aK4s+BAd4tq4+3Hq50N2GoG0uIg=
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
github.com/cornelk/hashmap v1.0.1/go.mod h1:8wbysTUDnwJGrPZ1Iwsou3m+An6sldFrJItjRhfegCw=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dchest/siphash v1.1.0 h1:1Rs9eTUlZLPBEvV+2sTaM8O0NWn0ppbgqS7p11aWawI=
|
|
||||||
github.com/dchest/siphash v1.1.0/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4=
|
|
||||||
github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk=
|
|
||||||
github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
|
||||||
github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
|
github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
|
||||||
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
@ -24,7 +17,6 @@ github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB
|
|||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
|
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||||
@ -39,30 +31,37 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
|
|||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
|
||||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
github.com/gorilla/csrf v1.7.0 h1:mMPjV5/3Zd460xCavIkppUdvnl5fPXMpv2uz2Zyg7/Y=
|
||||||
|
github.com/gorilla/csrf v1.7.0/go.mod h1:+a/4tCmqhG6/w4oafeAZ9pEa3/NZOWYVbD9fV0FwIQA=
|
||||||
|
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||||
|
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||||
|
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
|
||||||
|
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI=
|
||||||
|
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
|
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
|
||||||
|
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/tidwall/lotsa v1.0.1/go.mod h1:X6NiU+4yHA3fE3Puvpnn1XMDrFZrE9JO2/w+UMuqgR8=
|
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||||
github.com/tidwall/rhh v1.1.1 h1:8zDpMKcK1pA1zU+Jyuo1UdzTFvME8pH3Sx/MdYgM5sE=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/tidwall/rhh v1.1.1/go.mod h1:DmqiIRtSnlVEi5CSKqNaX6m3YTa3YNSYrGB4FlfdLUU=
|
|
||||||
github.com/tidwall/shardmap v0.0.0-20190927132224-c190691bd211 h1:PiivTZ10nwpNhdOLyoCPcYTxHMQ0K9vXUXG9PU19lmc=
|
|
||||||
github.com/tidwall/shardmap v0.0.0-20190927132224-c190691bd211/go.mod h1:Mrr4SdBhvY+pIzCrRJ8ZnbarljEN4ph2rh9GzjRQEWI=
|
|
||||||
github.com/zaddok/moodle v0.5.0 h1:09GsVDr4xR5hLiBwcv9FlrhAxVzMLA5F03Mj7oAigVA=
|
|
||||||
github.com/zaddok/moodle v0.5.0/go.mod h1:VdegpktsJUouASZqd3GHlZKHTJhfSDFOTtIYtMu8tmg=
|
|
||||||
github.com/zaddok/moodle v0.6.6 h1:DQqlOIV9aJVm+jjCPRYuntQgeTafutvLwj5dTMhcx/Y=
|
github.com/zaddok/moodle v0.6.6 h1:DQqlOIV9aJVm+jjCPRYuntQgeTafutvLwj5dTMhcx/Y=
|
||||||
github.com/zaddok/moodle v0.6.6/go.mod h1:wZJLOprT38gE97uCczwUym6iSGzXWDka069e8VwJ9ro=
|
github.com/zaddok/moodle v0.6.6/go.mod h1:wZJLOprT38gE97uCczwUym6iSGzXWDka069e8VwJ9ro=
|
||||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16 h1:y6ce7gCWtnH+m3dCjzQ1PCuwl28DDIc3VNnvY29DlIA=
|
|
||||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/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-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 h1:vEg9joUBmeBcK9iSJftGNf3coIG4HqZElCPehJsfAYM=
|
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
|
||||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
|
||||||
golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392 h1:xYJJ3S178yv++9zXV/hnr29plCAGO9vAFG9dorqaFQc=
|
|
||||||
golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
@ -72,25 +71,21 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r
|
|||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
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-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65 h1:+rhAzEzT3f4JtomfC371qB+0Ola2caSKcY69NUBZrRQ=
|
|
||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/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-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME=
|
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew=
|
||||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/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-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
|
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200610111108-226ff32320da h1:bGb80FudwxpeucJUjPYJXuJ8Hk91vNtfvrymzwiei38=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200610111108-226ff32320da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3 h1:kzM6+9dur93BcC2kVlYl34cHU+TYZLanmpSJHVMmL64=
|
|
||||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/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-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.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
@ -99,10 +94,10 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
|
|||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
|
|
||||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
@ -118,10 +113,13 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ
|
|||||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
|
||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
|
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
|
||||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
|||||||
29
src/api.go
Normal file
29
src/api.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package main
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"encoding/json"
|
||||||
|
)
|
||||||
|
type accountApiResponse struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
DiscordUserId string `json:"discordUserId"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
}
|
||||||
|
func accountApi(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var accountKey string = r.FormValue("accountkey")
|
||||||
|
var password string = r.FormValue("password")
|
||||||
|
if password != secret.ApiToken {
|
||||||
|
http.Error(w, "Error 401 false password", 401)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var account accountApiResponse
|
||||||
|
var success bool
|
||||||
|
var usernameInter interface{}
|
||||||
|
usernameInter, success = sessions.Load(accountKey)
|
||||||
|
account.Username = usernameInter.(string)
|
||||||
|
if !success {
|
||||||
|
http.Error(w, "Error 400 invalid session", 400)
|
||||||
|
}
|
||||||
|
db.QueryRow("SELECT email,discordUserId FROM account WHERE username = ?", account.Username).Scan(&account.Email, &account.DiscordUserId)
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(account)
|
||||||
|
}
|
||||||
66
src/login.go
Normal file
66
src/login.go
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
package main
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
"net/http"
|
||||||
|
"bytes"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
type loginStruct struct {
|
||||||
|
FalsePassword bool
|
||||||
|
}
|
||||||
|
var sessions sync.Map
|
||||||
|
const sessionName string = "session"
|
||||||
|
const sessionTimeout time.Duration = 10 * 24 * time.Hour
|
||||||
|
func login(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var redirectUrl = r.FormValue("redirecturl")
|
||||||
|
if redirectUrl == "" {
|
||||||
|
redirectUrl = "/"
|
||||||
|
}
|
||||||
|
loginStruct := loginStruct{}
|
||||||
|
var login bool = false
|
||||||
|
if loggedIn(r) {
|
||||||
|
http.Redirect(w, r, redirectUrl, http.StatusSeeOther)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if r.Method == http.MethodPost {
|
||||||
|
var username string = r.FormValue("username")
|
||||||
|
var password string = r.FormValue("password")
|
||||||
|
var hash []byte
|
||||||
|
var salt []byte
|
||||||
|
db.QueryRow("SELECT hash,salt FROM account WHERE username = ?", username).Scan(&hash, &salt)
|
||||||
|
login = bytes.Equal(hashFunc([]byte(password), salt), hash)
|
||||||
|
loginStruct.FalsePassword = !login
|
||||||
|
if login {
|
||||||
|
key, err := GenerateRandomString(64)
|
||||||
|
log(err)
|
||||||
|
cookie := http.Cookie{
|
||||||
|
Name: sessionName,
|
||||||
|
Value: key,
|
||||||
|
Expires: time.Now().Add(sessionTimeout),
|
||||||
|
HttpOnly: true,
|
||||||
|
Secure: true,
|
||||||
|
}
|
||||||
|
http.SetCookie(w, &cookie)
|
||||||
|
sessions.Store(key, username)
|
||||||
|
go deleteSession(key)
|
||||||
|
http.Redirect(w, r, redirectUrl, http.StatusSeeOther)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if r.Method == http.MethodGet || !login {
|
||||||
|
runTemplate(r, w, loginTmpl, loginStruct)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func loggedIn(r *http.Request) bool {
|
||||||
|
cookie, err := r.Cookie(sessionName)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
_, valid := sessions.Load(cookie.Value)
|
||||||
|
return valid
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteSession(key string) {
|
||||||
|
time.Sleep(sessionTimeout)
|
||||||
|
sessions.Delete(key)
|
||||||
|
}
|
||||||
202
src/main.go
202
src/main.go
@ -1,65 +1,56 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"net/http"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"github.com/bwmarrin/discordgo"
|
"github.com/bwmarrin/discordgo"
|
||||||
"github.com/dlclark/regexp2"
|
"github.com/dlclark/regexp2"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
_ "github.com/mattn/go-sqlite3"
|
||||||
"github.com/zaddok/moodle"
|
"github.com/zaddok/moodle"
|
||||||
"html/template"
|
"html/template"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"code.gitea.io/sdk/gitea"
|
||||||
"golang.org/x/crypto/argon2"
|
"fmt"
|
||||||
"context"
|
"github.com/gorilla/csrf"
|
||||||
"time"
|
"github.com/gorilla/mux"
|
||||||
"github.com/cornelk/hashmap"
|
|
||||||
)
|
)
|
||||||
var discord *discordgo.Session
|
var discord *discordgo.Session
|
||||||
var secret secrets_json
|
var secret secrets_json
|
||||||
var cacheAccounts hashmap.HashMap
|
var config config_json
|
||||||
type account struct {
|
var db *sql.DB
|
||||||
email string
|
var giteaClient *gitea.Client
|
||||||
username string
|
var registerTmpl *template.Template
|
||||||
password string
|
var submitTmpl *template.Template
|
||||||
discordUsername string
|
var loginTmpl *template.Template
|
||||||
}
|
var stmtCreateAccount *sql.Stmt
|
||||||
type WrongAccount struct {
|
var isTest bool
|
||||||
User bool
|
|
||||||
Pass bool
|
|
||||||
Email bool
|
|
||||||
DiscordUser bool
|
|
||||||
}
|
|
||||||
type registertmpl struct {
|
|
||||||
Success bool
|
|
||||||
WrongAccount WrongAccount
|
|
||||||
AlreadyEsitsInDatabase struct{
|
|
||||||
Username bool
|
|
||||||
DiscordUsername bool
|
|
||||||
}
|
|
||||||
}
|
|
||||||
type SubmitStruct struct {
|
|
||||||
Success bool
|
|
||||||
}
|
|
||||||
type secrets_json struct {
|
type secrets_json struct {
|
||||||
DiscordToken string `json:"discordToken"`
|
DiscordToken string `json:"discordToken"`
|
||||||
MysqlIndentify string `json:"mysqlIndentify"`
|
MysqlIndentify string `json:"mysqlIndentify"`
|
||||||
DiscordServerID string `json:"discordServerID"`
|
DiscordServerID string `json:"discordServerID"`
|
||||||
MoodleToken string `json:"moodleToken"`
|
MoodleToken string `json:"moodleToken"`
|
||||||
|
GiteaToken string `json:"giteaToken"`
|
||||||
|
ApiToken string `json:"apiToken"`
|
||||||
|
DiscordTestUser string `json:"discordTestUser"`
|
||||||
|
DiscordTestUserEmail string `json:"discordTestUserEmail"`
|
||||||
|
DiscordTestUserPassword string `json:"discordTestUserpassword"`
|
||||||
|
DiscordBotUserId string `json:"discordBotUserId"`
|
||||||
|
}
|
||||||
|
type config_json struct {
|
||||||
|
CreateGiteaAccount bool `json:"createGiteaAccount"`
|
||||||
|
Port uint16 `json:"port"`
|
||||||
|
RootUrl string `json:"rootUrl"`
|
||||||
|
DatabaseType string `json:"databaseType"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var newRbuMember *discordgo.Member
|
|
||||||
var dmChannel *discordgo.Channel
|
|
||||||
var err error
|
var err error
|
||||||
var SubmitStruct SubmitStruct
|
|
||||||
var jsonfile *os.File
|
var jsonfile *os.File
|
||||||
jsonfile, err = os.Open("secrets.json")
|
jsonfile, err = os.Open("secrets" + testFilename() + ".json")
|
||||||
log(err)
|
log(err)
|
||||||
var jsondata []byte
|
var jsondata []byte
|
||||||
jsondata, err = ioutil.ReadAll(jsonfile)
|
jsondata, err = ioutil.ReadAll(jsonfile)
|
||||||
@ -67,129 +58,64 @@ func main() {
|
|||||||
err = json.Unmarshal(jsondata, &secret)
|
err = json.Unmarshal(jsondata, &secret)
|
||||||
log(err)
|
log(err)
|
||||||
jsonfile.Close()
|
jsonfile.Close()
|
||||||
|
jsonfile, err = os.Open("config" + testFilename() + ".json")
|
||||||
|
log(err)
|
||||||
|
jsondata, err = ioutil.ReadAll(jsonfile)
|
||||||
|
log(err)
|
||||||
|
err = json.Unmarshal(jsondata, &config)
|
||||||
|
log(err)
|
||||||
|
jsonfile.Close()
|
||||||
|
if(config.DatabaseType != "mysql" && config.DatabaseType != "sqlite3") {
|
||||||
|
fmt.Println("Unknown database type. Use mysql or sqlite3")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
discordgo.MakeIntent(discordgo.IntentsAll)
|
discordgo.MakeIntent(discordgo.IntentsAll)
|
||||||
discord, err = discordgo.New("Bot " + secret.DiscordToken)
|
discord, err = discordgo.New("Bot " + secret.DiscordToken)
|
||||||
log(err)
|
log(err)
|
||||||
err = discord.Open()
|
err = discord.Open()
|
||||||
log(err)
|
log(err)
|
||||||
db, err := sql.Open("mysql", secret.MysqlIndentify)
|
db, err = sql.Open(config.DatabaseType, secret.MysqlIndentify)
|
||||||
log(err)
|
log(err)
|
||||||
_, err = db.Exec("CREATE TABLE IF NOT EXISTS account(" +
|
_, err = db.Exec("CREATE TABLE IF NOT EXISTS account(" +
|
||||||
"username varchar(40) NOT NULL, " +
|
"username varchar(40) NOT NULL, " +
|
||||||
"email varchar(255) NOT NULL, " +
|
"email varchar(255) NOT NULL, " +
|
||||||
"hash TINYBLOB NOT NULL, " +
|
"hash TINYBLOB NOT NULL, " +
|
||||||
"salt TINYBLOB NOT NULL, " +
|
"salt TINYBLOB NOT NULL, " +
|
||||||
"discordUsername varchar(32) NOT NULL, " +
|
"discordUserId varchar(32) NOT NULL, " +
|
||||||
"PRIMARY KEY ( username )" +
|
"PRIMARY KEY ( username )" +
|
||||||
");")
|
");")
|
||||||
log(err)
|
log(err)
|
||||||
|
giteaClient, err = gitea.NewClient("https://git.redstoneunion.de", gitea.SetToken(secret.GiteaToken))
|
||||||
|
log(err)
|
||||||
moodle := moodle.NewMoodleApi("https://exam.redstoneunion.de/", secret.MoodleToken)
|
moodle := moodle.NewMoodleApi("https://exam.redstoneunion.de/", secret.MoodleToken)
|
||||||
_ = moodle
|
_ = moodle
|
||||||
tmpl := template.Must(template.ParseFiles("tmpl/register.html"))
|
registerTmpl = template.Must(template.ParseFiles("tmpl/register.html"))
|
||||||
submitTmpl := template.Must(template.ParseFiles("tmpl/submit.html"))
|
submitTmpl = template.Must(template.ParseFiles("tmpl/submit.html"))
|
||||||
remail := regexp2.MustCompile("^(?=.{0,255}$)(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])$", 0)
|
loginTmpl = template.Must(template.ParseFiles("tmpl/login.html"))
|
||||||
rusername := regexp.MustCompile("^([[:lower:]]|\\d|_|-|\\.){1,40}$")
|
remail = regexp2.MustCompile("^(?=.{0,255}$)(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])$", 0)
|
||||||
rpassword := regexp2.MustCompile("^(?=.{8,255}$)(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*\\W).*$", 0)
|
rusername = regexp.MustCompile("^([[:lower:]]|\\d|_|-|\\.){1,40}$")
|
||||||
registerstruct := registertmpl{}
|
rpassword = regexp2.MustCompile("^(?=.{8,255}$)(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*\\W).*$", 0)
|
||||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
stmtCreateAccount, err = db.Prepare("INSERT INTO account(username, email, hash, salt, discordUserId) VALUES(?,?,?,?,?)")
|
||||||
if r.Method == http.MethodPost {
|
csrfKeyfile, err := os.Open("csrf-key")
|
||||||
newAccount := account{
|
|
||||||
email: r.FormValue("email"),
|
|
||||||
username: r.FormValue("username"),
|
|
||||||
password: r.FormValue("password"),
|
|
||||||
discordUsername: r.FormValue("discordUser"),
|
|
||||||
}
|
|
||||||
registerstruct.WrongAccount.Email, _ = remail.MatchString(newAccount.email)
|
|
||||||
registerstruct.WrongAccount.Email = !registerstruct.WrongAccount.Email
|
|
||||||
registerstruct.WrongAccount.User = !rusername.MatchString(newAccount.username) || strings.Contains(newAccount.username, "\"")
|
|
||||||
registerstruct.WrongAccount.Pass, _ = rpassword.MatchString(newAccount.password)
|
|
||||||
registerstruct.WrongAccount.Pass = !registerstruct.WrongAccount.Pass
|
|
||||||
newRbuMember, registerstruct.WrongAccount.DiscordUser = getRbuMember(newAccount.discordUsername)
|
|
||||||
registerstruct.WrongAccount.DiscordUser = !registerstruct.WrongAccount.DiscordUser
|
|
||||||
{
|
|
||||||
var username string
|
|
||||||
registerstruct.AlreadyEsitsInDatabase.Username = db.QueryRow("select username from account where username = ?", newAccount.username).Scan(&username) == nil || UsernameExistsInMem(newAccount.username) // check if username exits
|
|
||||||
registerstruct.AlreadyEsitsInDatabase.DiscordUsername = db.QueryRow("select username from account where discordUsername = ?", newAccount.discordUsername).Scan(&username) == nil || discordUsernameExistsInMem(newAccount.discordUsername)
|
|
||||||
}
|
|
||||||
registerstruct.Success = !registerstruct.WrongAccount.User && !registerstruct.WrongAccount.Pass && !registerstruct.WrongAccount.Email && !registerstruct.WrongAccount.DiscordUser && !registerstruct.AlreadyEsitsInDatabase.DiscordUsername && !registerstruct.AlreadyEsitsInDatabase.Username
|
|
||||||
if registerstruct.Success {
|
|
||||||
token, err := GenerateRandomStringURLSafe(64)
|
|
||||||
log(err)
|
log(err)
|
||||||
dmChannel, err = discord.UserChannelCreate(newRbuMember.User.ID)
|
csrfKey, err := ioutil.ReadAll(csrfKeyfile)
|
||||||
log(err)
|
log(err)
|
||||||
discord.ChannelMessageSend(dmChannel.ID, "Bitte klicke auf den Link, um die Erstellung des Accounts abzuschließen.\nhttp://localhost:8080/submit?token=" + token)
|
csrfKeyfile.Close()
|
||||||
cacheAccounts.Set(token, newAccount)
|
csrfHandler := csrf.Protect(csrfKey)
|
||||||
}
|
router := mux.NewRouter()
|
||||||
}
|
router.HandleFunc("/register", register)
|
||||||
tmpl.Execute(w, registerstruct)
|
router.HandleFunc("/submit", submit)
|
||||||
fmt.Println(registerstruct)
|
router.HandleFunc("/login", login)
|
||||||
})
|
router.HandleFunc("/api/accountinfo", accountApi)
|
||||||
http.HandleFunc("/submit", func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
token := r.FormValue("token")
|
|
||||||
var accInter interface{}
|
|
||||||
accInter, SubmitStruct.Success = cacheAccounts.GetStringKey(token)
|
|
||||||
var account account = accInter.(account)
|
|
||||||
if SubmitStruct.Success {
|
|
||||||
fmt.Println(token);
|
|
||||||
salt := make([]byte, 32)
|
|
||||||
_, err := rand.Read(salt)
|
|
||||||
log(err)
|
|
||||||
hash := argon2.IDKey([]byte(account.password), salt[:], 1, 64*1024, 4, 32)
|
|
||||||
// add user to the database
|
|
||||||
query := "INSERT INTO account(username, email, hash, salt, discordUsername) VALUES (?, ?, ?, ?, ?)"
|
|
||||||
ctx, cancelfunc := context.WithTimeout(context.Background(), 5*time.Second)
|
|
||||||
defer cancelfunc()
|
|
||||||
stmt, err := db.PrepareContext(ctx, query)
|
|
||||||
log(err)
|
|
||||||
defer stmt.Close()
|
|
||||||
_, err = stmt.ExecContext(ctx, account.username, account.email, hash, salt, account.discordUsername)
|
|
||||||
log(err)
|
|
||||||
//_, err = moodle.AddUser(account.username, account.username, account.email, account.username, account.password)
|
|
||||||
log(err)
|
|
||||||
cacheAccounts.Del(token)
|
|
||||||
}
|
|
||||||
err = submitTmpl.Execute(w, SubmitStruct)
|
|
||||||
log(err)
|
|
||||||
})
|
|
||||||
|
|
||||||
http.ListenAndServe(":8080", nil)
|
if(!isTest) {
|
||||||
}
|
http.ListenAndServe(":" + fmt.Sprint(config.Port), csrfHandler(router))
|
||||||
func getRbuMember(user string) (*discordgo.Member, bool) {
|
|
||||||
allUsers, err := discord.GuildMembers(secret.DiscordServerID, "0", 1000)
|
|
||||||
log(err)
|
|
||||||
for _, element := range allUsers {
|
|
||||||
if element.User.Username==user {
|
|
||||||
return element, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
func log(err error) {
|
|
||||||
if err!=nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func UsernameExistsInMem(username string) bool {
|
func testFilename() string {
|
||||||
for key := range cacheAccounts.Iter() {
|
if(isTest) {
|
||||||
var accInter interface{}
|
return "_test"
|
||||||
accInter, _ = cacheAccounts.Get(key)
|
|
||||||
var account account = accInter.(account)
|
|
||||||
if account.username == username {
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
}
|
return ""
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func discordUsernameExistsInMem(discordUsername string) bool {
|
|
||||||
for key := range cacheAccounts.Iter() {
|
|
||||||
var accInter interface{}
|
|
||||||
accInter, _ = cacheAccounts.Get(key)
|
|
||||||
var account account = accInter.(account)
|
|
||||||
if account.discordUsername == discordUsername {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|||||||
92
src/main_test.go
Normal file
92
src/main_test.go
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"net/url"
|
||||||
|
"bytes"
|
||||||
|
"strings"
|
||||||
|
"github.com/bwmarrin/discordgo"
|
||||||
|
"github.com/dlclark/regexp2"
|
||||||
|
"html/template"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
var testPassword = "*#566jgjgJJf"
|
||||||
|
var testUsername = "ausername"
|
||||||
|
var testSession string
|
||||||
|
|
||||||
|
func TestOrder(test *testing.T) {
|
||||||
|
isTest = true
|
||||||
|
main()
|
||||||
|
test.Run("register", testRegister)
|
||||||
|
test.Run("submit", testSubmit)
|
||||||
|
test.Run("login", testLogin)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testSetUsernamePassword(form url.Values) {
|
||||||
|
form.Set("username", testUsername)
|
||||||
|
form.Set("password", testPassword)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testForm(test *testing.T, url string, statusCode int, handler http.HandlerFunc, form url.Values) *http.Response {
|
||||||
|
request := httptest.NewRequest("POST", url, strings.NewReader(form.Encode()))
|
||||||
|
request.Form = form
|
||||||
|
recorder := httptest.NewRecorder()
|
||||||
|
handler.ServeHTTP(recorder, request)
|
||||||
|
if recorder.Code != statusCode {
|
||||||
|
test.Errorf("handler returned wrong status code: got %v want %v", recorder.Code, http.StatusOK)
|
||||||
|
}
|
||||||
|
return recorder.Result()
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkBodyByTemplate(test *testing.T, response *http.Response, template *template.Template, templateData interface{}) {
|
||||||
|
var expectedResponse bytes.Buffer
|
||||||
|
template.Execute(&expectedResponse, templateData)
|
||||||
|
checkBody(test, response, expectedResponse.Bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkBody(test *testing.T, response *http.Response, expectedResponse []byte) {
|
||||||
|
responseBody, _ := io.ReadAll(response.Body)
|
||||||
|
if !bytes.Equal(expectedResponse, responseBody) {
|
||||||
|
test.Errorf("unexpected body:\n%v", string(responseBody))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testRegister(test *testing.T) {
|
||||||
|
form := url.Values{}
|
||||||
|
testSetUsernamePassword(form)
|
||||||
|
form.Set("email", "jffg@fv.com")
|
||||||
|
form.Set("discordUser", secret.DiscordTestUser)
|
||||||
|
response := testForm(test, "/register", http.StatusOK, register, form)
|
||||||
|
checkBodyByTemplate(test, response, registerTmpl, registerStruct{Success: true})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testSubmit(test *testing.T) {
|
||||||
|
discordClient, err := discordgo.New()
|
||||||
|
log(err)
|
||||||
|
err = discordClient.Login(secret.DiscordTestUserEmail, secret.DiscordTestUserPassword)
|
||||||
|
log(err)
|
||||||
|
err = discordClient.Open()
|
||||||
|
log(err)
|
||||||
|
channel, err := discordClient.UserChannelCreate(secret.DiscordBotUserId)
|
||||||
|
log(err)
|
||||||
|
msg, err := discordClient.ChannelMessages(channel.ID, 1, "", "", channel.LastMessageID)
|
||||||
|
log(err)
|
||||||
|
re := regexp2.MustCompile(`(?<=\?token\=)[^>]*`, 0)
|
||||||
|
match, _ := re.FindStringMatch(msg[0].Content)
|
||||||
|
if match == nil {
|
||||||
|
test.Error("The submit link was not send")
|
||||||
|
}
|
||||||
|
form := url.Values{}
|
||||||
|
form.Set("token", match.String())
|
||||||
|
response := testForm(test, "/submit", http.StatusOK, submit, form)
|
||||||
|
checkBodyByTemplate(test, response, submitTmpl, submitStruct{Success: true})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testLogin(test *testing.T) {
|
||||||
|
form := url.Values{}
|
||||||
|
testSetUsernamePassword(form)
|
||||||
|
testForm(test, "/login", http.StatusSeeOther, login, form)
|
||||||
|
}
|
||||||
138
src/register.go
Normal file
138
src/register.go
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
package main
|
||||||
|
import (
|
||||||
|
"github.com/bwmarrin/discordgo"
|
||||||
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
"regexp"
|
||||||
|
"github.com/dlclark/regexp2"
|
||||||
|
"code.gitea.io/sdk/gitea"
|
||||||
|
"crypto/rand"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
type account struct {
|
||||||
|
email string
|
||||||
|
username string
|
||||||
|
password string
|
||||||
|
discordUsername string
|
||||||
|
discordTag string
|
||||||
|
discordId string
|
||||||
|
}
|
||||||
|
type WrongAccount struct {
|
||||||
|
User bool
|
||||||
|
Pass bool
|
||||||
|
Email bool
|
||||||
|
DiscordUser bool
|
||||||
|
}
|
||||||
|
type registerStruct struct {
|
||||||
|
Success bool
|
||||||
|
WrongAccount WrongAccount
|
||||||
|
AlreadyEsitsInDatabase struct{
|
||||||
|
Username bool
|
||||||
|
DiscordUsername bool
|
||||||
|
}
|
||||||
|
}
|
||||||
|
type submitStruct struct {
|
||||||
|
Success bool
|
||||||
|
}
|
||||||
|
var accountByToken sync.Map
|
||||||
|
var usernameExitsMap sync.Map
|
||||||
|
var discordUserExitsMap sync.Map
|
||||||
|
var rusername *regexp.Regexp
|
||||||
|
var remail *regexp2.Regexp
|
||||||
|
var rpassword *regexp2.Regexp
|
||||||
|
func register(w http.ResponseWriter, r *http.Request) {
|
||||||
|
registerStruct := registerStruct{}
|
||||||
|
if r.Method == http.MethodPost {
|
||||||
|
var newAccount account
|
||||||
|
var newRbuMember *discordgo.Member
|
||||||
|
var split = strings.Split(r.FormValue("discordUser"), "#")
|
||||||
|
newAccount = account{
|
||||||
|
email: r.FormValue("email"),
|
||||||
|
username: r.FormValue("username"),
|
||||||
|
password: r.FormValue("password"),
|
||||||
|
}
|
||||||
|
if len(split) == 2 {
|
||||||
|
newAccount.discordUsername = split[0]
|
||||||
|
newAccount.discordTag = split[1]
|
||||||
|
}
|
||||||
|
registerStruct.WrongAccount.Email, _ = remail.MatchString(newAccount.email)
|
||||||
|
registerStruct.WrongAccount.Email = !registerStruct.WrongAccount.Email
|
||||||
|
registerStruct.WrongAccount.User = !rusername.MatchString(newAccount.username)
|
||||||
|
registerStruct.WrongAccount.Pass, _ = rpassword.MatchString(newAccount.password)
|
||||||
|
registerStruct.WrongAccount.Pass = !registerStruct.WrongAccount.Pass
|
||||||
|
newRbuMember, registerStruct.WrongAccount.DiscordUser = getRbuMember(newAccount.discordUsername, newAccount.discordTag)
|
||||||
|
registerStruct.WrongAccount.DiscordUser = !registerStruct.WrongAccount.DiscordUser
|
||||||
|
if registerStruct.WrongAccount.DiscordUser {
|
||||||
|
goto registerReturn
|
||||||
|
}
|
||||||
|
newAccount.discordId = newRbuMember.User.ID
|
||||||
|
{
|
||||||
|
var username string
|
||||||
|
_, usernameExitsInMem := usernameExitsMap.Load(newAccount.username)
|
||||||
|
registerStruct.AlreadyEsitsInDatabase.Username = db.QueryRow("SELECT username FROM account WHERE username = ?", newAccount.username).Scan(&username) == nil || usernameExitsInMem
|
||||||
|
_, discordUserExitsInMem := discordUserExitsMap.Load(newAccount.discordId)
|
||||||
|
registerStruct.AlreadyEsitsInDatabase.DiscordUsername = db.QueryRow("SELECT username FROM account WHERE discordUserId = ?", newAccount.discordId).Scan(&username) == nil || discordUserExitsInMem
|
||||||
|
}
|
||||||
|
registerStruct.Success = !registerStruct.WrongAccount.User && !registerStruct.WrongAccount.Pass && !registerStruct.WrongAccount.Email && !registerStruct.WrongAccount.DiscordUser && !registerStruct.AlreadyEsitsInDatabase.DiscordUsername && !registerStruct.AlreadyEsitsInDatabase.Username
|
||||||
|
if !registerStruct.Success {
|
||||||
|
goto registerReturn
|
||||||
|
}
|
||||||
|
token, err := GenerateRandomStringURLSafe(64)
|
||||||
|
log(err)
|
||||||
|
var dmChannel *discordgo.Channel
|
||||||
|
dmChannel, err = discord.UserChannelCreate(newRbuMember.User.ID)
|
||||||
|
log(err)
|
||||||
|
discord.ChannelMessageSend(dmChannel.ID, "Bitte klicke auf den Link, um die Erstellung des Accounts abzuschließen.\n<" + config.RootUrl + "/submit?token=" + token + ">")
|
||||||
|
accountByToken.Store(token, newAccount)
|
||||||
|
usernameExitsMap.Store(newAccount.username, nil)
|
||||||
|
discordUserExitsMap.Store(newAccount.discordId, nil)
|
||||||
|
}
|
||||||
|
registerReturn: runTemplate(r, w, registerTmpl, registerStruct)
|
||||||
|
}
|
||||||
|
func submit(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var err error
|
||||||
|
var submitStruct submitStruct
|
||||||
|
token := r.FormValue("token")
|
||||||
|
var accInter interface{}
|
||||||
|
accInter, submitStruct.Success = accountByToken.LoadAndDelete(token)
|
||||||
|
if !submitStruct.Success {
|
||||||
|
goto submitReturn
|
||||||
|
}
|
||||||
|
{
|
||||||
|
var account account = accInter.(account)
|
||||||
|
usernameExitsMap.Delete(account.username)
|
||||||
|
discordUserExitsMap.Delete(account.discordId)
|
||||||
|
salt := make([]byte, 32)
|
||||||
|
_, err = rand.Read(salt)
|
||||||
|
log(err)
|
||||||
|
hash := hashFunc([]byte(account.password), salt)
|
||||||
|
// add user to the database
|
||||||
|
stmtCreateAccount.Exec(account.username, account.email, hash, salt, account.discordId)
|
||||||
|
//_, err = moodle.AddUser(account.username + "wg", account.username, account.email, account.username, account.password)
|
||||||
|
log(err)
|
||||||
|
if config.CreateGiteaAccount {
|
||||||
|
opt := gitea.CreateUserOption{
|
||||||
|
Email: account.email,
|
||||||
|
Username: account.username,
|
||||||
|
SourceID: 0,
|
||||||
|
Password: account.password,
|
||||||
|
SendNotify: false,
|
||||||
|
}
|
||||||
|
_, _, err = giteaClient.AdminCreateUser(opt)
|
||||||
|
log(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
submitReturn: runTemplate(r, w, submitTmpl, submitStruct)
|
||||||
|
}
|
||||||
|
func getRbuMember(user string, tag string) (*discordgo.Member, bool) {
|
||||||
|
allUsers, err := discord.GuildMembers(secret.DiscordServerID, "0", 1000)
|
||||||
|
log(err)
|
||||||
|
for _, element := range allUsers {
|
||||||
|
if element.User.Username == user && element.User.Discriminator == tag{
|
||||||
|
return element, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
26
src/util.go
Normal file
26
src/util.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package main
|
||||||
|
import (
|
||||||
|
"golang.org/x/crypto/argon2"
|
||||||
|
"net/http"
|
||||||
|
"html/template"
|
||||||
|
"github.com/gorilla/csrf"
|
||||||
|
"github.com/mitchellh/mapstructure"
|
||||||
|
)
|
||||||
|
|
||||||
|
func log(err error) {
|
||||||
|
if err!=nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func hashFunc(password []byte, salt []byte) []byte {
|
||||||
|
return argon2.IDKey(password, salt, 1, 64*1024, 4, 32)
|
||||||
|
}
|
||||||
|
func runTemplate(r *http.Request, w http.ResponseWriter, template *template.Template, templateData interface{}) {
|
||||||
|
var templateMap map[string]interface{}
|
||||||
|
mapstructure.Decode(templateData, &templateMap)
|
||||||
|
templateMap[csrf.TemplateTag] = csrf.TemplateField(r)
|
||||||
|
w.Header().Set("Content-Type", "text/html")
|
||||||
|
var err error = template.Execute(w, templateMap)
|
||||||
|
log(err)
|
||||||
|
}
|
||||||
10
tmpl/login.html
Normal file
10
tmpl/login.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{{if .FalsePassword}}
|
||||||
|
<p>falches Passwort</p>
|
||||||
|
{{end}}
|
||||||
|
<form method="POST" class="responsive">
|
||||||
|
<label class="responsive">Benutzername:</label><br/>
|
||||||
|
<input class="responsive" type="text" name="username"><br/>
|
||||||
|
<label class="responsive">Passwort:</label><br/>
|
||||||
|
<input class="responsive" type="password" name="password"><br/>
|
||||||
|
<input type="submit" name="login" value="login"class="btn active responsive">
|
||||||
|
</form>
|
||||||
@ -1,17 +1,71 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>RBU - Register</title>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="https://redstoneunion.de/assets/css/bs/styles.css">
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
||||||
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
|
||||||
|
<script src="Subject-Dateien/js"></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
|
||||||
|
function gtag() {
|
||||||
|
dataLayer.push(arguments);
|
||||||
|
}
|
||||||
|
gtag('js', new Date());
|
||||||
|
</script>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="icon" type="image/x-icon" href="https://redstoneunion.de/assets/img/mds_vers2.png">
|
||||||
|
<link href="https://redstoneunion.de/assets/css/css.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://redstoneunion.de/assets/css/styles.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="https://redstoneunion.de/assets/css/font1.css">
|
||||||
|
<link rel="stylesheet" type="text" href="https://redstoneunion.de/assets/css/font2.css">
|
||||||
|
<link rel="stylesheet" type="text" href="https://redstoneunion.de/assets/css/font3.css">
|
||||||
|
<link rel="stylesheet" type="text" href="https://redstoneunion.de/assets/css/font4.css">
|
||||||
|
<link rel="stylesheet" type="text" href="https://redstoneunion.de/assets/css/font5.css">
|
||||||
|
<link rel="stylesheet" type="text" href="https://redstoneunion.de/assets/css/font5.css">
|
||||||
|
<link rel="stylesheet" type="text" href="https://redstoneunion.de/assets/css/layout1.css">
|
||||||
|
<link rel="stylesheet" type="text" href="https://redstoneunion.de/assets/css/calendar1.css.css">
|
||||||
|
<link rel="stylesheet" href="https://redstoneunion.de/assets/animate.css">
|
||||||
|
<link rel="stylesheet" href="https://redstoneunion.de/assets/local.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="mdslogo"><img src="https://redstoneunion.de/assets/img/rbu_logo_modern_wasser.png" class="logoimg"></div>
|
||||||
|
</li>
|
||||||
|
<li><a href="https://redstoneunion.de/index.html">Home</a></li>
|
||||||
|
<li><a href="https://redstoneunion.de/project/index.html">Projekte</a></li>
|
||||||
|
<li><a href="https://redstoneunion.de/mds/home.html">MDS</a></li>
|
||||||
|
<li><a href="https://redstoneunion.de/downloads/index.html">Downloads</a></li>
|
||||||
|
<li><a href="https://redstoneunion.de/imc/index.html">IMC</a>
|
||||||
|
<li><a href="https://redstoneunion.de/applications/index.html">Karriere</a></li>
|
||||||
|
</ul>
|
||||||
|
<div class="row">
|
||||||
|
<center>
|
||||||
|
<div class="Banner responsive">
|
||||||
|
<div class="abs">
|
||||||
|
<img src="https://redstoneunion.de/assets/img/2019-12-22_00.04.35.jpg" class="responsive">
|
||||||
|
</div>
|
||||||
|
<div class="regcard">
|
||||||
|
<img src="https://redstoneunion.de/assets/img/rbu_logo_normal_modern_db.png"class="responsive"><br>
|
||||||
{{if .Success}}
|
{{if .Success}}
|
||||||
<p>Bitte klicke in discord auf den Bestätigungslink.</p>
|
<p>Bitte klicke in discord auf den Bestätigungslink.</p>
|
||||||
{{else}}
|
{{else}}
|
||||||
<h1>Erstelle ein RBU Account</h1>
|
<h1>Erstelle ein RBU Account</h1>
|
||||||
<form method="POST">
|
<form method="POST"class="responsive">
|
||||||
<label>Benutzername:</label><br/>
|
<label class="responsive">Benutzername:</label><br/>
|
||||||
<input type="text" name="username"><br/>
|
<input class="responsive" type="text" name="username"><br/>
|
||||||
<label>E-Mail:</label><br/>
|
<label class="responsive">E-Mail:</label><br/>
|
||||||
<input type="text" name="email"><br/>
|
<input class="responsive" type="text" name="email"><br/>
|
||||||
<label>Discordbenutzername (ohne ####):</label><br/>
|
<label class="responsive">Discordbenutzername (mit ####):</label><br/>
|
||||||
<input type="text" name="discordUser"><br/>
|
<input class="responsive" type="text" name="discordUser"><br/>
|
||||||
<label>Passwort:</label><br/>
|
<label class="responsive">Passwort:</label><br/>
|
||||||
<input name="password"><br/>
|
<input class="responsive" type="password" name="password"><br/>
|
||||||
<input type="submit" name="createAccount" value="Account erstellen">
|
{{ .csrfField }}
|
||||||
|
<input type="submit" name="createAccount" value="Account erstellen"class="btn active responsive">
|
||||||
</form>
|
</form>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .WrongAccount.User}}
|
{{if .WrongAccount.User}}
|
||||||
@ -24,7 +78,7 @@
|
|||||||
<p>Ungültiges Passwort. Passwörter müssen 8 bis 255 Zeichen lang sein. Außerdem muss ein Groß- und Kleichbuchstabe, eine Ziffer und ein Sonderzeichen enthalten sein</p>
|
<p>Ungültiges Passwort. Passwörter müssen 8 bis 255 Zeichen lang sein. Außerdem muss ein Groß- und Kleichbuchstabe, eine Ziffer und ein Sonderzeichen enthalten sein</p>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .WrongAccount.DiscordUser}}
|
{{if .WrongAccount.DiscordUser}}
|
||||||
<p>Discordbenutzer ist nicht auf den RBU server. Beachte den tag wegzulassen.</p>
|
<p>Discordbenutzer ist nicht auf den RBU server. Beachte den tag anzugeben.</p>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .AlreadyEsitsInDatabase.Username}}
|
{{if .AlreadyEsitsInDatabase.Username}}
|
||||||
<p>Diesen Benutzername ist leider schon vergeben.</p>
|
<p>Diesen Benutzername ist leider schon vergeben.</p>
|
||||||
@ -32,3 +86,22 @@
|
|||||||
{{if .AlreadyEsitsInDatabase.DiscordUsername}}
|
{{if .AlreadyEsitsInDatabase.DiscordUsername}}
|
||||||
<p>Dieses RBU Mitglied hat bereits einen Account.</p>
|
<p>Dieses RBU Mitglied hat bereits einen Account.</p>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</center>
|
||||||
|
</div>
|
||||||
|
<footer _ngcontent-c1="" class="footer" style="background-color: #031D41;">
|
||||||
|
<div _ngcontent-c1="" class="container">
|
||||||
|
<img _ngcontent-c1="" alt="RBU logo" class="logo" src="https://redstoneunion.de/assets/img/rbu_logo_modern_wasser.png">
|
||||||
|
<div _ngcontent-c1="" class="copyright">
|
||||||
|
<p _ngcontent-c1="">
|
||||||
|
Copyright © 2021 RBU All rights reserved <a href="rechtliches/impressum.html" class="negtext">Impressum & Datenschutzverordung</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div _ngcontent-c1="" class="top" style="background-color: rgb(177, 51, 41);">
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user