Files
glchat/internal/source/permissions.go
T

94 lines
2.8 KiB
Go
Raw Normal View History

// 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
}