diff --git a/api/api.go b/api/api.go index 45a4476..683cd4b 100644 --- a/api/api.go +++ b/api/api.go @@ -5,7 +5,9 @@ import ( "crypto/rand" "encoding/base32" "flag" + "log" "net/http" + "os" jwt "github.com/dgrijalva/jwt-go" "github.com/jinzhu/gorm" @@ -66,12 +68,36 @@ func initAuth() { tokenAuth = New("HS256", hmacSampleSecret, hmacSampleSecret) } -// createToken create JWT auth token for current login user -func createToken(user models.User) (string, error) { +// createUserToken create JWT auth token for current login user +func createUserToken(user models.User, role models.Role) (string, error) { claims := jwt.MapClaims{ - "name": user.Username, - "email": user.Email, - "role": user.IDRole, + "name": user.Username, + "email": user.Email, + "role": role.RoleName, + "archive": role.CanArchive, + "invite": role.CanInvite, + "manage": role.CanManage, + "manageuser": role.CanManageUser, + "moderate": role.CanModerate, + "private": role.CanUsePrivate, + "type": "userauth", + } + unsignedToken := *jwt.NewWithClaims(jwt.SigningMethodHS256, claims) + tokenString, err := unsignedToken.SignedString(hmacSampleSecret) + + if err != nil { + return "", err + } + + return tokenString, nil +} + +// createInviteToken create JWT auth token for current invitation +func createInviteToken(inviteMail string, organisationName string) (string, error) { + claims := jwt.MapClaims{ + "email": inviteMail, + "organisation": organisationName, + "type": "invitation", } unsignedToken := *jwt.NewWithClaims(jwt.SigningMethodHS256, claims) tokenString, err := unsignedToken.SignedString(hmacSampleSecret) @@ -102,6 +128,7 @@ func initMiddleware(router *chi.Mux) { // basicRoutes set basic routes for the API func basicRoutes(router *chi.Mux) { + router.Use(tokenAuth.Verifier) // swagger:route GET / Test hello // // Hello World @@ -149,18 +176,56 @@ func basicRoutes(router *chi.Mux) { // 422: wrongEntity // 503: databaseError router.Post("/login", loginMiddleware) - // swagger:route POST /user Users newPublicUser - // - // New user - // - // This will create an user for organisation if organisation is Public OR Email match parametetered emails - // - // Responses: - // 201: userObjectSuccess - // 422: wrongEntity - // 503: databaseError - // default: genericError - router.Post("/publicuser", newPublicUser) + router.Route("/publicuser", func(r chi.Router) { + // swagger:route POST /publicuser/new Users newPublicUser + // + // New user + // + // This will create an user for organisation if organisation is Public OR Email match parametetered emails + // + // Responses: + // 201: userObjectSuccess + // 422: wrongEntity + // 503: databaseError + // default: genericError + r.Post("/new", newPublicUser) + r.Route("/newfrominvite", func(r chi.Router) { + r.Use(tokenAuth.Verifier) + r.Use(allowUserCreationFromToken) + // swagger:route POST /publicuser/newfrominvite Users newPublicUser + // + // New user + // + // This will create an user for organisation if user was invited + // + // Responses: + // 201: userObjectSuccess + // 422: wrongEntity + // 503: databaseError + // default: genericError + r.Post("/", newUser) + }) + }) +} + +func initDevGetter(router chi.Router) { + env := os.Getenv("POPCUBE_API_ENV") + if env == "prod" || env == "test" || env == "beta" || env == "alpha" || env == "production" { + return + } + log.Print("<><><><><><><> Using DEV routes <><><><><><><> \n") + router.Route("/devgetters", func(r chi.Router) { + r.Get("/avatar", getAllAvatar) + r.Get("/channel", getAllChannel) + r.Get("/emoji", getAllEmoji) + r.Get("/folder", getAllFolder) + r.Get("/member", getAllMember) + r.Get("/message", getAllMessage) + r.Get("/organisation", getAllOrganisation) + r.Get("/parameter", getAllParameter) + r.Get("/role", getAllRole) + r.Get("/user", getAllUser) + }) } // loginMiddleware login funcion providing user && jwt auth token @@ -183,15 +248,18 @@ func loginMiddleware(w http.ResponseWriter, r *http.Request) { user, err := store.User().Login(data.Login, data.Password, db) if err == nil { var terr error + // role can't be empty if user exist => foreign key constraint + role := datastores.Store().Role().GetByID(user.IDRole, dbStore.db) response.User = user - response.Token, terr = createToken(user) + response.Token, terr = createUserToken(user, role) if terr == nil { render.JSON(w, 200, response) return } - render.JSON(w, err.StatusCode, err) - return + render.JSON(w, 422, "Could not generate token") } + render.JSON(w, err.StatusCode, err) + return } render.JSON(w, error503.StatusCode, error503) @@ -245,7 +313,7 @@ func StartAPI(hostname string, port string, DbConnectionInfo *configs.DbConnecti initParameterRoute(router) initRoleRoute(router) initUserRoute(router) - + initDevGetter(router) // Passing -routes to the program will generate docs for the above // router definition. See the `routes.json` file in this folder for // the output. diff --git a/api/api_responses.go b/api/api_responses.go index 5ee9f32..949c1c9 100644 --- a/api/api_responses.go +++ b/api/api_responses.go @@ -21,9 +21,21 @@ type generalOk struct { // swagger:response loginOk type loginOk struct { // in:body - User models.User + User models.User `json:"user,omitempty"` // in:body - Token string + Token string `json:"token,omitempty"` +} + +// inviteOk when invite correctly proceed, return the invite token information and the JWT token. +// +// swagger:response loginOk +type inviteOk struct { + // in:body + Email string `json:"email,omitempty"` + // in:body + Organisation string `json:"organisation,omitempty"` + // in:body + Token string `json:"token,omitempty"` } // --------------------------------------------------- diff --git a/api/jwtauth.go b/api/jwtauth.go index c0b09b1..f88b2d9 100644 --- a/api/jwtauth.go +++ b/api/jwtauth.go @@ -12,6 +12,7 @@ import ( "time" jwt "github.com/dgrijalva/jwt-go" + "github.com/titouanfreville/popcubeapi/datastores" ) var ( @@ -202,10 +203,7 @@ func (ja *JwtAuth) IsExpired(t *jwt.Token) bool { return false } -// Authenticator is a default authentication middleware to enforce access following -// the Verifier middleware. The Authenticator sends a 401 Unauthorized response for -// all unverified tokens and passes the good ones through. It's just fine until you -// decide to write something similar and customize your client response. +// Authenticator validate that user has a valid user auth token before letting him access. func Authenticator(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() @@ -223,6 +221,65 @@ func Authenticator(next http.Handler) http.Handler { return } + tokenType, ok := jwtToken.Claims.(jwt.MapClaims)["type"] + + if !ok { + render.JSON(w, 401, "Token is not valid. Type is undifined") + return + } + + if tokenType != "userauth" { + render.JSON(w, 401, "Token is not an user auth one") + return + } + + // Token is authenticated, pass it through + next.ServeHTTP(w, r) + }) +} + +// allowUserCreationFromToken check the provided token is an invitation one +func allowUserCreationFromToken(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + if jwtErr, ok := ctx.Value(jwtErrorKey).(error); ok { + if jwtErr != nil { + render.JSON(w, 401, jwtErr) + return + } + } + + jwtToken, ok := ctx.Value(jwtTokenKey).(*jwt.Token) + if !ok || jwtToken == nil || !jwtToken.Valid { + render.JSON(w, 401, "token is not valid or does not exist") + return + } + + tokenType, ok := jwtToken.Claims.(jwt.MapClaims)["type"] + + if !ok { + render.JSON(w, 401, "Token is not valid. Type is undifined") + return + } + + if tokenType != "invitation" { + render.JSON(w, 401, "Token is not an invitation one") + return + } + + tokenOrganisation, ok := jwtToken.Claims.(jwt.MapClaims)["organisation"].(string) + + if !ok { + render.JSON(w, 401, "Token is not valid. Organisation is undifined") + return + } + apiOrganisation := datastores.Store().Organisation().Get(dbStore.db) + + if tokenOrganisation != apiOrganisation.OrganisationName { + render.JSON(w, 401, "Token is not valid. Organisation does not match current organsisation") + return + } // Token is authenticated, pass it through next.ServeHTTP(w, r) }) diff --git a/api/user_route.go b/api/user_route.go index ab6b8be..6d1a3f0 100644 --- a/api/user_route.go +++ b/api/user_route.go @@ -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" @@ -71,6 +74,18 @@ func initUserRoute(router chi.Router) { // 503: databaseError // default: genericError r.Post("/new", newUser) + // swagger:route POST /user/invite Users inviteUser + // + // Invite user + // + // This will create an invitation token for a user. + // + // Responses: + // 201: userObjectSuccess + // 422: wrongEntity + // 503: databaseError + // default: genericError + r.Post("/invite", inviteUser) // swagger:route GET /user/all Users getDeletedUser // // Get deleted user @@ -216,7 +231,7 @@ func userContext(next http.Handler) http.Handler { date, _ := strconv.ParseInt(chi.URLParam(r, "date"), 10, 64) oldUser := models.User{} ctx := context.WithValue(r.Context(), userNameKey, name) - ctx = context.WithValue(r.Context(), nickNameKey, nickName) + ctx = context.WithValue(ctx, nickNameKey, nickName) ctx = context.WithValue(ctx, firstNameKey, firstName) ctx = context.WithValue(ctx, lastNameKey, lastName) ctx = context.WithValue(ctx, userEmailKey, email) @@ -229,34 +244,57 @@ func userContext(next http.Handler) http.Handler { }) } -func getAllUser(w http.ResponseWriter, r *http.Request) { +func canManageUser(place string, self bool, currentUser 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 self && currentUser == userName { + return true + } + 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) @@ -264,8 +302,11 @@ func getUserFromName(w http.ResponseWriter, r *http.Request) { 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) @@ -273,8 +314,11 @@ func getUserFromNickName(w http.ResponseWriter, r *http.Request) { 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) @@ -282,8 +326,11 @@ func getUserFromFirstName(w http.ResponseWriter, r *http.Request) { 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) @@ -291,8 +338,11 @@ func getUserFromLastName(w http.ResponseWriter, r *http.Request) { 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) @@ -300,8 +350,11 @@ func getUserFromEmail(w http.ResponseWriter, r *http.Request) { 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) @@ -313,20 +366,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) { @@ -335,24 +387,71 @@ func newUser(w http.ResponseWriter, r *http.Request) { OmitID interface{} `json:"id,omitempty"` } store := datastores.Store() + token := r.Context().Value(jwtTokenKey).(*jwt.Token) + if !canManageUser("global", false, "", 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) { + var data struct { + Email string `json:"email"` + Message string `json:"message"` + OmitID interface{} `json:"id,omitempty"` + } + store := datastores.Store() + db := dbStore.db + organisation := store.Organisation().Get(db) + response := inviteOk{} + request := r.Body + token := r.Context().Value(jwtTokenKey).(*jwt.Token) + if !canManageUser("global", false, "", 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) + 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) { @@ -366,26 +465,39 @@ 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) + if !canManageUser("global", true, user.Username, 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) + if !canManageUser("global", true, user.Username, 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, } @@ -396,12 +508,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) } diff --git a/datastores/data_store.go b/datastores/data_store.go index 213dd3b..a26cd72 100644 --- a/datastores/data_store.go +++ b/datastores/data_store.go @@ -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 diff --git a/datastores/members_store.go b/datastores/members_store.go index 0cb1b7f..7f28de3 100644 --- a/datastores/members_store.go +++ b/datastores/members_store.go @@ -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{} diff --git a/datastores/user_store.go b/datastores/user_store.go index d45ec96..bdcb64a 100644 --- a/datastores/user_store.go +++ b/datastores/user_store.go @@ -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 } diff --git a/scripts/init.sql b/scripts/init.sql index 7783e11..13abe2a 100644 --- a/scripts/init.sql +++ b/scripts/init.sql @@ -147,13 +147,6 @@ CREATE TABLE IF NOT EXISTS `popcube_test`.`members` ( ENGINE = InnoDB COMMENT = 'Store information about member of organisation.'; -CREATE UNIQUE INDEX `User_UNIQUE` ON `popcube_test`.`members` (`idUser` ASC); - -CREATE UNIQUE INDEX `Role_UNIQUE` ON `popcube_test`.`members` (`idRole` ASC); - -CREATE UNIQUE INDEX `channel_UNIQUE` ON `popcube_test`.`members` (`idChannel` ASC); - - -- ----------------------------------------------------- -- Table `popcube_test`.`messages` -- ----------------------------------------------------- diff --git a/scripts/init_values.sql b/scripts/init_values.sql index 1abb245..aac6042 100644 --- a/scripts/init_values.sql +++ b/scripts/init_values.sql @@ -6,7 +6,116 @@ INSERT INTO roles (roleName, canUsePrivate, canModerate, canArchive, canInvite, VALUES ("admin", true, true, true, true, true, true); INSERT INTO roles (roleName, canUsePrivate, canModerate, canArchive, canInvite, canManage, canManageUser) -VALUES ("standart", true, true, true, false, false, false); +VALUES ("standard", true, true, true, false, false, false); INSERT INTO roles (roleName, canUsePrivate, canModerate, canArchive, canInvite, canManage, canManageUser) -VALUES ("guest", false, false, false, false, false, false); \ No newline at end of file +VALUES ("guest", false, false, false, false, false, false); + +-- CHANNEL INITIALISATION ------------------------------------------------------------------------ +INSERT INTO channels (webId, channelName, type, lastUpdate, private, avatar, description, subject) +VALUES ("generaltextchannel", "general", "text", 1, false, "defaultAvatar", "Speak on general subjects", "General"); + +INSERT INTO channels (webId, channelName, type, lastUpdate, private, avatar,description) +VALUES ("randomtextchannel", "random", "text", 1, false, "defaultAvatar","Speak about any thing"); + +INSERT INTO channels (webId, channelName, type, lastUpdate, private, avatar) +VALUES ("generalvocchannel", "general - voc", "audio", 1, false, "defaultAvatar"); + +INSERT INTO channels (webId, channelName, type, lastUpdate, private, avatar) +VALUES ("randomvocchannel", "random - voc", "audio", 1, false, "defaultAvatar"); + +INSERT INTO channels (webId, channelName, type, lastUpdate, private, avatar) +VALUES ("generalvidchannel", "general - vid", "video", 1, false, "defaultAvatar"); + +INSERT INTO channels (webId, channelName, type, lastUpdate, private, avatar) +VALUES ("randomvidchannel", "random - vid", "video", 1, false, "defaultAvatar"); + +-- PARMETER INITIALISATION ------------------------------------------------------------------------ +INSERT INTO parameters (local, timeZone) +VALUES ("en_EN", "UTC-1"); + +-- UNCOMMENT THE FOLLOWINGS FOR LOCAL DEV TEST --------------------------------------------------- + +-- USER INITIALISATION <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> +INSERT INTO users (webId, userName, email, lastUpdate, password, idRole, avatar, nickName, firstName, lastName) +VALUES ("TestUserOwner", "devowner", "devowner@popcube.xyz", 1105154015461, "$2a$10$IU8oU9dseYZytHcr54VXj.H9tX78hS2xUuPrzMeVN6rFG7k89i6EW", 1, "user/owned.svg", "owner", "owner", "dev"); + + +INSERT INTO users (webId, userName, email, lastUpdate, password, idRole, avatar, nickName, firstName, lastName) +VALUES ("TestUserAdmin", "devadmin", "devadmin@popcube.xyz", 1105154015461, "$2a$10$IU8oU9dseYZytHcr54VXj.H9tX78hS2xUuPrzMeVN6rFG7k89i6EW", 2, "user/avatar.svg", "admin", "admin", "dev"); + +INSERT INTO users (webId, userName, email, lastUpdate, password, idRole, avatar, nickName, firstName, lastName) +VALUES ("TestUserStandard", "devstandard", "devstandard@popcube.xyz", 1105154015461, "$2a$10$IU8oU9dseYZytHcr54VXj.H9tX78hS2xUuPrzMeVN6rFG7k89i6EW", 3, "user/avatar.svg", "standard", "standard", "dev"); + +INSERT INTO users (webId, userName, email, lastUpdate, password, idRole, avatar, nickName, firstName, lastName) +VALUES ("TestUserGuest", "devguest", "devguest@popcube.xyz", 1105154015461, "$2a$10$IU8oU9dseYZytHcr54VXj.H9tX78hS2xUuPrzMeVN6rFG7k89i6EW", 4, "user/avatar.svg", "guest", "guest", "dev"); + +-- ORGANISATION INITIALISATION <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> +INSERT INTO organisations (dockerStack, organisationName, description, avatar, domain) +VALUES (1, "Popcube Dev", "Test for popcube", "popcube.svg", "popcubedev.popbcube.xyz"); + +-- MEMBERS INITITIALISATION <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> +INSERT INTO members (idUser, idChannel) +VALUES (1, 1); +INSERT INTO members (idUser, idChannel) +VALUES (2, 1); +INSERT INTO members (idUser, idChannel) +VALUES (3, 1); +INSERT INTO members (idUser, idChannel) +VALUES (4, 1); + +INSERT INTO members (idUser, idChannel) +VALUES (1, 2); +INSERT INTO members (idUser, idChannel) +VALUES (2, 2); +INSERT INTO members (idUser, idChannel) +VALUES (3, 2); +INSERT INTO members (idUser, idChannel) +VALUES (4, 2); + +INSERT INTO members (idUser, idChannel) +VALUES (1, 3); +INSERT INTO members (idUser, idChannel, idRole) +VALUES (2, 3,3); +INSERT INTO members (idUser, idChannel) +VALUES (3, 3); +INSERT INTO members (idUser, idChannel) +VALUES (4, 3); + +INSERT INTO members (idUser, idChannel) +VALUES (1, 4); +INSERT INTO members (idUser, idChannel) +VALUES (2, 4); +INSERT INTO members (idUser, idChannel, idRole) +VALUES (3, 4, 2); +INSERT INTO members (idUser, idChannel) +VALUES (4, 4); + +-- MESSAGE INITIALISATION <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> +INSERT INTO messages (idUser, idChannel, date, content) +VALUES (1, 1, 10210541, "Test message."); +INSERT INTO messages (idUser, idChannel, date, content) +VALUES (1, 1, 10210542, ""); +INSERT INTO messages (idUser, idChannel, date, content) +VALUES (1, 1, 10210543, "Test message with folder."); + +-- FOLDER INITIALISATION <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> +INSERT INTO folders (idMessage, type, link, name) +VALUES (2, "txt", "folders/text.txt", "text"); + +INSERT INTO folders (idMessage) +VALUES (3); + +-- EMOJIS INITIALISATION <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> +INSERT INTO emojis (name, shortcut, link) +VALUE ("troll face", ":troll:", "emojis/troll.svg"); + +INSERT INTO emojis (name, shortcut, link) +VALUE ("love", "<3", "emojis/love.svg"); + +-- AVATARS INITIALISATION <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> +INSERT INTO avatars (name, link) +VALUE ("troll face", "emojis/troll.svg"); + +INSERT INTO avatars (name, link) +VALUE ("Strawberrie", "emojis/straw.svg"); \ No newline at end of file