Make create badge works in both annoymous and logged in mode

This commit is contained in:
2020-09-05 10:26:30 +10:00
parent 478cdf51f4
commit c263cdd381
9 changed files with 94 additions and 23 deletions
+16
View File
@@ -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)
+41 -5
View File
@@ -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
}
+1 -1
View File
@@ -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)
+2 -2
View File
@@ -6,8 +6,8 @@
<b-collapse id="nav-collapse" is-nav>
<b-navbar-nav>
<b-nav-item to="/" exact>
Home
<b-nav-item to="/badges" exact>
Badges
</b-nav-item>
</b-navbar-nav>
<b-navbar-nav class="ml-auto">
+14 -11
View File
@@ -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']
// }
@@ -9,9 +9,9 @@
</b-container>
</div>
</template>
<script lang="ts">
<script>
export default {
middleware: ['auth']
};
</script>
<style lang="scss"></style>
+1 -1
View File
@@ -22,7 +22,7 @@ export default {
this.$store.dispatch("users/logout", () => {
setTimeout(() => {
this.$router.push({ name: "index" });
}, 5000);
}, 3000);
});
}
};
+10
View File
@@ -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;
}
}
});
}
+7 -1
View File
@@ -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();
}