spindle: fetch and add existing collaborators when ingesting repos #399

merged
opened by oppi.li targeting master from push-vuzywsvmkwqn
Changed files
+48 -28
appview
pages
templates
repo
settings
repo
knotserver
spindle
+27 -22
appview/pages/templates/repo/settings/pipelines.html
···
<div class="col-span-1 md:col-span-2">
<h2 class="text-sm pb-2 uppercase font-bold">Spindle</h2>
<p class="text-gray-500 dark:text-gray-400">
-
Choose a spindle to execute your workflows on. Spindles can be
-
selfhosted,
+
Choose a spindle to execute your workflows on. Only repository owners
+
can configure spindles. Spindles can be selfhosted,
<a class="text-gray-500 dark:text-gray-400 underline" href="https://tangled.sh/@tangled.sh/core/blob/master/docs/spindle/hosting.md">
click to learn more.
</a>
</p>
</div>
-
<form hx-post="/{{ $.RepoInfo.FullName }}/settings/spindle" class="col-span-1 md:col-span-1 md:justify-self-end group flex gap-2 items-stretch">
-
<select
-
id="spindle"
-
name="spindle"
-
required
-
class="p-1 max-w-64 border border-gray-200 bg-white dark:bg-gray-800 dark:text-white dark:border-gray-700"
-
{{ if not $.RepoInfo.Roles.IsOwner }}disabled{{ end }}>
-
<option value="" disabled selected >
-
Choose a spindle
-
</option>
-
{{ range $.Spindles }}
-
<option value="{{ . }}" class="py-1" {{ if eq . $.CurrentSpindle }}selected{{ end }}>
-
{{ . }}
+
{{ if not $.RepoInfo.Roles.IsOwner }}
+
<div class="col-span-1 md:col-span-1 md:justify-self-end group flex gap-2 items-stretch">
+
{{ or $.CurrentSpindle "No spindle configured" }}
+
</div>
+
{{ else }}
+
<form hx-post="/{{ $.RepoInfo.FullName }}/settings/spindle" class="col-span-1 md:col-span-1 md:justify-self-end group flex gap-2 items-stretch">
+
<select
+
id="spindle"
+
name="spindle"
+
required
+
class="p-1 max-w-64 border border-gray-200 bg-white dark:bg-gray-800 dark:text-white dark:border-gray-700">
+
<option value="" disabled>
+
Choose a spindle
</option>
-
{{ end }}
-
</select>
-
<button class="btn flex gap-2 items-center" type="submit" {{ if not $.RepoInfo.Roles.IsOwner }}disabled{{ end }}>
-
{{ i "check" "size-4" }}
-
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
-
</button>
-
</form>
+
{{ range $.Spindles }}
+
<option value="{{ . }}" class="py-1" {{ if eq . $.CurrentSpindle }}selected{{ end }}>
+
{{ . }}
+
</option>
+
{{ end }}
+
</select>
+
<button class="btn flex gap-2 items-center" type="submit" {{ if not $.RepoInfo.Roles.IsOwner }}disabled{{ end }}>
+
{{ i "check" "size-4" }}
+
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
+
</button>
+
</form>
+
{{ end }}
</div>
{{ end }}
+2 -2
appview/repo/repo.go
···
f, err := rp.repoResolver.Resolve(r)
user := rp.oauth.GetUser(r)
-
// all spindles that this user is a member of
-
spindles, err := rp.enforcer.GetSpindlesForUser(user.Did)
+
// all spindles that the repo owner is a member of
+
spindles, err := rp.enforcer.GetSpindlesForUser(f.OwnerDid())
if err != nil {
log.Println("failed to fetch spindles", err)
return
-1
knotserver/ingester.go
···
defer func() {
eventTime := event.TimeUS
lastTimeUs := eventTime + 1
-
fmt.Println("lastTimeUs", lastTimeUs)
if err := h.db.SaveLastTimeUs(lastTimeUs); err != nil {
err = fmt.Errorf("(deferred) failed to save last time us: %w", err)
}
+19 -3
spindle/ingester.go
···
import (
"context"
"encoding/json"
+
"errors"
"fmt"
-
"path/filepath"
"tangled.sh/tangled.sh/core/api/tangled"
"tangled.sh/tangled.sh/core/eventconsumer"
···
return nil
}
-
func (s *Spindle) ingestRepo(_ context.Context, e *models.Event) error {
+
func (s *Spindle) ingestRepo(ctx context.Context, e *models.Event) error {
var err error
+
did := e.Did
+
resolver := idresolver.DefaultResolver()
l := s.l.With("component", "ingester", "record", tangled.RepoNSID)
···
return fmt.Errorf("failed to add repo: %w", err)
}
+
didSlashRepo, err := securejoin.SecureJoin(record.Owner, record.Name)
+
if err != nil {
+
return err
+
}
+
// add repo to rbac
-
if err := s.e.AddRepo(record.Owner, rbac.ThisServer, filepath.Join(record.Owner, record.Name)); err != nil {
+
if err := s.e.AddRepo(record.Owner, rbac.ThisServer, didSlashRepo); err != nil {
l.Error("failed to add repo to enforcer", "error", err)
return fmt.Errorf("failed to add repo: %w", err)
}
+
// add collaborators to rbac
+
owner, err := resolver.ResolveIdent(ctx, did)
+
if err != nil || owner.Handle.IsInvalidHandle() {
+
return err
+
}
+
if err := s.fetchAndAddCollaborators(ctx, owner, didSlashRepo); err != nil {
+
return err
+
}
+
// add this knot to the event consumer
src := eventconsumer.NewKnotSource(record.Knot)
s.ks.AddSource(context.Background(), src)