// Package source связывает пакет прав с хранилищем: реализует permissions.Source // поверх store, чтобы движок прав не зависел от деталей доступа к данным. package source import ( "context" "errors" "time" "glchat/internal/permissions" "glchat/internal/store" ) // Adapter реализует permissions.Source. type Adapter struct { store *store.Store } func New(st *store.Store) *Adapter { return &Adapter{store: st} } var _ permissions.Source = (*Adapter)(nil) func (a *Adapter) GuildRoles(ctx context.Context, guildID uint64) ([]permissions.RoleData, error) { roles, err := a.store.ListGuildRoles(ctx, guildID) if err != nil { return nil, err } result := make([]permissions.RoleData, 0, len(roles)) for _, role := range roles { result = append(result, permissions.RoleData{ ID: role.ID, Permissions: permissions.Permission(role.Permissions), IsDefault: role.IsDefault, Position: role.Position, }) } return result, nil } func (a *Adapter) MemberRoleIDs(ctx context.Context, guildID, userID uint64) ([]uint64, error) { return a.store.MemberRoleIDs(ctx, guildID, userID) } // IsMember отвечает, состоит ли пользователь в сервере. func (a *Adapter) IsMember(ctx context.Context, guildID, userID uint64) (bool, error) { if _, err := a.store.GetGuildMember(ctx, guildID, userID); err != nil { if errors.Is(err, store.ErrNotFound) { return false, nil } return false, err } return true, nil } func (a *Adapter) ChannelOverrides(ctx context.Context, channelID uint64) ([]permissions.OverrideData, error) { overrides, err := a.store.ListChannelOverrides(ctx, channelID) if err != nil { return nil, err } result := make([]permissions.OverrideData, 0, len(overrides)) for _, override := range overrides { result = append(result, permissions.OverrideData{ TargetType: override.TargetType, TargetID: override.TargetID, Allow: permissions.Permission(override.Allow), Deny: permissions.Permission(override.Deny), }) } return result, nil } func (a *Adapter) GuildOwnerID(ctx context.Context, guildID uint64) (uint64, error) { guild, err := a.store.GetGuild(ctx, guildID) if err != nil { return 0, err } return guild.OwnerID, nil } func (a *Adapter) MemberTimeout(ctx context.Context, guildID, userID uint64) (bool, error) { member, err := a.store.GetGuildMember(ctx, guildID, userID) if err != nil { if errors.Is(err, store.ErrNotFound) { // Не участник сервера: тайм-аут не применяется, правами рулит VIEW_GUILD. return false, nil } return false, err } if member.TimeoutUntil == nil { return false, nil } return member.TimeoutUntil.After(time.Now().UTC()), nil }