mirror of
https://github.com/m1k1o/neko.git
synced 2024-07-24 14:40:50 +12:00
allow multiple users to be set in object provider.
This commit is contained in:
parent
107eba22a5
commit
1fb5ae43dd
@ -65,11 +65,41 @@ desktop:
|
|||||||
member:
|
member:
|
||||||
provider: "object"
|
provider: "object"
|
||||||
object:
|
object:
|
||||||
admin_password: "admin"
|
users:
|
||||||
user_password: "neko"
|
- username: "admin"
|
||||||
|
password: "admin"
|
||||||
|
profile:
|
||||||
|
name: "Administrator"
|
||||||
|
is_admin: true
|
||||||
|
can_login: true
|
||||||
|
can_connect: true
|
||||||
|
can_watch: true
|
||||||
|
can_host: true
|
||||||
|
can_share_media: true
|
||||||
|
can_access_clipboard: true
|
||||||
|
sends_inactive_cursor: true
|
||||||
|
can_see_inactive_cursors: true
|
||||||
|
- username: "user"
|
||||||
|
password: "neko"
|
||||||
|
profile:
|
||||||
|
name: "User"
|
||||||
|
is_admin: false
|
||||||
|
can_login: true
|
||||||
|
can_connect: true
|
||||||
|
can_watch: true
|
||||||
|
can_host: true
|
||||||
|
can_share_media: true
|
||||||
|
can_access_clipboard: true
|
||||||
|
sends_inactive_cursor: true
|
||||||
|
can_see_inactive_cursors: false
|
||||||
# provider: "file"
|
# provider: "file"
|
||||||
# file:
|
# file:
|
||||||
# path: "/home/neko/members.json"
|
# path: "/home/neko/members.json"
|
||||||
|
# provider: "multiuser"
|
||||||
|
# multiuser:
|
||||||
|
# admin_password: "admin"
|
||||||
|
# user_password: "neko"
|
||||||
|
# provider: "noauth"
|
||||||
|
|
||||||
session:
|
session:
|
||||||
# Allows reconnecting the websocket even if the previous
|
# Allows reconnecting the websocket even if the previous
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"github.com/demodesk/neko/internal/member/file"
|
"github.com/demodesk/neko/internal/member/file"
|
||||||
"github.com/demodesk/neko/internal/member/multiuser"
|
"github.com/demodesk/neko/internal/member/multiuser"
|
||||||
"github.com/demodesk/neko/internal/member/object"
|
"github.com/demodesk/neko/internal/member/object"
|
||||||
|
"github.com/demodesk/neko/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Member struct {
|
type Member struct {
|
||||||
@ -31,13 +33,8 @@ func (Member) Init(cmd *cobra.Command) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// object provider
|
// object provider
|
||||||
cmd.PersistentFlags().String("member.object.user_password", "", "member object provider: user password")
|
cmd.PersistentFlags().String("member.object.users", "[]", "member object provider: users in JSON format")
|
||||||
if err := viper.BindPFlag("member.object.user_password", cmd.PersistentFlags().Lookup("member.object.user_password")); err != nil {
|
if err := viper.BindPFlag("member.object.users", cmd.PersistentFlags().Lookup("member.object.users")); err != nil {
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.PersistentFlags().String("member.object.admin_password", "", "member object provider: admin password")
|
|
||||||
if err := viper.BindPFlag("member.object.admin_password", cmd.PersistentFlags().Lookup("member.object.admin_password")); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,8 +59,11 @@ func (s *Member) Set() {
|
|||||||
s.File.Path = viper.GetString("member.file.path")
|
s.File.Path = viper.GetString("member.file.path")
|
||||||
|
|
||||||
// object provider
|
// object provider
|
||||||
s.Object.UserPassword = viper.GetString("member.object.user_password")
|
if err := viper.UnmarshalKey("member.object.users", &s.Object.Users, viper.DecodeHook(
|
||||||
s.Object.AdminPassword = viper.GetString("member.object.admin_password")
|
utils.JsonStringAutoDecode(s.Object.Users),
|
||||||
|
)); err != nil {
|
||||||
|
log.Warn().Err(err).Msgf("unable to parse member object users")
|
||||||
|
}
|
||||||
|
|
||||||
// multiuser provider
|
// multiuser provider
|
||||||
s.Multiuser.UserPassword = viper.GetString("member.multiuser.user_password")
|
s.Multiuser.UserPassword = viper.GetString("member.multiuser.user_password")
|
||||||
|
@ -7,48 +7,20 @@ import (
|
|||||||
func New(config Config) types.MemberProvider {
|
func New(config Config) types.MemberProvider {
|
||||||
return &MemberProviderCtx{
|
return &MemberProviderCtx{
|
||||||
config: config,
|
config: config,
|
||||||
entries: make(map[string]*MemberEntry),
|
entries: make(map[string]*memberEntry),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type MemberProviderCtx struct {
|
type MemberProviderCtx struct {
|
||||||
config Config
|
config Config
|
||||||
entries map[string]*MemberEntry
|
entries map[string]*memberEntry
|
||||||
}
|
}
|
||||||
|
|
||||||
func (provider *MemberProviderCtx) Connect() error {
|
func (provider *MemberProviderCtx) Connect() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if provider.config.AdminPassword != "" {
|
for _, entry := range provider.config.Users {
|
||||||
// create default admin account at startup
|
_, err = provider.Insert(entry.Username, entry.Password, entry.Profile)
|
||||||
_, err = provider.Insert("admin", provider.config.AdminPassword, types.MemberProfile{
|
|
||||||
Name: "Administrator",
|
|
||||||
IsAdmin: true,
|
|
||||||
CanLogin: true,
|
|
||||||
CanConnect: true,
|
|
||||||
CanWatch: true,
|
|
||||||
CanHost: true,
|
|
||||||
CanShareMedia: true,
|
|
||||||
CanAccessClipboard: true,
|
|
||||||
SendsInactiveCursor: true,
|
|
||||||
CanSeeInactiveCursors: true,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if provider.config.UserPassword != "" {
|
|
||||||
// create default user account at startup
|
|
||||||
_, err = provider.Insert("user", provider.config.UserPassword, types.MemberProfile{
|
|
||||||
Name: "User",
|
|
||||||
IsAdmin: false,
|
|
||||||
CanLogin: true,
|
|
||||||
CanConnect: true,
|
|
||||||
CanWatch: true,
|
|
||||||
CanHost: true,
|
|
||||||
CanShareMedia: true,
|
|
||||||
CanAccessClipboard: true,
|
|
||||||
SendsInactiveCursor: true,
|
|
||||||
CanSeeInactiveCursors: false,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
@ -68,11 +40,11 @@ func (provider *MemberProviderCtx) Authenticate(username string, password string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Use hash function.
|
// TODO: Use hash function.
|
||||||
if entry.Password != password {
|
if !entry.CheckPassword(password) {
|
||||||
return "", types.MemberProfile{}, types.ErrMemberInvalidPassword
|
return "", types.MemberProfile{}, types.ErrMemberInvalidPassword
|
||||||
}
|
}
|
||||||
|
|
||||||
return id, entry.Profile, nil
|
return id, entry.profile, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (provider *MemberProviderCtx) Insert(username string, password string, profile types.MemberProfile) (string, error) {
|
func (provider *MemberProviderCtx) Insert(username string, password string, profile types.MemberProfile) (string, error) {
|
||||||
@ -84,10 +56,10 @@ func (provider *MemberProviderCtx) Insert(username string, password string, prof
|
|||||||
return "", types.ErrMemberAlreadyExists
|
return "", types.ErrMemberAlreadyExists
|
||||||
}
|
}
|
||||||
|
|
||||||
provider.entries[id] = &MemberEntry{
|
provider.entries[id] = &memberEntry{
|
||||||
// TODO: Use hash function.
|
// TODO: Use hash function.
|
||||||
Password: password,
|
password: password,
|
||||||
Profile: profile,
|
profile: profile,
|
||||||
}
|
}
|
||||||
|
|
||||||
return id, nil
|
return id, nil
|
||||||
@ -99,7 +71,7 @@ func (provider *MemberProviderCtx) UpdateProfile(id string, profile types.Member
|
|||||||
return types.ErrMemberDoesNotExist
|
return types.ErrMemberDoesNotExist
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.Profile = profile
|
entry.profile = profile
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -111,7 +83,7 @@ func (provider *MemberProviderCtx) UpdatePassword(id string, password string) er
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Use hash function.
|
// TODO: Use hash function.
|
||||||
entry.Password = password
|
entry.password = password
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -122,7 +94,7 @@ func (provider *MemberProviderCtx) Select(id string) (types.MemberProfile, error
|
|||||||
return types.MemberProfile{}, types.ErrMemberDoesNotExist
|
return types.MemberProfile{}, types.ErrMemberDoesNotExist
|
||||||
}
|
}
|
||||||
|
|
||||||
return entry.Profile, nil
|
return entry.profile, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (provider *MemberProviderCtx) SelectAll(limit int, offset int) (map[string]types.MemberProfile, error) {
|
func (provider *MemberProviderCtx) SelectAll(limit int, offset int) (map[string]types.MemberProfile, error) {
|
||||||
@ -131,7 +103,7 @@ func (provider *MemberProviderCtx) SelectAll(limit int, offset int) (map[string]
|
|||||||
i := 0
|
i := 0
|
||||||
for id, entry := range provider.entries {
|
for id, entry := range provider.entries {
|
||||||
if i >= offset && (limit == 0 || i < offset+limit) {
|
if i >= offset && (limit == 0 || i < offset+limit) {
|
||||||
profiles[id] = entry.Profile
|
profiles[id] = entry.profile
|
||||||
}
|
}
|
||||||
|
|
||||||
i = i + 1
|
i = i + 1
|
||||||
|
@ -4,12 +4,21 @@ import (
|
|||||||
"github.com/demodesk/neko/pkg/types"
|
"github.com/demodesk/neko/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MemberEntry struct {
|
type memberEntry struct {
|
||||||
Password string `json:"password"`
|
password string
|
||||||
Profile types.MemberProfile `json:"profile"`
|
profile types.MemberProfile
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *memberEntry) CheckPassword(password string) bool {
|
||||||
|
return m.password == password
|
||||||
|
}
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
Username string
|
||||||
|
Password string
|
||||||
|
Profile types.MemberProfile
|
||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
AdminPassword string
|
Users []User
|
||||||
UserPassword string
|
|
||||||
}
|
}
|
||||||
|
@ -12,15 +12,15 @@ type MemberProfile struct {
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
|
||||||
// permissions
|
// permissions
|
||||||
IsAdmin bool `json:"is_admin"`
|
IsAdmin bool `json:"is_admin" mapstructure:"is_admin"`
|
||||||
CanLogin bool `json:"can_login"`
|
CanLogin bool `json:"can_login" mapstructure:"can_login"`
|
||||||
CanConnect bool `json:"can_connect"`
|
CanConnect bool `json:"can_connect" mapstructure:"can_connect"`
|
||||||
CanWatch bool `json:"can_watch"`
|
CanWatch bool `json:"can_watch" mapstructure:"can_watch"`
|
||||||
CanHost bool `json:"can_host"`
|
CanHost bool `json:"can_host" mapstructure:"can_host"`
|
||||||
CanShareMedia bool `json:"can_share_media"`
|
CanShareMedia bool `json:"can_share_media" mapstructure:"can_share_media"`
|
||||||
CanAccessClipboard bool `json:"can_access_clipboard"`
|
CanAccessClipboard bool `json:"can_access_clipboard" mapstructure:"can_access_clipboard"`
|
||||||
SendsInactiveCursor bool `json:"sends_inactive_cursor"`
|
SendsInactiveCursor bool `json:"sends_inactive_cursor" mapstructure:"sends_inactive_cursor"`
|
||||||
CanSeeInactiveCursors bool `json:"can_see_inactive_cursors"`
|
CanSeeInactiveCursors bool `json:"can_see_inactive_cursors" mapstructure:"can_see_inactive_cursors"`
|
||||||
|
|
||||||
// plugin scope
|
// plugin scope
|
||||||
Plugins map[string]any `json:"plugins"`
|
Plugins map[string]any `json:"plugins"`
|
||||||
|
Loading…
Reference in New Issue
Block a user