More work on auth system I guess, still no motivation though
Some checks failed
/ test (push) Has been cancelled

This commit is contained in:
Melody Becker 2025-02-28 15:01:12 +01:00
parent 402932602d
commit ab3051fa78
Signed by: mstar
SSH key fingerprint: SHA256:9VAo09aaVNTWKzPW7Hq2LW+ox9OdwmTSHRoD4mlz1yI
4 changed files with 132 additions and 12 deletions

View file

@ -1,5 +1,8 @@
Linstrom is a new social media server with the focus on providing users, moderators and admins alike
simple, yet powerful features to moderate the experience.
# Linstrom
Linstrom is a new social media server with the focus on providing
users, moderators and admins alike simple, yet powerful features
to moderate the experience.
## Federation
@ -20,3 +23,18 @@ And they all have different woes with their software.
I want to try and make a server that combines the strengths of various
project's tooling while also hopefully solving
some of the weaknesses.
## Permission system
All permissions operate on a role based system, similar to what Discord offers.
Accounts in power (admins and moderators) are only able to manipulate other accounts
via this role system. This prevents moderators from directly manipulating accounts,
such as changing their username, info fields or otherwise, while still providing
ample control over the activities these accounts can perform.
These same roles, while most powerful for local accounts, also apply to remote accounts
as much as realisticly possible. Preventing a login on a remote server for example
might not be possible, but blocking all inbound traffic from that account is.
However, roles are not only for moderators and admins to use.
Normal accounts can also make use of them, all be it in a more limited way.

View file

@ -1,11 +1,17 @@
package auth
import "gorm.io/gorm"
import (
"git.mstar.dev/mstar/linstrom/storage"
"gorm.io/gorm"
)
type Authentication struct {
// For when in-depth access is needed
db *gorm.DB
// Primary method to acquire account data
store *storage.Storage
}
func NewAuth(db *gorm.DB) *Authentication {
return &Authentication{db}
func NewAuth(db *gorm.DB, store *storage.Storage) *Authentication {
return &Authentication{db, store}
}

View file

@ -1,15 +1,107 @@
package auth
import "git.mstar.dev/mstar/linstrom/storage"
import (
"git.mstar.dev/mstar/goutils/sliceutils"
"git.mstar.dev/mstar/linstrom/storage"
"github.com/rs/zerolog/log"
)
// Can actorId access the account with targetId?
func (a *Authentication) CanAccessAccount(actorId *string, targetId string) bool { return true }
// Can actorId read the account with targetId?
func (a *Authentication) CanReadAccount(actorId *string, targetId string) bool {
targetAccount, err := a.store.FindAccountById(targetId)
if err != nil {
if err == storage.ErrEntryNotFound {
return true
}
log.Error().
Err(err).
Str("account-id", targetId).
Msg("Failed to receive account for permission check")
return false
}
if actorId == nil {
// TODO: Decide if roles should have a field to declare an account as follow only/hidden
// and then check for that flag here
return true
}
roles, err := a.store.FindRolesByNames(targetAccount.Roles)
if err != nil {
log.Error().
Err(err).
Strs("role-names", targetAccount.Roles).
Msg("Failed to get roles for target account")
return false
}
combined := storage.CollapseRolesIntoOne(roles...)
if sliceutils.Contains(combined.BlockedUsers, *actorId) {
return false
}
return true
}
// Can actorId edit the account with targetId?
func (a *Authentication) CanEditAccount(actorId *string, targetIt *string) bool { return true }
// If actorId is nil, it is assumed to be an anonymous user trying to edit the target account
// if targetId is nil, it is assumed that the actor is editing themselves
func (a *Authentication) CanEditAccount(actorId *string, targetId *string) bool {
// FIXME: This entire function feels wrong, idk
// Only the owner of an account should be able to edit said account's data
// But how do moderation actions play with this? Do they count as edit or as something separate?
if actorId == nil {
return false
}
if targetId == nil {
targetId = actorId
}
targetAccount, err := a.store.FindAccountById(*targetId)
if err != nil {
if err != storage.ErrEntryNotFound {
log.Error().
Err(err).
Str("target-id", *targetId).
Msg("Failed to receive account for permission checks")
}
return false
}
if targetId == actorId {
targetRoles, err := a.store.FindRolesByNames(targetAccount.Roles)
if err != nil {
log.Error().
Err(err).
Strs("role-names", targetAccount.Roles).
Msg("Failed to get roles from storage")
return false
}
combined := storage.CollapseRolesIntoOne(targetRoles...)
return *combined.CanLogin
} else {
return false
}
}
// Can actorId delete the account with targetId?
func (a *Authentication) CanDeleteAccount(actorId *string, targetIt *string) bool { return true }
// If actorId is nil, it is assumed to be an anonymous user trying to delete the target account
// if targetId is nil, it is assumed that the actor is deleting themselves
func (a *Authentication) CanDeleteAccount(actorId *string, targetId *string) bool {
if actorId == nil {
return false
}
acc, err := a.store.FindAccountById(*actorId)
if err != nil {
// TODO: Logging
return false
}
roles, err := a.store.FindRolesByNames(acc.Roles)
if err != nil {
// TODO: Logging
return false
}
collapsed := storage.CollapseRolesIntoOne(roles...)
if targetId == nil {
return *collapsed.CanLogin
} else {
return *collapsed.CanDeleteAccounts
}
}
// Can actorId create a new post at all?
// Specific restrictions regarding the content are not checked

View file

@ -1,9 +1,9 @@
package storage
import (
"github.com/rs/zerolog/log"
"git.mstar.dev/mstar/goutils/sliceutils"
"git.mstar.dev/mstar/linstrom/util"
"github.com/rs/zerolog/log"
"gorm.io/gorm"
)
@ -80,6 +80,9 @@ type Role struct {
// Internal ids of accounts blocked by this role
BlockedUsers []string `gorm:"type:bytes;serializer:gob"` // Local
CanSubmitReports *bool // Local & remote
// If disabled, an account can no longer be interacted with. The owner can no longer change anything about it
// And the UI will show a notice (and maybe include that info in the AP data too)
// Only moderators and admins will be able to edit the account's roles
CanLogin *bool // Local
CanMentionOthers *bool // Local & remote
@ -125,6 +128,7 @@ type Role struct {
CanManageAvatarDecorations *bool // Local
CanManageAds *bool // Local
CanSendAnnouncements *bool // Local
CanDeleteAccounts *bool // Local
}
/*