u
This commit is contained in:
1 parent
dc46d8034d
commit
949cfa113b
1 file changed
+102
-32
@@ -40,7 +40,14 @@ func Exists(key string) (bool, error) {
|
|||||||
return cnt > 0, nil
|
return cnt > 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================== Space User / Role ==================
|
/*
|
||||||
|
Key design:
|
||||||
|
|
||||||
|
space:user:{spaceId}:{userId} -> role (string/int)
|
||||||
|
space:users:{spaceId} -> Set(userId)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// ================== Role ==================
|
||||||
|
|
||||||
const (
|
const (
|
||||||
RoleMember int32 = 1
|
RoleMember int32 = 1
|
||||||
@@ -50,32 +57,78 @@ const (
|
|||||||
SpaceUserTTL = 10 * time.Minute
|
SpaceUserTTL = 10 * time.Minute
|
||||||
)
|
)
|
||||||
|
|
||||||
// space:user:{spaceId}:{userId}
|
// ================== Key helpers ==================
|
||||||
func SpaceUserKey(spaceId int64, userId int64) string {
|
|
||||||
|
func spaceUserKey(spaceId, userId int64) string {
|
||||||
return fmt.Sprintf("space:user:%d:%d", spaceId, userId)
|
return fmt.Sprintf("space:user:%d:%d", spaceId, userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set / Create space user role
|
func spaceUsersKey(spaceId int64) string {
|
||||||
func SetSpaceUserRole(spaceId int64, userId int64, role int32) error {
|
return fmt.Sprintf("space:users:%d", spaceId)
|
||||||
key := SpaceUserKey(spaceId, userId)
|
|
||||||
return Set(key, role, SpaceUserTTL)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update space user role (same as set, semantic clarity)
|
// ================== Domain APIs ==================
|
||||||
func UpdateSpaceUserRole(spaceId int64, userId int64, role int32) error {
|
|
||||||
return SetSpaceUserRole(spaceId, userId, role)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get space user role
|
// JoinSpace
|
||||||
// return 0 means not exists
|
// - add user to space users set
|
||||||
func GetSpaceUserRole(spaceId int64, userId int64) (int32, error) {
|
// - set user role
|
||||||
key := SpaceUserKey(spaceId, userId)
|
func JoinSpace(spaceId, userId int64, role int32) error {
|
||||||
val, err := Get(key)
|
ctx := context.Background()
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
// 1. add to space users
|
||||||
|
if err := Client().SAdd(ctx, spaceUsersKey(spaceId), userId).Err(); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
if val == "" {
|
|
||||||
return 0, nil
|
// 2. set role
|
||||||
|
if err := Set(spaceUserKey(spaceId, userId), role, SpaceUserTTL); err != nil {
|
||||||
|
// rollback
|
||||||
|
_ = Client().SRem(ctx, spaceUsersKey(spaceId), userId).Err()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LeaveSpace
|
||||||
|
// - remove user from space
|
||||||
|
// - delete role cache
|
||||||
|
func LeaveSpace(spaceId, userId int64) error {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
if err := Client().SRem(ctx, spaceUsersKey(spaceId), userId).Err(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return Delete(spaceUserKey(spaceId, userId))
|
||||||
|
}
|
||||||
|
|
||||||
|
// KickSpaceUser = LeaveSpace
|
||||||
|
func KickSpaceUser(spaceId, userId int64) error {
|
||||||
|
return LeaveSpace(spaceId, userId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChangeSpaceUserRole
|
||||||
|
func ChangeSpaceUserRole(spaceId, userId int64, role int32) error {
|
||||||
|
ok, err := IsUserInSpace(spaceId, userId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("user not in space")
|
||||||
|
}
|
||||||
|
|
||||||
|
return Set(spaceUserKey(spaceId, userId), role, SpaceUserTTL)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================== Query APIs ==================
|
||||||
|
|
||||||
|
// GetSpaceUserRole
|
||||||
|
// return 0 means not exists
|
||||||
|
func GetSpaceUserRole(spaceId, userId int64) (int32, error) {
|
||||||
|
val, err := Get(spaceUserKey(spaceId, userId))
|
||||||
|
if err != nil || val == "" {
|
||||||
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
r, err := strconv.ParseInt(val, 10, 32)
|
r, err := strconv.ParseInt(val, 10, 32)
|
||||||
@@ -85,20 +138,37 @@ func GetSpaceUserRole(spaceId int64, userId int64) (int32, error) {
|
|||||||
return int32(r), nil
|
return int32(r), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete space user (kick / dissolve)
|
func IsUserInSpace(spaceId, userId int64) (bool, error) {
|
||||||
func DeleteSpaceUser(spaceId int64, userId int64) error {
|
return Client().
|
||||||
key := SpaceUserKey(spaceId, userId)
|
SIsMember(context.Background(), spaceUsersKey(spaceId), userId).
|
||||||
return Delete(key)
|
Result()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exists space user
|
func GetSpaceUsers(spaceId int64) ([]int64, error) {
|
||||||
func ExistsSpaceUser(spaceId int64, userId int64) (bool, error) {
|
members, err := Client().
|
||||||
key := SpaceUserKey(spaceId, userId)
|
SMembers(context.Background(), spaceUsersKey(spaceId)).
|
||||||
return Exists(key)
|
Result()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
users := make([]int64, 0, len(members))
|
||||||
|
for _, m := range members {
|
||||||
|
uid, err := strconv.ParseInt(m, 10, 64)
|
||||||
|
if err == nil {
|
||||||
|
users = append(users, uid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return users, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Permission check
|
// CheckRole
|
||||||
// owner > admin > member
|
// check whether user's role in space >= needRole
|
||||||
func HasPermission(userRole int32, needRole int32) bool {
|
func CheckRole(spaceId, userId int64, needRole int32) (bool, error) {
|
||||||
return userRole >= needRole
|
userRole, err := GetSpaceUserRole(spaceId, userId)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return userRole == needRole, nil
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user