Skip to content

Commit

Permalink
Lots of tricky things here
Browse files Browse the repository at this point in the history
Made sure all the migration to slugs within the settings is complete. I
think I still need to remove it from the database as its own field.

Fixed an events recovery bug, where the session needs to be captured and
"recreated"... aka restore the session token to the context.

Along the context lines, make use of context.WithoutCancel() to continue
passing the context around with all its values but in a way that can
persist across the http request ending.

Also made a few more things dynamic in the profile and migrated the
callsign finder to the finder interface. This way it can get cached.
  • Loading branch information
ryanfaerman committed Feb 16, 2024
1 parent 993ff09 commit 4551e45
Show file tree
Hide file tree
Showing 21 changed files with 199 additions and 82 deletions.
33 changes: 33 additions & 0 deletions internal/events/membership.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package events

import "time"

func init() {
register[MembershipRequested]("membership.requested")
register[MembershipAccepted]("membership.accepted")
register[MembershipDenied]("membership.denied")
register[MembershipRevoked]("membership.revoked")
}

type (
MembershipRequested struct {
Message string `json:"message"`
}

MembershipAccepted struct {
Message string `json:"message"`
}

MembershipDenied struct {
Until time.Time `json:"until"`
Message string `json:"message"`
}

MembershipRevoked struct {
Message string `json:"message"`
}

MembershipEnded struct {
Message string `json:"message"`
}
)
2 changes: 1 addition & 1 deletion internal/handlers/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func (h account) Show(w http.ResponseWriter, r *http.Request) {
}

if slug == "" && slug != user.Slug {
http.Redirect(w, r, named.URLFor("account-profile", user.Callsign().Call), http.StatusSeeOther)
http.Redirect(w, r, named.URLFor("account-profile", user.Callsign(r.Context()).Call), http.StatusSeeOther)
return
}

