forked from tangled.org/core
this repo has no description

appview: improve spindle verification process

Signed-off-by: oppiliappan <me@oppi.li>

oppi.li ad67b46a a1e86cf4

verified
Changed files
+74 -15
appview
db
pages
templates
repo
spindles
repo
spindles
spindle
+7 -2
appview/db/spindle.go
···
for rows.Next() {
var spindle Spindle
var createdAt string
-
var verified sql.NullTime
+
var verified sql.NullString
if err := rows.Scan(
&spindle.Id,
···
}
if verified.Valid {
-
spindle.Verified = &verified.Time
+
t, err := time.Parse(time.RFC3339, verified.String)
+
if err != nil {
+
now := time.Now()
+
spindle.Verified = &now
+
}
+
spindle.Verified = &t
}
spindles = append(spindles, spindle)
+2 -2
appview/pages/templates/repo/new.html
···
</fieldset>
<div class="space-y-2">
-
<button type="submit" class="btn flex gap-2 items-center">
+
<button type="submit" class="btn flex items-center">
create repo
<span id="spinner" class="group">
-
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
+
{{ i "loader-circle" "ml-2 w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
</span>
</button>
<div id="repo" class="error"></div>
+3 -3
appview/pages/templates/repo/settings.html
···
{{ if .RepoInfo.Roles.IsOwner }}
<form
-
hx-put="/{{ $.RepoInfo.FullName }}/settings/spindle"
+
hx-post="/{{ $.RepoInfo.FullName }}/settings/spindle"
class="mt-6 group"
>
<label for="spindle">spindle</label>
···
<option
value="{{ . }}"
class="py-1"
-
{{ if .eq . $.Repo.Spindle }}
+
{{ if eq . $.CurrentSpindle }}
selected
{{ end }}
>
···
<button class="btn my-2 flex items-center" type="text">
<span>delete</span>
<span id="delete-repo-spinner" class="group">
-
{{ i "loader-circle" "pl-2 w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
+
{{ i "loader-circle" "ml-2 w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
</span>
</button>
<span>
+2 -2
appview/pages/templates/spindles/fragments/spindleListing.html
···
<button
class="btn text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 gap-2 group"
title="Delete spindle"
-
hx-delete="/spindles/{{ urlquery .Instance }}"
+
hx-delete="/spindles/{{ .Instance }}"
hx-swap="outerHTML"
hx-target="#spindle-{{.Id}}"
hx-confirm="Are you sure you want to delete the spindle '{{ .Instance }}'?"
···
<button
class="btn gap-2 group"
title="Retry spindle verification"
-
hx-post="/spindles/{{ urlquery .Instance }}/retry"
+
hx-post="/spindles/{{ .Instance }}/retry"
hx-swap="none"
hx-target="#spindle-{{.Id}}"
>
+1
appview/repo/repo.go
···
return
+
// all spindles that this user is a member of
spindles, err := rp.enforcer.GetSpindlesForUser(user.Did)
if err != nil {
log.Println("failed to fetch spindles", err)
+46
appview/spindles/spindles.go
···
)
if err != nil {
s.Logger.Error("failed to fetch spindles", "err", err)
+
w.WriteHeader(http.StatusInternalServerError)
+
return
}
s.Pages.Spindles(w, pages.SpindlesParams{
···
return
}
+
tx, err = s.Db.Begin()
+
if err != nil {
+
l.Error("failed to commit verification info", "err", err)
+
s.Pages.HxRefresh(w)
+
return
+
}
+
defer func() {
+
tx.Rollback()
+
s.Enforcer.E.LoadPolicy()
+
}()
+
+
// mark this spindle as verified in the db
+
_, err = db.VerifySpindle(
+
tx,
+
db.FilterEq("owner", user.Did),
+
db.FilterEq("instance", instance),
+
)
+
+
err = s.Enforcer.AddSpindleOwner(instance, user.Did)
+
if err != nil {
+
l.Error("failed to update ACL", "err", err)
+
s.Pages.HxRefresh(w)
+
return
+
}
+
+
err = tx.Commit()
+
if err != nil {
+
l.Error("failed to commit verification info", "err", err)
+
s.Pages.HxRefresh(w)
+
return
+
}
+
+
err = s.Enforcer.E.SavePolicy()
+
if err != nil {
+
l.Error("failed to update ACL", "err", err)
+
s.Pages.HxRefresh(w)
+
return
+
}
+
// ok
s.Pages.HxRefresh(w)
return
···
db.FilterEq("owner", user.Did),
db.FilterEq("instance", instance),
)
+
if err != nil {
+
l.Error("verification failed", "err", err)
+
fail()
+
return
+
}
verifiedSpindle := db.Spindle{
Id: int(rowId),
+6 -5
spindle/ingester.go
···
if s.cfg.Server.Dev {
domain = s.cfg.Server.ListenAddr
}
-
recordInstance := *record.Instance
+
recordInstance := record.Instance
if recordInstance != domain {
l.Error("domain mismatch", "domain", recordInstance, "expected", domain)
-
return fmt.Errorf("domain mismatch: %s != %s", *record.Instance, domain)
+
return fmt.Errorf("domain mismatch: %s != %s", record.Instance, domain)
}
ok, err := s.e.E.Enforce(did, rbacDomain, rbacDomain, "server:invite")
···
l := s.l.With("component", "ingester", "record", tangled.RepoNSID)
+
l.Info("ingesting repo record")
+
switch e.Commit.Operation {
case models.CommitOperationCreate, models.CommitOperationUpdate:
raw := e.Commit.Record
···
}
domain := s.cfg.Server.Hostname
-
if s.cfg.Server.Dev {
-
domain = s.cfg.Server.ListenAddr
-
}
// no spindle configured for this repo
if record.Spindle == nil {
+
l.Info("no spindle configured", "did", record.Owner, "name", record.Name)
return nil
}
// this repo did not want this spindle
if *record.Spindle != domain {
+
l.Info("different spindle configured", "did", record.Owner, "name", record.Name, "spindle", *record.Spindle, "domain", domain)
return nil
}
+7 -1
spindle/server.go
···
jq := queue.NewQueue(100, 2)
-
collections := []string{tangled.SpindleMemberNSID}
+
collections := []string{
+
tangled.SpindleMemberNSID,
+
tangled.RepoNSID,
+
}
jc, err := jetstream.NewJetstreamClient(cfg.Server.JetstreamEndpoint, "spindle", collections, nil, logger, d, false, false)
if err != nil {
return fmt.Errorf("failed to setup jetstream client: %w", err)
···
mux := chi.NewRouter()
mux.HandleFunc("/events", s.Events)
+
mux.HandleFunc("/owner", func(w http.ResponseWriter, r *http.Request) {
+
w.Write([]byte(s.cfg.Server.Owner))
+
})
mux.HandleFunc("/logs/{knot}/{rkey}/{name}", s.Logs)
return mux
}