From a869a9faa1b2f8c37ccb8049fa962be80696afb4 Mon Sep 17 00:00:00 2001 From: Mshivam2409 Date: Wed, 3 Mar 2021 22:20:46 +0530 Subject: [PATCH] Refactorized Code #1 --- .gitignore | 1 + .keto/access-policy.json | 38 --------- .keto/keto.yaml | 39 --------- .keto/roles/admin.example.json | 0 .keto/roles/user.example.json | 0 .kratos/.kratos.prod.yml | 5 +- CHANGELOG.md | 14 ++++ api/controller.go | 56 +++++++++++++ {router => api}/router.go | 8 +- changelog.md | 9 --- database/courses.go | 38 --------- database/mongo.go | 34 +++++++- database/users.go | 37 --------- go.mod | 4 +- go.sum | 11 --- googleapis/client.go | 71 ---------------- googleapis/drive.go | 48 ----------- graph/schema.resolvers.go | 4 +- main.go | 43 +++++----- models/user.go | 1 + services/drive.go | 144 ++++++++++++++++++++++++--------- services/keto.go | 43 ---------- services/kratos.go | 27 ------- services/mail.go | 21 +++-- services/ory.go | 122 +++++++++++++++++++++++++--- services/redis.go | 3 +- 26 files changed, 365 insertions(+), 456 deletions(-) delete mode 100644 .keto/access-policy.json delete mode 100644 .keto/keto.yaml delete mode 100644 .keto/roles/admin.example.json delete mode 100644 .keto/roles/user.example.json create mode 100644 CHANGELOG.md create mode 100644 api/controller.go rename {router => api}/router.go (77%) delete mode 100644 changelog.md delete mode 100644 database/courses.go delete mode 100644 database/users.go delete mode 100644 googleapis/client.go delete mode 100644 googleapis/drive.go delete mode 100644 services/keto.go delete mode 100644 services/kratos.go diff --git a/.gitignore b/.gitignore index 81d3edc..923c778 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ bin/main !.secrets/*.secret config.yml config.yaml +kratos diff --git a/.keto/access-policy.json b/.keto/access-policy.json deleted file mode 100644 index bf53949..0000000 --- a/.keto/access-policy.json +++ /dev/null @@ -1,38 +0,0 @@ -[ - { - "subjects": ["admin", "secy", "coordi"], - "resources": ["courses", "files"], - "actions": ["create", "modify"], - "effect": "allow" - }, - { - "subjects": ["admin", "coordi"], - "resources": ["courses", "files"], - "actions": ["delete"], - "effect": "allow" - }, - { - "subjects": ["admin", "user", "secy", "coordi"], - "resources": ["courses", "files"], - "actions": ["read"], - "effect": "allow" - }, - { - "subjects": ["admin", "secy", "coordi"], - "resources": ["cpanel"], - "actions": ["login"], - "effect": "allow" - }, - { - "subjects": ["admin", "user", "secy", "coordi"], - "resources": ["portal"], - "actions": ["login"], - "effect": "allow" - }, - { - "subjects": ["admin", "coordi"], - "resources": ["coordi", "secy"], - "actions": ["create", "delete"], - "effect": "allow" - } -] diff --git a/.keto/keto.yaml b/.keto/keto.yaml deleted file mode 100644 index 48b25e3..0000000 --- a/.keto/keto.yaml +++ /dev/null @@ -1,39 +0,0 @@ -## ORY Kratos Configuration -# - - -## Data Source Name ## -# -# Sets the data source name. This configures the backend where ORY Keto persists data. If dsn is "memory", data will be written to memory and is lost when you restart this instance. ORY Hydra supports popular SQL databases. For more detailed configuration information go to: https://www.ory.sh/docs/hydra/dependencies-environment#sql -# -# Examples: -# - postgres://user:password@host:123/database -# - mysql://user:password@tcp(host:123)/database -# - memory -# -dsn: memory - -## HTTP REST API ## -serve: - port: 4456 - host: 127.0.0.1 - cors: - enabled: true - allowed_origins: - - https://anciitk.in - - http://localhost - - http://127.0.0.1 - allowed_methods: - - TRACE - - DELETE - - PUT - - HEAD - - GET - - POST - allow_credentials: true - max_age: -41798350 - debug: true - -log: - level: debug - format: text \ No newline at end of file diff --git a/.keto/roles/admin.example.json b/.keto/roles/admin.example.json deleted file mode 100644 index e69de29..0000000 diff --git a/.keto/roles/user.example.json b/.keto/roles/user.example.json deleted file mode 100644 index e69de29..0000000 diff --git a/.kratos/.kratos.prod.yml b/.kratos/.kratos.prod.yml index a810902..cd39933 100644 --- a/.kratos/.kratos.prod.yml +++ b/.kratos/.kratos.prod.yml @@ -1,5 +1,8 @@ session: lifespan: 24h + +dsn: memory + serve: public: base_url: http://127.0.0.1:3001/.ory/kratos/public @@ -48,7 +51,7 @@ hashers: salt_length: 16 key_length: 16 identity: - default_schema_url: file:///etc/config/kratos/identity.traits.schema.json + default_schema_url: file:///home/mshivam/AnC/go/.kratos/identity.traits.schema.json courier: smtp: connection_uri: smtps://anc.courses@gmail.com:AnC@2020@smtp.gmail.com:465/?skip_ssl_verify=true diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..8e1b800 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,14 @@ +# Changelog + +## 09/02/2021 `v0.1.0` + +- Initial Commit for web app + +## 10/02/2021 `v0.1.1` + +- GraphQL support added! + +## 03/02/2021 `v0.1.2` + +- Ory KETO has been phased out in support of Custom MongoDB Solution. +- Nodemailer has been phased out in support of go `net/smtp` package. diff --git a/api/controller.go b/api/controller.go new file mode 100644 index 0000000..5617f27 --- /dev/null +++ b/api/controller.go @@ -0,0 +1,56 @@ +package api + +import ( + "context" + "encoding/json" + "fmt" + "strconv" + + "github.com/Mshivam2409/AnC-Courses/database" + "github.com/Mshivam2409/AnC-Courses/models" + "github.com/Mshivam2409/AnC-Courses/services" + "github.com/gofiber/fiber/v2" + "go.mongodb.org/mongo-driver/bson" +) + +// CreateFile sdfs +func CreateFile(c *fiber.Ctx) error { + d := services.GetService() + n, err := strconv.Atoi(c.FormValue("length")) + cno := c.FormValue("course") + if err != nil { + return &fiber.Error{Code: 422, Message: "Length of files must be a number"} + } + files := []string{} + for i := 0; i < n; i++ { + f, err := c.FormFile("file" + fmt.Sprint(n)) + if err != nil { + return &fiber.Error{Code: 422, Message: "Unable to process file!"} + } + r, err := d.CreateFile("", f) + if err != nil { + return &fiber.Error{Code: 422, Message: "Unable to upload file!"} + } + out, err := json.Marshal(r) + if err != nil { + return &fiber.Error{Code: 422, Message: "Unable to get file ID!"} + } + files = append(files, string(out)) + } + update := bson.D{ + {Key: "$push", Value: bson.D{ + {Key: "driveFiles", Value: bson.A{"$each", files}}, + }}, + } + err = database.MongoClient.Courses.Collection("courses").FindOneAndUpdate(context.TODO(), bson.D{{Key: "number", Value: cno}}, update).Decode(&models.MGMCourse{}) + return c.Status(200).JSON(fiber.Map{"message": "success"}) +} + +func DownloadFile(ctx *fiber.Ctx) error { + d := services.GetService() + s, err := d.GetFile(ctx.Params("fid")) + if err != nil { + return &fiber.Error{Code: 500, Message: "Unable to download file!"} + } + return ctx.Status(200).SendStream(s) +} diff --git a/router/router.go b/api/router.go similarity index 77% rename from router/router.go rename to api/router.go index 45ba7b0..8897695 100644 --- a/router/router.go +++ b/api/router.go @@ -1,4 +1,4 @@ -package router +package api import ( "log" @@ -16,7 +16,7 @@ import ( // SetupRoutes .... func SetupRoutes(app *fiber.App) { srv := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &graph.Resolver{}})) - cache, err := services.NewCache(viper.GetString("redis"), viper.GetString("fsd"), 24*time.Hour) + cache, err := services.NewCache(viper.GetString("redis.host"), viper.GetString("redis.pwd"), 24*time.Hour) if err != nil { log.Printf("cannot create APQ redis cache: %v", err) } @@ -29,5 +29,7 @@ func SetupRoutes(app *fiber.App) { return nil }) restAPI := app.Group("/secure") - restAPI.Post("/file/create", services.CreateFile) + restAPI.Post("/file/create", CreateFile) + app.Get("/file/:fid", DownloadFile) + // app.Post("/register", services.Register) } diff --git a/changelog.md b/changelog.md deleted file mode 100644 index e3c6879..0000000 --- a/changelog.md +++ /dev/null @@ -1,9 +0,0 @@ -# Changelog - -## 09/02/2021 `v0.1.0` - -- Initial Commit for web app - -## 10/02/2021 `v0.1.1` - -- GraphQL support added! diff --git a/database/courses.go b/database/courses.go deleted file mode 100644 index c2cdb6a..0000000 --- a/database/courses.go +++ /dev/null @@ -1,38 +0,0 @@ -package database - -import ( - "context" - "log" - - "github.com/spf13/viper" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" -) - -func ConnectCoursesDB() *mongo.Database { - // err := mgm.SetDefaultConfig(nil, "primary", options.Client().ApplyURI("mongodb+srv://anc:courses@primary.hsesw.mongodb.net/primarydb?retryWrites=true&w=majority")) - // if err != nil { - print(12) - // } - clientOptions := options.Client().ApplyURI(viper.GetString("mongo.courses")) - - // Connect to MongoDB - client, err := mongo.Connect(context.TODO(), clientOptions) - - if err != nil { - print(err.Error()) - } - - err = client.Ping(context.TODO(), nil) - - if err != nil { - print(err.Error()) - } - - log.Printf("Connected to MongoDB!") - database := client.Database("primarydb") - return database -} - -// AdminCollection sadsd -// var MongoClient = connect() diff --git a/database/mongo.go b/database/mongo.go index d0a141d..ec2643f 100644 --- a/database/mongo.go +++ b/database/mongo.go @@ -1,13 +1,39 @@ package database -import "go.mongodb.org/mongo-driver/mongo" +import ( + "context" + "log" + + "github.com/spf13/viper" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" +) type mongoClient struct { Users *mongo.Database Courses *mongo.Database } -var usersClient = ConnectUsersDB() -var coursesClinet = ConnectCoursesDB() +// MongoClient ... +var MongoClient = &mongoClient{} + +// ConnectMongo .. +func ConnectMongo() { + MongoClient.Users = connect(viper.GetString("mongo.users"), "primarydb") + MongoClient.Courses = connect(viper.GetString("mongo.courses"), "students") +} -var MongoClient = &mongoClient{Users: usersClient, Courses: coursesClinet} +func connect(url string, dbname string) *mongo.Database { + clientOptions := options.Client().ApplyURI(url) + client, err := mongo.Connect(context.TODO(), clientOptions) + if err != nil { + log.Fatalf("Unable to Connect to MongoDB %v", err) + } + err = client.Ping(context.TODO(), nil) + if err != nil { + log.Fatalf("Unable to Connect to MongoDB %v", err) + } + log.Printf("Connected to MongoDB! URL : %s", url) + database := client.Database(dbname) + return database +} diff --git a/database/users.go b/database/users.go deleted file mode 100644 index 6f98881..0000000 --- a/database/users.go +++ /dev/null @@ -1,37 +0,0 @@ -package database - -import ( - "context" - "log" - - "github.com/spf13/viper" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" -) - -func ConnectUsersDB() *mongo.Database { - // err := mgm.SetDefaultConfig(nil, "primary", options.Client().ApplyURI("mongodb+srv://anc:courses@primary.hsesw.mongodb.net/primarydb?retryWrites=true&w=majority")) - // if err != nil { - print(12) - // } - clientOptions := options.Client().ApplyURI(viper.GetString("mongo.users")) - - // Connect to MongoDB - client, err := mongo.Connect(context.TODO(), clientOptions) - - if err != nil { - print(err.Error()) - } - - err = client.Ping(context.TODO(), nil) - - if err != nil { - print(err.Error()) - } - - log.Printf("Connected to MongoDB!") - database := client.Database("primarydb") - return database -} - -// AdminCollection sadsd diff --git a/go.mod b/go.mod index 1fcd1f8..3a97746 100644 --- a/go.mod +++ b/go.mod @@ -17,10 +17,8 @@ require ( github.com/go-redis/redis v6.15.9+incompatible github.com/gofiber/fiber/v2 v2.5.0 github.com/google/uuid v1.2.0 // indirect - github.com/hookactions/gqlgen-relay v0.0.0-20190817160925-716890b1c3b1 // indirect github.com/klauspost/compress v1.11.8 // indirect github.com/magiconair/properties v1.8.4 // indirect - github.com/ory/keto-client-go v0.5.2 github.com/ory/kratos-client-go v0.5.4-alpha.1 github.com/pelletier/go-toml v1.8.1 // indirect github.com/spf13/afero v1.5.1 // indirect @@ -33,7 +31,7 @@ require ( github.com/xdg/stringprep v1.0.0 // indirect go.mongodb.org/mongo-driver v1.4.6 go.opencensus.io v0.23.0 // indirect - golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 + golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93 google.golang.org/api v0.40.0 google.golang.org/genproto v0.0.0-20210226172003-ab064af71705 // indirect diff --git a/go.sum b/go.sum index c5df18d..ab3d01d 100644 --- a/go.sum +++ b/go.sum @@ -183,7 +183,6 @@ github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQH github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= -github.com/go-openapi/errors v0.19.4/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= github.com/go-openapi/errors v0.19.6/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.19.7/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.19.8 h1:doM+tQdZbUm9gydV9yR+iQNmztbjj7I3sW4sIcAwIzc= @@ -210,7 +209,6 @@ github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= github.com/go-openapi/loads v0.19.3/go.mod h1:YVfqhUCdahYwR3f3iiwQLhicVRvLlU/WO5WPaZvcvSI= -github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk= github.com/go-openapi/loads v0.19.5 h1:jZVYWawIQiA1NBnHla28ktg6hrcfTHsCE+3QLVRBIls= github.com/go-openapi/loads v0.19.5/go.mod h1:dswLCAdonkRufe/gSUC3gN8nTSaB9uaS2es0x5/IbjY= github.com/go-openapi/loads v0.19.6/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= @@ -257,7 +255,6 @@ github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/ 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.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= -github.com/go-openapi/swag v0.19.8/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= github.com/go-openapi/swag v0.19.11 h1:RFTu/dlFySpyVvJDfp/7674JY4SDglYWKztbiIGFpmc= github.com/go-openapi/swag v0.19.11/go.mod h1:Uc0gKkdR+ojzsEpjh39QChyu92vPgIr72POcgHMAgSY= @@ -268,7 +265,6 @@ github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/ github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo= -github.com/go-openapi/validate v0.19.7/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= github.com/go-openapi/validate v0.19.10/go.mod h1:RKEZTUWDkxKQxN2jDT7ZnZi2bhZlbNMAuKvKB+IaGx8= github.com/go-openapi/validate v0.19.12 h1:mPLM/bfbd00PGOCJlU0yJL7IulkZ+q9VjPv7U11RMQQ= github.com/go-openapi/validate v0.19.12/go.mod h1:Rzou8hA/CBw8donlS6WNEUQupNvUZ0waH08tGe6kAQ4= @@ -429,8 +425,6 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hookactions/gqlgen-relay v0.0.0-20190817160925-716890b1c3b1 h1:KZ/Eetid/Qc801mOzWJDKonnKPDDbwKfgoUwizIhN8M= -github.com/hookactions/gqlgen-relay v0.0.0-20190817160925-716890b1c3b1/go.mod h1:Ps2LU6vMq/DVD8LAyC/RhKqm9t/nzanhV7CCnPnAWsw= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= @@ -445,7 +439,6 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw 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/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/joncalhoun/pipe v0.0.0-20170510025636-72505674a733/go.mod h1:2MNFZhLx2HMHTN4xKH6FhpoQWqmD8Ato8QOE2hp5hY4= 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/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -494,7 +487,6 @@ github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN 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.1 h1:mdxE1MF9o53iCb2Ghj1VfWvh7ZOwHpnVG/xwXrV90U8= github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= @@ -561,8 +553,6 @@ github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxS github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/ory/keto-client-go v0.5.2 h1:+kcT3nQ3pLzpbkeUDVbQj8p/zkJw+LVxX2awGB8AySY= -github.com/ory/keto-client-go v0.5.2/go.mod h1:m2TXLKtOsM6oE1E8G5phy41M6AfmWZUdoqHocuBXBZE= github.com/ory/kratos-client-go v0.5.4-alpha.1 h1:GHfgWVYqJwYj7aitzLOpy8aiTfywb/GjOVJc3AUuQmI= github.com/ory/kratos-client-go v0.5.4-alpha.1/go.mod h1:ADRXFi+QG6oLIXmYCRVoxJvuFA/hms9I2GdZyU0Nf4o= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= @@ -727,7 +717,6 @@ go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= go.mongodb.org/mongo-driver v1.4.2 h1:WlnEglfTg/PfPq4WXs2Vkl/5ICC6hoG8+r+LraPmGk4= diff --git a/googleapis/client.go b/googleapis/client.go deleted file mode 100644 index 50910be..0000000 --- a/googleapis/client.go +++ /dev/null @@ -1,71 +0,0 @@ -package googleapis - -import ( - "bytes" - "encoding/json" - "io/ioutil" - "log" - "net/http" - "os" - - "github.com/gofiber/fiber/v2" - "golang.org/x/net/context" - "golang.org/x/oauth2" - "golang.org/x/oauth2/google" - "google.golang.org/api/drive/v3" -) - -// Retrieve a token, saves the token, then returns the generated client. -func getClient(config *oauth2.Config) *http.Client { - // The file token.json stores the user's access and refresh tokens, and is - // created automatically when the authorization flow completes for the first - // time. - tokFile := ".secrets/token.json" - tok, err := tokenFromFile(tokFile) - if err != nil { - log.Panic("Unable to to parse Json file") - } - oldToken, err := json.Marshal(fiber.Map{"client_id": config.ClientID, "client_secret": config.ClientSecret, "refresh_token": tok.RefreshToken, "grant_type": "refresh_token"}) - if err != nil { - log.Panic("Unable to to parse Json file") - } - r, err := http.Post("https://accounts.google.com/o/oauth2/token", "application/json", bytes.NewBuffer(oldToken)) - if err != nil { - log.Panic("Unable to to parse Json file") - } - newToken := &oauth2.Token{} - defer r.Body.Close() - json.NewDecoder(r.Body).Decode(newToken) - return config.Client(context.Background(), newToken) -} - -// Retrieves a token from a local file. -func tokenFromFile(file string) (*oauth2.Token, error) { - f, err := os.Open(file) - if err != nil { - return nil, err - } - defer f.Close() - tok := &oauth2.Token{} - err = json.NewDecoder(f).Decode(tok) - return tok, err -} - -func GetService() *DriveClient { - b, err := ioutil.ReadFile(".secrets/credentials.json") - if err != nil { - log.Fatalf("Unable to read client secret file: %v", err) - } - - // If modifying these scopes, delete your previously saved token.json. - config, err := google.ConfigFromJSON(b, drive.DriveMetadataReadonlyScope) - if err != nil { - log.Fatalf("Unable to parse client secret file to config: %v", err) - } - client := getClient(config) - srv, err := drive.New(client) - if err != nil { - log.Fatalf("Unable to retrieve Drive client: %v", err) - } - return &DriveClient{srv} -} diff --git a/googleapis/drive.go b/googleapis/drive.go deleted file mode 100644 index e36024f..0000000 --- a/googleapis/drive.go +++ /dev/null @@ -1,48 +0,0 @@ -package googleapis - -import ( - "log" - "mime/multipart" - - "github.com/Mshivam2409/AnC-Courses/models" - "google.golang.org/api/drive/v3" -) - -// DriveClient hg -type DriveClient struct { - *drive.Service -} - -// CreateFile Creates a file in google drive and return the file id and filename -func (srv *DriveClient) CreateFile(folderID string, file *multipart.FileHeader) (models.File, error) { - f, err := file.Open() - if err != nil { - log.Printf("Unable to upload file! %v", err) - return models.File{}, err - } - driveFile, err := srv.Files.Create(&drive.File{Name: file.Filename, Parents: []string{folderID}}).Media(f).Do() - if err != nil { - log.Printf("Unable to upload file! %v", err) - return models.File{}, err - } - return models.File{ID: driveFile.DriveId, Name: file.Filename}, err -} - -// CreateFolder Creates a folder in google drive -func (srv *DriveClient) CreateFolder(folderName string) (string, error) { - folder, err := srv.Files.Create(&drive.File{MimeType: "application/vnd.google-apps.folder", Name: folderName}).Do() - log.Printf("Folder with id %v created", folder.Id) - if err != nil { - log.Printf("Unable to create folder: %v", err) - } - return folder.Id, err -} - -// DeleteFile deletes -func (srv *DriveClient) DeleteFile(fileID string) error { - err := srv.Files.Delete(fileID).Do() - if err != nil { - log.Printf("Unable to delete file! : %v"+"File ID:"+fileID, err) - } - return err -} diff --git a/graph/schema.resolvers.go b/graph/schema.resolvers.go index aeef5e7..a1aa9d0 100644 --- a/graph/schema.resolvers.go +++ b/graph/schema.resolvers.go @@ -9,9 +9,9 @@ import ( "log" "github.com/Mshivam2409/AnC-Courses/database" - "github.com/Mshivam2409/AnC-Courses/googleapis" "github.com/Mshivam2409/AnC-Courses/graph/generated" "github.com/Mshivam2409/AnC-Courses/models" + "github.com/Mshivam2409/AnC-Courses/services" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" @@ -26,7 +26,7 @@ func (r *mutationResolver) AddCourse(ctx context.Context, course models.NewCours // if !a { // return &models.Response{Ok: false, Message: "Unauthorzed"}, err // } - d := googleapis.GetService() + d := services.GetService() fid, err := d.CreateFolder(course.Number) log.Println(fid) if err != nil { diff --git a/main.go b/main.go index b5f9208..f92d018 100644 --- a/main.go +++ b/main.go @@ -2,8 +2,11 @@ package main import ( "fmt" + "log" - "github.com/Mshivam2409/AnC-Courses/router" + "github.com/Mshivam2409/AnC-Courses/api" + "github.com/Mshivam2409/AnC-Courses/database" + "github.com/Mshivam2409/AnC-Courses/services" "github.com/spf13/viper" "github.com/ansrivas/fiberprometheus/v2" @@ -12,48 +15,44 @@ import ( "github.com/gofiber/fiber/v2/middleware/recover" ) +func init() { + viper.AddConfigPath(".") + viper.AddConfigPath("/etc/config/fiber/") + viper.SetConfigName("config") + viper.SetConfigType("yaml") + err := viper.ReadInConfig() + if err != nil { + log.Panicf("Fatal error config file: %s", err) + } + database.ConnectMongo() + services.InitalizeOryServices() +} + func main() { - // Create a new fiber instance with custom config + print(9) app := fiber.New(fiber.Config{ - // Override default error handler ErrorHandler: func(ctx *fiber.Ctx, err error) error { - // Statuscode defaults to 500 code := fiber.StatusInternalServerError message := "Internal Server Error" - // Retreive the custom statuscode if it's an fiber.*Error if e, ok := err.(*fiber.Error); ok { code = e.Code message = e.Message } - - // Send custom error page err = ctx.Status(code).JSON(fiber.Map{"message": message}) if err != nil { - // In case the SendFile fails return ctx.Status(500).SendString("Internal Server Error") } - - // Return from handler return nil }, }) app.Use(cors.New(cors.Config{AllowOrigins: "*"})) app.Use(recover.New()) - prometheus := fiberprometheus.New("my-service-name") + prometheus := fiberprometheus.New("fiber") prometheus.RegisterAt(app, "/metrics") app.Use(prometheus.Middleware) - viper.AddConfigPath(".") - viper.AddConfigPath("/etc/config/fiber/") - viper.SetConfigName("config") - viper.SetConfigType("yml") - err := viper.ReadInConfig() // Find and read the config file - if err != nil { // Handle errors reading the config file - panic(fmt.Errorf("Fatal error config file: %s", err)) - } - router.SetupRoutes(app) - fmt.Print(viper.GetString("mongo.users")) + api.SetupRoutes(app) app.Static("/", "html") - err = app.Listen(":5000") + err := app.Listen(":5000") if err != nil { fmt.Print(err) } diff --git a/models/user.go b/models/user.go index 1cf8595..4e2df5d 100644 --- a/models/user.go +++ b/models/user.go @@ -8,4 +8,5 @@ type MGMUser struct { Clearance int `bson:"clearance"` Banned bool `bson:"banned"` RollNo string `bson:"rollno"` + KratosID string `bson:"kid"` } diff --git a/services/drive.go b/services/drive.go index 1a61a81..4973beb 100644 --- a/services/drive.go +++ b/services/drive.go @@ -1,47 +1,119 @@ package services import ( + "bytes" "context" "encoding/json" - "fmt" - "strconv" + "io" + "io/ioutil" + "log" + "mime/multipart" + "net/http" + "os" - "github.com/Mshivam2409/AnC-Courses/database" - "github.com/Mshivam2409/AnC-Courses/googleapis" "github.com/Mshivam2409/AnC-Courses/models" "github.com/gofiber/fiber/v2" - "go.mongodb.org/mongo-driver/bson" + "golang.org/x/oauth2" + "golang.org/x/oauth2/google" + "google.golang.org/api/drive/v3" ) -// CreateFile sdfs -func CreateFile(c *fiber.Ctx) error { - d := googleapis.GetService() - n, err := strconv.Atoi(c.FormValue("length")) - cno := c.FormValue("course") - if err != nil { - return &fiber.Error{Code: 422, Message: "Length of files must be a number"} - } - files := []string{} - for i := 0; i < n; i++ { - f, err := c.FormFile("file" + fmt.Sprint(n)) - if err != nil { - return &fiber.Error{Code: 422, Message: "Unable to process file!"} - } - r, err := d.CreateFile("", f) - if err != nil { - return &fiber.Error{Code: 422, Message: "Unable to upload file!"} - } - out, err := json.Marshal(r) - if err != nil { - return &fiber.Error{Code: 422, Message: "Unable to get file ID!"} - } - files = append(files, string(out)) - } - update := bson.D{ - {Key: "$push", Value: bson.D{ - {Key: "driveFiles", Value: bson.A{"$each", files}}, - }}, - } - err = database.MongoClient.Courses.Collection("courses").FindOneAndUpdate(context.TODO(), bson.D{{Key: "number", Value: cno}}, update).Decode(&models.MGMCourse{}) - return c.Status(200).JSON(fiber.Map{"message": "success"}) +// DriveClient : Helper struct for Google Drive Service +type DriveClient struct { + *drive.Service +} + +// Retrieve a token, saves the token, then returns the generated client. +func getClient(config *oauth2.Config) *http.Client { + tokFile := ".secrets/token.json" + tok, err := tokenFromFile(tokFile) + if err != nil { + log.Panic("Unable to to parse Json file") + } + oldToken, err := json.Marshal(fiber.Map{"client_id": config.ClientID, "client_secret": config.ClientSecret, "refresh_token": tok.RefreshToken, "grant_type": "refresh_token"}) + if err != nil { + log.Panic("Unable to to parse Json file") + } + r, err := http.Post("https://accounts.google.com/o/oauth2/token", "application/json", bytes.NewBuffer(oldToken)) + if err != nil { + log.Panic("Unable to to parse Json file") + } + newToken := &oauth2.Token{} + defer r.Body.Close() + json.NewDecoder(r.Body).Decode(newToken) + return config.Client(context.Background(), newToken) +} + +// Retrieves a token from a local file. +func tokenFromFile(file string) (*oauth2.Token, error) { + f, err := os.Open(file) + if err != nil { + return nil, err + } + defer f.Close() + tok := &oauth2.Token{} + err = json.NewDecoder(f).Decode(tok) + return tok, err +} + +// GetService : Connect to GoogleAPI and return the client +func GetService() *DriveClient { + b, err := ioutil.ReadFile(".secrets/credentials.json") + if err != nil { + log.Printf("Unable to read client secret file: %v", err) + } + config, err := google.ConfigFromJSON(b, drive.DriveMetadataReadonlyScope) + if err != nil { + log.Printf("Unable to parse client secret file to config: %v", err) + } + client := getClient(config) + srv, err := drive.New(client) + if err != nil { + log.Printf("Unable to retrieve Drive client: %v", err) + } + return &DriveClient{srv} +} + +// CreateFile : Creates a file in google drive and return the file id and filename +func (srv *DriveClient) CreateFile(folderID string, file *multipart.FileHeader) (models.File, error) { + f, err := file.Open() + if err != nil { + log.Printf("Unable to upload file! %v", err) + return models.File{}, err + } + driveFile, err := srv.Files.Create(&drive.File{Name: file.Filename, Parents: []string{folderID}}).Media(f).Do() + if err != nil { + log.Printf("Unable to upload file! %v", err) + return models.File{}, err + } + return models.File{ID: driveFile.DriveId, Name: file.Filename}, err +} + +// CreateFolder : Creates a folder in google drive +func (srv *DriveClient) CreateFolder(folderName string) (string, error) { + folder, err := srv.Files.Create(&drive.File{MimeType: "application/vnd.google-apps.folder", Name: folderName}).Do() + log.Printf("Folder with id %v created", folder.Id) + if err != nil { + log.Printf("Unable to create folder: %v", err) + } + return folder.Id, err +} + +// DeleteFile : Deletes a file with the given ID +func (srv *DriveClient) DeleteFile(fileID string) error { + err := srv.Files.Delete(fileID).Do() + if err != nil { + log.Printf("Unable to delete file! : %v"+"File ID:"+fileID, err) + } + return err +} + +// GetFile : Downloads a file with the given ID. +func (srv *DriveClient) GetFile(fileID string) (io.Reader, error) { + f, err := srv.Files.Get(fileID).Download() + a := io.Reader(f.Body) + if err != nil { + log.Printf("Unable to delete file! : %v"+"File ID:"+fileID, err) + } + return a, err } diff --git a/services/keto.go b/services/keto.go deleted file mode 100644 index f1ccbd0..0000000 --- a/services/keto.go +++ /dev/null @@ -1,43 +0,0 @@ -package services - -import ( - "fmt" - - "github.com/ory/keto-client-go/client/engines" - "github.com/ory/keto-client-go/models" - "github.com/spf13/viper" - "gopkg.in/square/go-jose.v2/jwt" -) - -// IsAuthorized chec -func (ory *Ory) IsAuthorized(tokenString string, action string, resource string) (bool, error) { - var claims map[string]interface{} // generic map to store parsed token - // decode JWT token without verifying the signature - token, err := jwt.ParseSigned(tokenString) - if err != nil { - return false, err - } - err = token.UnsafeClaimsWithoutVerification(&claims) - if err != nil { - return false, err - } - r, err := ory.OryKeto.Engines.DoOryAccessControlPoliciesAllow(&engines.DoOryAccessControlPoliciesAllowParams{Body: &models.OryAccessControlPolicyAllowedInput{ - Action: action, - Subject: fmt.Sprintf("%v", claims["subject"]), - Resource: resource, - }, Flavor: "exact"}) - if err != nil { - return false, err - } - return *r.Payload.Allowed, err -} - -func (ory *Ory) ElevateUser(email string, role string) error { - _, err := ory.OryKeto.Engines.AddOryAccessControlPolicyRoleMembers(&engines.AddOryAccessControlPolicyRoleMembersParams{Body: &models.AddOryAccessControlPolicyRoleMembersBody{Members: []string{email}}, Flavor: "exact", ID: viper.GetString("sdf")}) - return err -} - -func (ory *Ory) DelegateUser(email string, role string) error { - _, err := ory.OryKeto.Engines.RemoveOryAccessControlPolicyRoleMembers(&engines.RemoveOryAccessControlPolicyRoleMembersParams{Member: email, Flavor: "exact", ID: viper.GetString("sdf")}) - return err -} diff --git a/services/kratos.go b/services/kratos.go deleted file mode 100644 index 4cd89d5..0000000 --- a/services/kratos.go +++ /dev/null @@ -1,27 +0,0 @@ -package services - -import ( - "fmt" - - "github.com/gofiber/fiber/v2" - "github.com/ory/kratos-client-go/client/admin" - kratosmodels "github.com/ory/kratos-client-go/models" - "github.com/spf13/viper" -) - -// CreateUser sdfsd -func (ory *Ory) CreateUser(email string) error { - schema := viper.GetString("vasd") - i, err := ory.OryKratos.Admin.CreateIdentity(&admin.CreateIdentityParams{Body: &kratosmodels.CreateIdentity{SchemaID: &schema, Traits: fiber.Map{"email": email}}}) - id := i.GetPayload().ID - link, err := ory.OryKratos.Admin.CreateRecoveryLink(&admin.CreateRecoveryLinkParams{Body: &kratosmodels.CreateRecoveryLink{IdentityID: id}}) - fmt.Print(link.Payload.RecoveryLink) - ory.ElevateUser(email, "user") - return err -} - -// DeleteUser : adas -func (ory *Ory) DeleteUser(id string) error { - _, err := ory.OryKratos.Admin.DeleteIdentity(&admin.DeleteIdentityParams{ID: id}) - return err -} diff --git a/services/mail.go b/services/mail.go index b8e775a..c29d7ba 100644 --- a/services/mail.go +++ b/services/mail.go @@ -3,26 +3,25 @@ package services import ( "log" "net/smtp" + + "github.com/spf13/viper" ) -func SendMail(body string) { - from := "...@gmail.com" - pass := "..." - to := "foobarbazz@mailinator.com" +func SendMail(link string, to string) error { - msg := "From: " + from + "\n" + + msg := "From: " + viper.GetString("mail.from") + "\n" + "To: " + to + "\n" + - "Subject: Hello there\n\n" + - body + "Subject: Account Recovery\n\n" + + "Dear User,\nPlease use the following link to recover your account:\n" + link err := smtp.SendMail("smtp.gmail.com:587", - smtp.PlainAuth("", from, pass, "smtp.gmail.com"), - from, []string{to}, []byte(msg)) + smtp.PlainAuth("", viper.GetString("mail.id"), viper.GetString("mail.pwd"), "smtp.gmail.com"), + viper.GetString("mail.from"), []string{to}, []byte(msg)) if err != nil { log.Printf("smtp error: %s", err) - return + return err } - log.Print("sent, visit http://foobarbazz.mailinator.com") + return nil } diff --git a/services/ory.go b/services/ory.go index eba917b..0dc9ed6 100644 --- a/services/ory.go +++ b/services/ory.go @@ -1,27 +1,125 @@ package services import ( - keto "github.com/ory/keto-client-go/client" + "context" + "fmt" + "log" + + "github.com/Mshivam2409/AnC-Courses/database" + "github.com/Mshivam2409/AnC-Courses/models" + "github.com/gofiber/fiber/v2" kratos "github.com/ory/kratos-client-go/client" + "github.com/ory/kratos-client-go/client/admin" + kratosmodels "github.com/ory/kratos-client-go/models" + "github.com/spf13/viper" + "go.mongodb.org/mongo-driver/bson" + "gopkg.in/square/go-jose.v2/jwt" ) type Ory struct { *kratos.OryKratos - *keto.OryKeto } -func InitalizeOryServices() *Ory { - kr := kratos.NewHTTPClientWithConfig(nil, &kratos.TransportConfig{ - Host: "127.0.0.1:4434", - BasePath: "/", - Schemes: []string{"http"}, - }) - kt := keto.NewHTTPClientWithConfig(nil, &keto.TransportConfig{ - Host: "127.0.0.1:4456", +var OryClient = &Ory{} + +func InitalizeOryServices() { + OryClient.OryKratos = kratos.NewHTTPClientWithConfig(nil, &kratos.TransportConfig{ + Host: viper.GetString("kratos.admin_url"), BasePath: "/", Schemes: []string{"http"}, }) - return &Ory{kr, kt} } -var OryClient = InitalizeOryServices() +// CLEARANCE : Clearance levels required for access +var CLEARANCE = map[string]int{ + "REGISTER": 1, + "READ_COURSE_DATA": 1, + "ADD_COURSE": 2, + "ADD_REVIEW": 1, + "GOOGLE_DRIVE": 2, + "TOGGLE_REVIEW": 2, + "ELEVATE_USER": 3, + "DEMOTE_USER": 3, +} + +// IsAuthorized Checks access for a given resource +func (ory *Ory) IsAuthorized(tokenString string, resource string) (bool, error) { + var claims map[string]interface{} + token, err := jwt.ParseSigned(tokenString) + if err != nil { + return false, err + } + err = token.UnsafeClaimsWithoutVerification(&claims) + if err != nil { + return false, err + } + u := &models.MGMUser{} + filter := bson.D{{Key: "username", Value: claims["username"]}} + err = database.MongoClient.Users.Collection("ug").FindOne(context.TODO(), filter).Decode(u) + if err != nil { + log.Printf("Unable to check access : %v", err) + } + if u.Clearance >= CLEARANCE[resource] { + return true, err + } + + return false, err +} + +func (ory *Ory) CanRegister(username string) (bool, error) { + u := &models.MGMUser{} + // filte/r := bson.D{{Key: "username", Value: username}} + err := database.MongoClient.Users.Collection("ug").FindOne(context.TODO(), bson.D{}).Decode(u) + if err != nil { + log.Printf("Unable to check access for %s : %v", username, err) + } + if u.Clearance >= CLEARANCE["REGISTER"] { + return true, err + } + + return false, err +} + +func (ory *Ory) SetKratosID(kid string, username string) error { + u := &models.MGMUser{} + filter := bson.D{{Key: "username", Value: username}} + update := bson.D{{Key: "$set", Value: bson.D{{Key: "kid", Value: kid}}}} + fmt.Println(kid, 11) + err := database.MongoClient.Users.Collection("ug").FindOneAndUpdate(context.TODO(), filter, update).Decode(u) + if err != nil { + log.Printf("Unable to check access : %v", err) + } + return err +} + +// CreateUser sdfsd +func (ory *Ory) CreateUser(username string) error { + ok, err := ory.CanRegister(username) + if err != nil { + log.Printf("Unable to check regsitration : %v", err) + return fiber.NewError(401, "Error") + } + if !ok { + log.Printf("Unable to check regsitration : %v", err) + return fiber.NewError(401, "Error") + } + i, err := ory.OryKratos.Admin.CreateIdentity(&admin.CreateIdentityParams{Body: &kratosmodels.CreateIdentity{Traits: fiber.Map{"email": username + "@iitk.ac.in"}}, Context: context.TODO()}) + if err != nil { + log.Printf("Unable to check regsitration : %v", err) + return fiber.NewError(401, "Error") + } + id := i.GetPayload().ID + fmt.Print(id) + link, err := ory.OryKratos.Admin.CreateRecoveryLink(&admin.CreateRecoveryLinkParams{Body: &kratosmodels.CreateRecoveryLink{IdentityID: id}, Context: context.TODO()}) + if err != nil { + log.Printf("Unable to check regsitration : %v", err) + } + SendMail(*link.Payload.RecoveryLink, username+"@iitk.ac.in") + ory.SetKratosID(string(id), username) + return err +} + +func (ory *Ory) DeleteUser(id string) error { + _, err := ory.OryKratos.Admin.DeleteIdentity(&admin.DeleteIdentityParams{ID: id}) + return err +} diff --git a/services/redis.go b/services/redis.go index 7041145..70f22df 100644 --- a/services/redis.go +++ b/services/redis.go @@ -17,7 +17,8 @@ const apqPrefix = "apq:" func NewCache(redisAddress string, password string, ttl time.Duration) (*Cache, error) { client := redis.NewClient(&redis.Options{ - Addr: redisAddress, + Addr: redisAddress, + Password: password, }) err := client.Ping().Err()