diff --git a/handlers/badges.go b/handlers/badges.go index 4691424..cba5016 100644 --- a/handlers/badges.go +++ b/handlers/badges.go @@ -190,6 +190,18 @@ func (handler *BadgesHandler) queryBadgeFromDB(queryName string) (*models.Badge, return &badge, nil } +// func (handler *BadgesHandler) MyBadges(c *gin.Context) { +// var currentUser *models.User +// userInterface, exists := c.Get("user") +// if !exists { +// logrus.Error("user cannot be found from context") +// c.JSON(http.StatusInternalServerError, gin.H{"msg": ErrorMessageInternalError}) +// return +// } +// currentUser = userInterface.(*models.User) + +// } + func (handler *BadgesHandler) CreateBadge(c *gin.Context) { newID := NewULID() jsonB := new(postgres.Jsonb) @@ -217,6 +229,10 @@ func (handler *BadgesHandler) CreateBadge(c *gin.Context) { Options: jsonB, } + if c.GetBool("loggedIn") { + badge.UserID = c.GetInt("currentUserID") + } + if err = handler.DB.Save(&badge).Error; err != nil { logrus.Error(err.Error()) sentry.CaptureException(err) diff --git a/handlers/users.go b/handlers/users.go index 8e0cfda..6cdff41 100644 --- a/handlers/users.go +++ b/handlers/users.go @@ -19,6 +19,10 @@ const ( githubHTTPTimeout = 10 ) +var ( + NoAuthPaths = []string{"/api/badges", "/api/auth"} +) + type UsersHandler struct { DB *gorm.DB } @@ -34,10 +38,45 @@ type UserAuthenticationRequest struct { } type UserInfo struct { - ID uint `json:"id"` + ID string `json:"id"` GithubID string `json:"githubId"` } +func (usersHandler *UsersHandler) AuthRequired(c *gin.Context) { + authorization := c.GetHeader("Authorization") + uid := c.GetHeader("uid") + var user models.User + if len(authorization) != 0 && len(uid) != 0 { + if err := usersHandler.DB.Preload("Token").First(&user, "ulid = ?", uid).Error; err != nil { + logrus.Warn(err) + sentry.CaptureException(err) + c.AbortWithStatusJSON(http.StatusUnauthorized, GeneralError{"invalid credentials"}) + return + } + if user.Token.Token != authorization[7:] { + c.AbortWithStatusJSON(http.StatusUnauthorized, GeneralError{"invalid credentials"}) + return + } + } + c.Set("currentUser", user) + requestingAuthRequiredPath := true + + for _, noAuthPath := range NoAuthPaths { + if noAuthPath == c.Request.RequestURI { + requestingAuthRequiredPath = false + break + } + } + if requestingAuthRequiredPath && user.ID == 0 { + c.AbortWithStatusJSON(http.StatusUnauthorized, GeneralError{"login required"}) + return + } + if user.ID != 0 { + c.Set("loggedIn", true) + c.Set("currentUserID", int(user.ID)) + } +} + func (usersHandler *UsersHandler) Authenticate(c *gin.Context) { var requestBody UserAuthenticationRequest @@ -85,9 +124,7 @@ func (usersHandler *UsersHandler) Authenticate(c *gin.Context) { c.JSON(http.StatusInternalServerError, GeneralError{"internal error, please try it later"}) return } - - c.JSON(http.StatusOK, UserInfo{ID: user.ID, GithubID: user.GithubID}) - + c.JSON(http.StatusOK, UserInfo{ID: user.ULID, GithubID: user.GithubID}) } func validateUser(token string) bool { @@ -123,6 +160,5 @@ func validateUser(token string) bool { return false } - logrus.Info() return true } diff --git a/main.go b/main.go index 2d2544e..baf61f4 100644 --- a/main.go +++ b/main.go @@ -85,7 +85,7 @@ func main() { r.GET("/badges/:name/:color", handler.GetBadgeWithColorScheme) api := r.Group("/api") - + api.Use(userHandler.AuthRequired) api.POST("/auth", userHandler.Authenticate) api.POST("/badges", handler.CreateBadge) diff --git a/www/layouts/default.vue b/www/layouts/default.vue index 1eb600f..bfd9c72 100644 --- a/www/layouts/default.vue +++ b/www/layouts/default.vue @@ -6,8 +6,8 @@ - - Home + + Badges diff --git a/www/nuxt.config.js b/www/nuxt.config.js index 5039f86..a45ba95 100644 --- a/www/nuxt.config.js +++ b/www/nuxt.config.js @@ -36,7 +36,10 @@ export default { ** Plugins to load before mounting the App ** https://nuxtjs.org/guide/plugins */ - plugins: [{ src: "~plugins/ga.js", mode: "client" }], + plugins: [ + { src: "~plugins/ga.js", mode: "client" }, + { src: "~plugins/axios.js", mode: "client" } + ], /* ** Auto import components ** See https://nuxtjs.org/api/configuration-components @@ -104,33 +107,33 @@ export default { build: {}, auth: { redirect: { - callback: '/callback', - logout: '/signed-out', + callback: "/callback", + logout: "/signed-out" }, strategies: { github: { - clientId: 'e5f10ed97cf95f71c5b7', - clientSecret: '8543545533ca899c8d9b40b89c3685202c8eb683' + clientId: "e5f10ed97cf95f71c5b7", + clientSecret: "8543545533ca899c8d9b40b89c3685202c8eb683" }, local: { token: { - property: 'token.accessToken' + property: "token.accessToken" } }, localRefresh: { - scheme: 'refresh', + scheme: "refresh", token: { - property: 'token.accessToken', + property: "token.accessToken", maxAge: 15 }, refreshToken: { - property: 'token.refreshToken', - data: 'refreshToken', + property: "token.refreshToken", + data: "refreshToken", maxAge: false } } } - }, + } // router: { // middleware: ['auth'] // } diff --git a/www/pages/badge/index.vue b/www/pages/badges/index.vue similarity index 88% rename from www/pages/badge/index.vue rename to www/pages/badges/index.vue index b05f701..99601a6 100644 --- a/www/pages/badge/index.vue +++ b/www/pages/badges/index.vue @@ -9,9 +9,9 @@ - diff --git a/www/pages/signed-out.vue b/www/pages/signed-out.vue index 67f59e8..f31aeef 100644 --- a/www/pages/signed-out.vue +++ b/www/pages/signed-out.vue @@ -22,7 +22,7 @@ export default { this.$store.dispatch("users/logout", () => { setTimeout(() => { this.$router.push({ name: "index" }); - }, 5000); + }, 3000); }); } }; diff --git a/www/plugins/axios.js b/www/plugins/axios.js new file mode 100644 index 0000000..574e1a5 --- /dev/null +++ b/www/plugins/axios.js @@ -0,0 +1,10 @@ +export default function({ $axios, store }) { + $axios.onRequest(config => { + if (config.url.startsWith("/api") && config.url !== "/api/auth") { + if (store.state.auth.loggedIn) { + config.headers.common["Authorization"] = store.state.users.token; + config.headers.common["uid"] = store.state.users.currentUser.id; + } + } + }); +} diff --git a/www/store/users.js b/www/store/users.js index 25979af..490f6b3 100644 --- a/www/store/users.js +++ b/www/store/users.js @@ -1,10 +1,14 @@ export const state = () => ({ - currentUser: {} + currentUser: {}, + token: "" }); export const mutations = { updateUser(state, user) { state.currentUser = user; + }, + updateToken(state, token) { + state.token = token; } }; @@ -12,6 +16,7 @@ export const actions = { async authenticate(context, requestBody, callback) { const result = await this.$axios.$post("/api/auth", requestBody); context.commit("updateUser", result); + context.commit("updateToken", requestBody.token); if (!!callback && typeof callback === "function") { callback(); @@ -19,6 +24,7 @@ export const actions = { }, logout(context, callback) { context.commit("updateUser", {}); + context.commit("updateToken", ""); if (!!callback && typeof callback === "function") { callback(); }