func (h *isAuthHook) Hook(c *bitmonster.Context) error { if !IsAuth(c.Socket()) { return fmt.Errorf("socket session is not authorized") } return nil }
func editCurrentUser(c *bitmonster.Context) error { // Obtain the data from the context. data := struct { // All these values replace the values of the user: Name string `json:"name"` Email string `json:"email"` }{} err := c.Decode(&data) if err != nil { return err } // Obtain the current user. user, err := CurrentUser(c.Socket()) if err != nil { return err } // Update the user fields. user.Name = data.Name user.Email = data.Email // Update the user in the database. err = UpdateUser(user) if err != nil { return err } // Set the updated user as return data. c.Data(user) return nil }
func getCurrentUser(c *bitmonster.Context) error { // Obtain the current user. user, err := CurrentUser(c.Socket()) if err != nil { return err } // Set the user as return data. c.Data(user) return nil }
func clearAuthSessionsOfCurrentUser(c *bitmonster.Context) error { // Obtain the current user. user, err := CurrentUser(c.Socket()) if err != nil { return err } // Clear the authenticated sessions. user.ClearAuthSessions() // Update the user in the database. err = UpdateUser(user) if err != nil { return err } return nil }
func logout(c *bitmonster.Context) error { // Get the socket. s := c.Socket() // Get the current authenticated user. user, err := CurrentUser(s) if err != nil { if err == ErrNotAuth { // Not authenticated. return nil } return err } // Debug log. log.L.WithFields(logrus.Fields{ "remoteAddress": s.RemoteAddr(), "user": user.Username, "userID": user.ID, }).Debugf("auth: logout") // Get the current socket value. av := getAuthSocketValue(s) if av == nil { return fmt.Errorf("failed to obtain auth socket value") } // Reset the socket authentication values. resetAuthSocketValue(s) // Remove the authenticated session specified by the key. if user.AuthSessions != nil { delete(user.AuthSessions, av.authSessionKey) } // Update the user in the database. err = UpdateUser(user) if err != nil { return err } return nil }
func (h *groupHook) Hook(c *bitmonster.Context) error { // Obtain the current user. // Enable the cache. This hook might be called many times... user, err := CurrentUser(c.Socket(), true) if err != nil { return err } // Check if the user is in one of the groups. for _, g := range h.groups { for _, ug := range user.Groups { if g == ug { // Return because the user is at least in one group. return nil } } } return fmt.Errorf("socket session is not authorized: not member of required group(s)") }
func changePasswordOfCurrentUser(c *bitmonster.Context) error { // Obtain the data from the context. data := struct { OldPassword string `json:"oldPassword"` NewPassword string `json:"newPassword"` }{} err := c.Decode(&data) if err != nil { return err } // Obtain the current user. user, err := CurrentUser(c.Socket()) if err != nil { return err } // Check if the old password is valid. if match := user.ComparePasswords(data.OldPassword); !match { c.Error("wrong_password") return nil } // Change the user's password. err = user.ChangePassword(data.NewPassword) if err != nil { return err } // Update the user in the database. err = UpdateUser(user) if err != nil { return err } return nil }
func getUsers(c *bitmonster.Context) error { println("getUsers") v := struct { Foo string Bar string }{} err := c.Decode(&v) if err != nil { return err } fmt.Printf("%+v\n", v) // Get the event. e, err := c.Module().Event("onNew") if err != nil { return err } // Trigger the event. err = e.Trigger(v) if err != nil { return err } // Only this socket. err = e.TriggerSocket(c.Socket(), v) if err != nil { return err } c.Data(&v) c.Error("error message") return nil }
func authenticate(c *bitmonster.Context) (err error) { // Get the socket. s := c.Socket() // Reset the session authentication values if an error occurs. defer func() { if err == nil { return } // Reset the socket authentication values. resetAuthSocketValue(s) }() // Obtain the authentication data from the context. authData := struct { Token string `json:"token"` Fingerprint string `json:"fingerprint"` }{} err = c.Decode(&authData) if err != nil { return err } if len(authData.Token) == 0 || len(authData.Fingerprint) == 0 { return fmt.Errorf("invalid authentication data") } // Parse the authentication data. userID, key, token, err := parseAuthToken(authData.Token) if err != nil { return err } // Obtain the user. user, err := GetUser(userID) if err != nil { return err } // Debug log. log.L.WithFields(logrus.Fields{ "remoteAddress": s.RemoteAddr(), "user": user.Username, "userID": user.ID, }).Debugf("auth: authentication request") // Check if the authenticated sessions map is nil. if user.AuthSessions == nil { return fmt.Errorf("invalid authentication data") } // Obtain the authenticated session value. as, ok := user.AuthSessions[key] if !ok { return fmt.Errorf("invalid authentication data") } // Get the current time. timeNow := time.Now() // Check if the maximum age is reached. if as.Created.Add(authSessionMaxAge).Before(timeNow) { return fmt.Errorf("authenticated user session expired: max age reached") } // Compare the tokens in a constant time span. if subtle.ConstantTimeCompare([]byte(as.Token), []byte(token)) != 1 { return fmt.Errorf("invalid authentication token") } // Compare the fingerprints. err = comparePasswordHash(as.Fingerprint, authData.Fingerprint) if err != nil { return fmt.Errorf("invalid fingerprint: %v", err) } // Hint: Authentication success. // ----------------------------- // Update the timestamps. user.LastLogin = timeNow as.LastAuth = timeNow // If the token is expired, then create a new token. // This ensures an authentication token rotation. var authToken string if as.TokenCreated.Add(authSessionTokenLifetime).Before(timeNow) { // Create a new random token. as.Token = utils.RandomString(authSessionTokenLength) as.TokenCreated = timeNow // Create a new encrypted authentication token. authToken, err = newAuthToken(user.ID, key, as.Token) if err != nil { return err } // Debug log. log.L.WithFields(logrus.Fields{ "remoteAddress": s.RemoteAddr(), "user": user.Username, "userID": user.ID, }).Debugf("auth: authentication token rotated") } // Update the user in the database. err = UpdateUser(user) if err != nil { return err } // Get or create the auth socket value. av := getAuthSocketValue(s) if av == nil { return fmt.Errorf("failed to create auth socket value for socket") } // Stop the logout timer if present. if av.reauthTimer != nil { av.reauthTimer.Stop() } // Update the auth socket value. av.isAuth = true av.authSessionKey = key av.userID = user.ID // Clear the cache. clearCache(s) // Create the respond data. data := struct { Token string `json:"token"` User *User `json:"user"` }{ Token: authToken, User: user, } // Set it. c.Data(data) // Debug log. log.L.WithFields(logrus.Fields{ "remoteAddress": s.RemoteAddr(), "user": user.Username, "userID": user.ID, }).Debugf("auth: authentication success") return nil }