Expand Down
2 changes: 2 additions & 0 deletions internal/handlers/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,8 @@ func (h settings) SettingsSave(w http.ResponseWriter, r *http.Request) {
return
}
default:
fmt.Println("settings handler calling save settings")
spew.Dump(settings)
if err := services.Account.SaveSettings(ctx, account.ID, &settings); err != nil {
ErrorHandler(err)(w, r)
return
Expand Down
54 changes: 12 additions & 42 deletions internal/models/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,15 +147,15 @@ func (u *Account) Emails() ([]*Email, error) {
return Find[Email](context.Background(), ByAccount(u.ID))
}

func (m *Account) PrimaryEmail() (Email, error) {
func (m *Account) PrimaryEmail() Email {
emails, err := m.Emails()
if err != nil {
return Email{}, err
return Email{}
}
if len(emails) > 0 {
return *emails[0], nil
return *emails[0]
}
return Email{}, errors.New("no primary email")
return Email{}
}

func (m *Account) Members(ctx context.Context) []*Membership {
Expand Down Expand Up @@ -217,57 +217,27 @@ func FindAccountByCallsign(ctx context.Context, callsign string) (*Account, erro
return FindOne[Account](ctx, ByCallsign(callsign))
}

func (u *Account) Callsigns() ([]Callsign, error) {
if len(u.callsigns) > 0 {
return u.callsigns, nil
}
var callsigns []Callsign
rows, err := global.dao.FindCallsignsForAccount(context.Background(), u.ID)
if err != nil {
return callsigns, err
}
for _, row := range rows {
callsign := Callsign{
ID: row.ID,
Call: row.Callsign,
Expires: row.Expires.Time,
Status: row.Status,
Latitude: row.Latitude.Float64,
Longitude: row.Longitude.Float64,
Firstname: row.Firstname.String,
Middlename: row.Middlename.String,
Lastname: row.Lastname.String,
Suffix: row.Suffix.String,
Address: row.Address.String,
City: row.City.String,
State: row.State.String,
Zip: row.Zip.String,
Country: row.Country.String,
}
callsigns = append(callsigns, callsign)
}
u.callsigns = callsigns

return callsigns, nil
func (u *Account) Callsigns(ctx context.Context) ([]*Callsign, error) {
return Find[Callsign](ctx, ByAccount(u.ID))
}

func (m *Account) Callsign() Callsign {
calls, err := m.Callsigns()
func (m *Account) Callsign(ctx context.Context) *Callsign {
calls, err := m.Callsigns(ctx)
if err != nil {
return Callsign{}
return &Callsign{}
}
if len(calls) == 0 {
return Callsign{}
return &Callsign{}
}

return calls[0]
}

func (m *Account) Location() (float64, float64) {
func (m *Account) Location(ctx context.Context) (float64, float64) {
if m.Settings.LocationSettings.HasLocation() {
return m.Settings.LocationSettings.Location()
}
callsign := m.Callsign()
callsign := m.Callsign(ctx)
return callsign.Latitude, callsign.Longitude
}

Expand Down
14 changes: 6 additions & 8 deletions internal/models/account_finder.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"encoding/json"
"time"

"github.com/davecgh/go-spew/spew"

"github.com/ryanfaerman/netctl/internal/dao"
"github.com/ryanfaerman/netctl/internal/models/finders"
)
Expand Down Expand Up @@ -136,11 +138,14 @@ func (m Account) Find(ctx context.Context, queries finders.QuerySet) (any, error
return nil, err
}

spew.Dump(a.Settings)

a.Name = a.Settings.ProfileSettings.Name
a.About = a.Settings.ProfileSettings.About
a.Slug = a.Settings.ProfileSettings.Slug

if !a.Settings.LocationSettings.HasLocation() {
callsigns, err := a.Callsigns()
callsigns, err := a.Callsigns(ctx)
if err == nil {
if len(callsigns) > 0 {
callsign := callsigns[0]
Expand All @@ -150,13 +155,6 @@ func (m Account) Find(ctx context.Context, queries finders.QuerySet) (any, error
}
}

switch {
case queries.HasField("callsigns"):
if _, err := (&a).Callsigns(); err != nil {
return nil, err
}
}

found[i] = &a
}

Expand Down
8 changes: 8 additions & 0 deletions internal/models/callsign.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package models

import (
"fmt"
"time"

"github.com/ryanfaerman/netctl/hamdb"
)

type Callsign struct {
Expand All @@ -26,3 +29,8 @@ type Callsign struct {
CreatedAt time.Time
UpdatedAt time.Time
}

func (m Callsign) LicenseClass() string {
fmt.Println(m.Class)
return hamdb.LicenseClass(m.Class).String()
}
65 changes: 65 additions & 0 deletions internal/models/callsign_finder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package models

import (
"context"
"time"

"github.com/ryanfaerman/netctl/internal/dao"
"github.com/ryanfaerman/netctl/internal/models/finders"
)

func (m Callsign) FindCacheKey() string {
return "callsigns"
}

func (m Callsign) FindCacheDuration() time.Duration {
return 7 * 24 * time.Hour
}

func (m Callsign) Find(ctx context.Context, queries finders.QuerySet) (any, error) {
var (
raws []dao.Callsign
err error
found []*Callsign
)

switch {
default:
return nil, finders.ErrInvalidWhere
case queries.HasWhere("account_id"):
accountID, ok := finders.EnforceValue[int64](queries, "account_id")
if ok != nil {
return nil, ok
}
raws, err = global.dao.FindCallsignsForAccount(ctx, accountID)

}

if err != nil {
return nil, err
}

found = make([]*Callsign, len(raws))
for i, raw := range raws {
found[i] = &Callsign{
ID: raw.ID,
Call: raw.Callsign,
Class: raw.Class,
Expires: raw.Expires.Time,
Status: raw.Status,
Latitude: raw.Latitude.Float64,
Longitude: raw.Longitude.Float64,
Firstname: raw.Firstname.String,
Middlename: raw.Middlename.String,
Lastname: raw.Lastname.String,
Suffix: raw.Suffix.String,
Address: raw.Address.String,
City: raw.City.String,
State: raw.State.String,
Zip: raw.Zip.String,
Country: raw.Country.String,
}
}

return found, nil
}
2 changes: 2 additions & 0 deletions internal/models/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ func FindEventsForCallsign(eventType string, callsign string) (EventStream, erro

type RecoveredEvent struct {
RegisteredFn string
SessionToken string
Event Event
ID int64
}
Expand All @@ -107,6 +108,7 @@ func FindRecoverableEvents(ctx context.Context) ([]RecoveredEvent, error) {
stream[i] = RecoveredEvent{
ID: raw.RecoveryID,
RegisteredFn: raw.RegisteredFn,
SessionToken: raw.SessionToken,
Event: Event{
ID: raw.ID,
At: raw.Created,
Expand Down
15 changes: 13 additions & 2 deletions internal/models/membership.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,25 @@ import (
"github.com/ryanfaerman/netctl/internal/models/finders"
)

type MembershipStatus int

const (
MembershipStatusPending MembershipStatus = iota
MembershipStatusActive
MembershipStatusDenied
MembershipStatusBanned
MembershipStatusInactive
)

type Membership struct {
CreatedAt time.Time
AccountID int64

TargetID int64
RoleID int64

CreatedAt time.Time
ID int64
ID int64
Status MembershipStatus
}

func (m *Membership) Account(ctx context.Context) *Account {
Expand Down
12 changes: 5 additions & 7 deletions internal/services/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,12 +188,7 @@ func (s account) AvatarURL(ctx context.Context, slugs ...string) string {
return ""
}

email, err := account.PrimaryEmail()
if err != nil {
fmt.Println("error getting primary email", "error", err)
return ""
}
fmt.Println(email.Address)
email := account.PrimaryEmail()

h := sha256.New()
h.Write([]byte(strings.TrimSpace(strings.ToLower(email.Address))))
Expand All @@ -215,6 +210,8 @@ func (a account) SaveSettings(ctx context.Context, id int64, settings *models.Se
if err != nil {
return err
}
fmt.Println("args")
spew.Dump(settings)

if err := mergo.Merge(&account.Settings, settings, mergo.WithOverride); err != nil {
return err
Expand All @@ -223,6 +220,7 @@ func (a account) SaveSettings(ctx context.Context, id int64, settings *models.Se
if err := Validation.Apply(account.Settings); err != nil {
return err
}
spew.Dump(account.Settings)

data, err := json.Marshal(account.Settings)
if err != nil {
Expand All @@ -244,7 +242,7 @@ func (a account) SaveSettings(ctx context.Context, id int64, settings *models.Se
}

func (s account) Geolocation(ctx context.Context, m *models.Account) (float64, float64, error) {
call := m.Callsign()
call := m.Callsign(ctx)
return call.Latitude, call.Longitude, nil
}

Expand Down
Loading

0 comments on commit 4551e45

Please sign in to comment.