Skip to content

Commit

Permalink
Protected user methods
Browse files Browse the repository at this point in the history
Need to have rights to be able to add/invite/delete/update user informations
  • Loading branch information
titouanfreville committed Mar 8, 2017
1 parent 74130f9 commit 1e67090
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 72 deletions.
198 changes: 132 additions & 66 deletions api/user_route.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import (
"net/http"
"strconv"

"log"

jwt "github.com/dgrijalva/jwt-go"
"github.com/pressly/chi"
chiRender "github.com/pressly/chi/render"
"github.com/titouanfreville/popcubeapi/datastores"
Expand Down Expand Up @@ -241,79 +244,114 @@ func userContext(next http.Handler) http.Handler {
})
}

func getAllUser(w http.ResponseWriter, r *http.Request) {
func canManageUser(place string, token *jwt.Token) bool {
store := datastores.Store()
db := dbStore.db
userName := token.Claims.(jwt.MapClaims)["name"].(string)
user := store.User().GetByUserName(userName, db)
userRights := store.Role().GetByID(user.IDRole, db)
if place == "organisation" || place == "global" {
haveGlobalManageRight, ok := token.Claims.(jwt.MapClaims)["canManageUser"].(bool)
log.Print(haveGlobalManageRight)
return (ok && haveGlobalManageRight) || userRights.CanManageUser
}
chanel := store.Channel().GetByName(place, db)
member := store.Member().GetChannelMember(&user, &chanel, db)
channelRights := store.Role().GetByID(member.IDRole, db)
return channelRights.CanManageUser
}

func getAllUser(w http.ResponseWriter, r *http.Request) {
store := datastores.Store()
db := dbStore.db
if err := db.DB().Ping(); err == nil {
result := store.User().GetAll(db)
render.JSON(w, 200, result)
} else {
if err := db.DB().Ping(); err != nil {
render.JSON(w, error503.StatusCode, error503)
return
}
result := store.User().GetAll(db)
render.JSON(w, 200, result)

}

func getDeletedUser(w http.ResponseWriter, r *http.Request) {
store := datastores.Store()

db := dbStore.db
if err := db.DB().Ping(); err == nil {
result := store.User().GetDeleted(db)
render.JSON(w, 200, result)
} else {
if err := db.DB().Ping(); err != nil {
render.JSON(w, error503.StatusCode, error503)
return
}
result := store.User().GetDeleted(db)
render.JSON(w, 200, result)

}

func getUserFromName(w http.ResponseWriter, r *http.Request) {
store := datastores.Store()

db := dbStore.db
if err := db.DB().Ping(); err != nil {
render.JSON(w, error503.StatusCode, error503)
return
}
name := r.Context().Value("userName").(string)
user := store.User().GetByUserName(name, db)
render.JSON(w, 200, user)
}

func getUserFromNickName(w http.ResponseWriter, r *http.Request) {
store := datastores.Store()

db := dbStore.db
if err := db.DB().Ping(); err != nil {
render.JSON(w, error503.StatusCode, error503)
return
}
name := r.Context().Value(nickNameKey).(string)
user := store.User().GetByNickName(name, db)
render.JSON(w, 200, user)
}

func getUserFromFirstName(w http.ResponseWriter, r *http.Request) {
store := datastores.Store()

db := dbStore.db
if err := db.DB().Ping(); err != nil {
render.JSON(w, error503.StatusCode, error503)
return
}
name := r.Context().Value(firstNameKey).(string)
user := store.User().GetByFirstName(name, db)
render.JSON(w, 200, user)
}

func getUserFromLastName(w http.ResponseWriter, r *http.Request) {
store := datastores.Store()

db := dbStore.db
if err := db.DB().Ping(); err != nil {
render.JSON(w, error503.StatusCode, error503)
return
}
name := r.Context().Value(lastNameKey).(string)
user := store.User().GetByLastName(name, db)
render.JSON(w, 200, user)
}

func getUserFromEmail(w http.ResponseWriter, r *http.Request) {
store := datastores.Store()

db := dbStore.db
if err := db.DB().Ping(); err != nil {
render.JSON(w, error503.StatusCode, error503)
return
}
email := r.Context().Value(userEmailKey).(string)
user := store.User().GetByEmail(email, db)
render.JSON(w, 200, user)
}

func getOrderedByDate(w http.ResponseWriter, r *http.Request) {
store := datastores.Store()

db := dbStore.db
if err := db.DB().Ping(); err != nil {
render.JSON(w, error503.StatusCode, error503)
return
}
date := r.Context().Value(userDateKey).(int)
user := store.User().GetOrderedByDate(date, db)
render.JSON(w, 200, user)
Expand All @@ -325,20 +363,19 @@ func getUserFromRole(w http.ResponseWriter, r *http.Request) {
OmitID interface{} `json:"id,omitempty"`
}
store := datastores.Store()

db := dbStore.db
request := r.Body
err := chiRender.Bind(request, &data)
if err != nil || data.Role == nil {
render.JSON(w, error422.StatusCode, error422)
} else {
if err := db.DB().Ping(); err == nil {
role := store.User().GetByRole(data.Role, db)
render.JSON(w, 200, role)
} else {
render.JSON(w, error503.StatusCode, error503)
}
return
}
if err := db.DB().Ping(); err != nil {
render.JSON(w, error503.StatusCode, error503)
return
}
role := store.User().GetByRole(data.Role, db)
render.JSON(w, 200, role)
}

func newUser(w http.ResponseWriter, r *http.Request) {
Expand All @@ -347,24 +384,30 @@ func newUser(w http.ResponseWriter, r *http.Request) {
OmitID interface{} `json:"id,omitempty"`
}
store := datastores.Store()

if !canManageUser("global", r.Context().Value(jwtTokenKey).(*jwt.Token)) {
res := error401
res.Message = "You don't have the right to manage user."
render.JSON(w, error401.StatusCode, error401)
return
}
db := dbStore.db
request := r.Body
err := chiRender.Bind(request, &data)
if err != nil || data.User == nil {
render.JSON(w, error422.StatusCode, error422)
} else {
if err := db.DB().Ping(); err == nil {
err := store.User().Save(data.User, db)
if err == nil {
render.JSON(w, 201, data.User)
} else {
render.JSON(w, err.StatusCode, err)
}
} else {
render.JSON(w, error503.StatusCode, error503)
}
return
}
if err := db.DB().Ping(); err != nil {
render.JSON(w, error503.StatusCode, error503)
return
}
apperr := store.User().Save(data.User, db)
if err == nil {
render.JSON(w, 201, data.User)
return
}
render.JSON(w, apperr.StatusCode, apperr)

}

func inviteUser(w http.ResponseWriter, r *http.Request) {
Expand All @@ -378,24 +421,32 @@ func inviteUser(w http.ResponseWriter, r *http.Request) {
organisation := store.Organisation().Get(db)
response := inviteOk{}
request := r.Body

if !canManageUser("global", r.Context().Value(jwtTokenKey).(*jwt.Token)) {
res := error401
res.Message = "You don't have the right to manage user."
render.JSON(w, error401.StatusCode, error401)
return
}

err := chiRender.Bind(request, &data)
if err != nil || data.Email == "" {
render.JSON(w, error422.StatusCode, error422)
} else {
if err := db.DB().Ping(); err == nil {
var terr error
response.Email = data.Email
response.Organisation = organisation.OrganisationName
response.Token, terr = createInviteToken(data.Email, organisation.OrganisationName)
if terr == nil {
render.JSON(w, 201, response)
} else {
render.JSON(w, 422, "Could not generate token")
}
} else {
render.JSON(w, error503.StatusCode, error503)
return
}
if err := db.DB().Ping(); err == nil {
var terr error
response.Email = data.Email
response.Organisation = organisation.OrganisationName
response.Token, terr = createInviteToken(data.Email, organisation.OrganisationName)
if terr == nil {
render.JSON(w, 201, response)
return
}
render.JSON(w, 422, "Could not generate token")
return
}
render.JSON(w, error503.StatusCode, error503)
}

func updateUser(w http.ResponseWriter, r *http.Request) {
Expand All @@ -409,26 +460,41 @@ func updateUser(w http.ResponseWriter, r *http.Request) {
request := r.Body
err := chiRender.Bind(request, &data)
user := r.Context().Value(oldUserKey).(models.User)
token := r.Context().Value(jwtTokenKey).(*jwt.Token)
self := token.Claims.(jwt.MapClaims)["user"].(string) == user.Username
if !self && !canManageUser("global", token) {
res := error401
res.Message = "You don't have the right to manage user."
render.JSON(w, error401.StatusCode, error401)
return
}

if err != nil || data.User == nil {
render.JSON(w, error422.StatusCode, error422)
} else {
if err := db.DB().Ping(); err == nil {
err := store.User().Update(&user, data.User, db)
if err == nil {
render.JSON(w, 200, user)
} else {
render.JSON(w, err.StatusCode, err)
}
} else {
render.JSON(w, error503.StatusCode, error503)
return
}
if err := db.DB().Ping(); err == nil {
err := store.User().Update(&user, data.User, db)
if err == nil {
render.JSON(w, 200, user)
return
}

}
render.JSON(w, error503.StatusCode, error503)
}

func deleteUser(w http.ResponseWriter, r *http.Request) {
user := r.Context().Value(oldUserKey).(models.User)
store := datastores.Store()

token := r.Context().Value(jwtTokenKey).(*jwt.Token)
self := token.Claims.(jwt.MapClaims)["user"].(string) == user.Username
if !self && !canManageUser("global", token) {
res := error401
res.Message = "You don't have the right to manage user."
render.JSON(w, error401.StatusCode, error401)
return
}
message := deleteMessageModel{
Object: user,
}
Expand All @@ -439,12 +505,12 @@ func deleteUser(w http.ResponseWriter, r *http.Request) {
message.Success = true
message.Message = "User well removed."
render.JSON(w, 200, message)
} else {
message.Success = false
message.Message = err.Message
render.JSON(w, err.StatusCode, message.Message)
return
}
} else {
render.JSON(w, 503, error503)
message.Success = false
message.Message = err.Message
render.JSON(w, err.StatusCode, message.Message)
return
}
render.JSON(w, 503, error503)
}
1 change: 1 addition & 0 deletions datastores/data_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ type MemberStore interface {
Save(member *models.Member, db *gorm.DB) *u.AppError
Update(member *models.Member, newMember *models.Member, db *gorm.DB) *u.AppError
GetByID(ID uint64, db *gorm.DB) models.Member
GetChannelMember(user *models.User, channel *models.Channel, db *gorm.DB) models.Member
GetByUser(user *models.User, db *gorm.DB) []models.Member
GetByChannel(channel *models.Channel, db *gorm.DB) []models.Member
GetByRole(role *models.Role, db *gorm.DB) []models.Member
Expand Down
7 changes: 7 additions & 0 deletions datastores/members_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ func (msi MemberStoreImpl) GetByID(ID uint64, db *gorm.DB) models.Member {
return member
}

// GetChannelMember get specific user in specific channel
func (msi MemberStoreImpl) GetChannelMember(user *models.User, channel *models.Channel, db *gorm.DB) models.Member {
member := models.Member{}
db.Table("members").Select("*").Joins("natural join users natural join channels").Where("users.idUser = ? and channels.idChannel = ?", user.IDUser, channel.IDChannel).Find(&member)
return member
}

// GetByUser get member from user
func (msi MemberStoreImpl) GetByUser(user *models.User, db *gorm.DB) []models.Member {
members := []models.Member{}
Expand Down
17 changes: 11 additions & 6 deletions datastores/user_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,21 @@ func (usi UserStoreImpl) GetByUserName(userName string, db *gorm.DB) models.User
}

// Login Used to log user in
func (usi UserStoreImpl) Login(userName string, pass string, db *gorm.DB) (models.User, *u.AppError) {
user := models.User{}
func (usi UserStoreImpl) Login(login string, pass string, db *gorm.DB) (models.User, *u.AppError) {
user1 := models.User{}
user2 := models.User{}
empty := models.User{}
err := u.NewAPIError(404, "Wrong user name or password", "Can't proceed to login. Password or user name is not correct")
db.Where("userName = ?", userName).First(&user)
if (user == models.User{}) {
db.Where("userName = ?", login).First(&user1)
db.Where("email = ?", login).First(&user2)
if (user1 == models.User{} && user2 == models.User{}) {
return empty, err
}
if models.ComparePassword(user.Password, pass) {
return user, nil
if models.ComparePassword(user1.Password, pass) {
return user1, nil
}
if models.ComparePassword(user2.Password, pass) {
return user2, nil
}
return empty, err
}
Expand Down

0 comments on commit 1e67090

Please sign in to comment.