forked from tangled.org/core
Monorepo for Tangled

appview: improve spindle verification process

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

oppi.li 2a45e84f 45882b6b

verified
Changed files
+74 -15
appview
db
pages
templates
repo
spindles
repo
spindles
spindle
+7 -2
appview/db/spindle.go
··· 51 51 for rows.Next() { 52 52 var spindle Spindle 53 53 var createdAt string 54 - var verified sql.NullTime 54 + var verified sql.NullString 55 55 56 56 if err := rows.Scan( 57 57 &spindle.Id, ··· 69 69 } 70 70 71 71 if verified.Valid { 72 - spindle.Verified = &verified.Time 72 + t, err := time.Parse(time.RFC3339, verified.String) 73 + if err != nil { 74 + now := time.Now() 75 + spindle.Verified = &now 76 + } 77 + spindle.Verified = &t 73 78 } 74 79 75 80 spindles = append(spindles, spindle)
+2 -2
appview/pages/templates/repo/new.html
··· 60 60 </fieldset> 61 61 62 62 <div class="space-y-2"> 63 - <button type="submit" class="btn flex gap-2 items-center"> 63 + <button type="submit" class="btn flex items-center"> 64 64 create repo 65 65 <span id="spinner" class="group"> 66 - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 66 + {{ i "loader-circle" "ml-2 w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 67 67 </span> 68 68 </button> 69 69 <div id="repo" class="error"></div>
+3 -3
appview/pages/templates/repo/settings.html
··· 83 83 84 84 {{ if .RepoInfo.Roles.IsOwner }} 85 85 <form 86 - hx-put="/{{ $.RepoInfo.FullName }}/settings/spindle" 86 + hx-post="/{{ $.RepoInfo.FullName }}/settings/spindle" 87 87 class="mt-6 group" 88 88 > 89 89 <label for="spindle">spindle</label> ··· 100 100 <option 101 101 value="{{ . }}" 102 102 class="py-1" 103 - {{ if .eq . $.Repo.Spindle }} 103 + {{ if eq . $.CurrentSpindle }} 104 104 selected 105 105 {{ end }} 106 106 > ··· 127 127 <button class="btn my-2 flex items-center" type="text"> 128 128 <span>delete</span> 129 129 <span id="delete-repo-spinner" class="group"> 130 - {{ i "loader-circle" "pl-2 w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 130 + {{ i "loader-circle" "ml-2 w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 131 131 </span> 132 132 </button> 133 133 <span>
+2 -2
appview/pages/templates/spindles/fragments/spindleListing.html
··· 24 24 <button 25 25 class="btn text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 gap-2 group" 26 26 title="Delete spindle" 27 - hx-delete="/spindles/{{ urlquery .Instance }}" 27 + hx-delete="/spindles/{{ .Instance }}" 28 28 hx-swap="outerHTML" 29 29 hx-target="#spindle-{{.Id}}" 30 30 hx-confirm="Are you sure you want to delete the spindle '{{ .Instance }}'?" ··· 40 40 <button 41 41 class="btn gap-2 group" 42 42 title="Retry spindle verification" 43 - hx-post="/spindles/{{ urlquery .Instance }}/retry" 43 + hx-post="/spindles/{{ .Instance }}/retry" 44 44 hx-swap="none" 45 45 hx-target="#spindle-{{.Id}}" 46 46 >
+1
appview/repo/repo.go
··· 1108 1108 return 1109 1109 } 1110 1110 1111 + // all spindles that this user is a member of 1111 1112 spindles, err := rp.enforcer.GetSpindlesForUser(user.Did) 1112 1113 if err != nil { 1113 1114 log.Println("failed to fetch spindles", err)
+46
appview/spindles/spindles.go
··· 54 54 ) 55 55 if err != nil { 56 56 s.Logger.Error("failed to fetch spindles", "err", err) 57 + w.WriteHeader(http.StatusInternalServerError) 58 + return 57 59 } 58 60 59 61 s.Pages.Spindles(w, pages.SpindlesParams{ ··· 150 152 return 151 153 } 152 154 155 + tx, err = s.Db.Begin() 156 + if err != nil { 157 + l.Error("failed to commit verification info", "err", err) 158 + s.Pages.HxRefresh(w) 159 + return 160 + } 161 + defer func() { 162 + tx.Rollback() 163 + s.Enforcer.E.LoadPolicy() 164 + }() 165 + 166 + // mark this spindle as verified in the db 167 + _, err = db.VerifySpindle( 168 + tx, 169 + db.FilterEq("owner", user.Did), 170 + db.FilterEq("instance", instance), 171 + ) 172 + 173 + err = s.Enforcer.AddSpindleOwner(instance, user.Did) 174 + if err != nil { 175 + l.Error("failed to update ACL", "err", err) 176 + s.Pages.HxRefresh(w) 177 + return 178 + } 179 + 180 + err = tx.Commit() 181 + if err != nil { 182 + l.Error("failed to commit verification info", "err", err) 183 + s.Pages.HxRefresh(w) 184 + return 185 + } 186 + 187 + err = s.Enforcer.E.SavePolicy() 188 + if err != nil { 189 + l.Error("failed to update ACL", "err", err) 190 + s.Pages.HxRefresh(w) 191 + return 192 + } 193 + 153 194 // ok 154 195 s.Pages.HxRefresh(w) 155 196 return ··· 255 296 db.FilterEq("owner", user.Did), 256 297 db.FilterEq("instance", instance), 257 298 ) 299 + if err != nil { 300 + l.Error("verification failed", "err", err) 301 + fail() 302 + return 303 + } 258 304 259 305 verifiedSpindle := db.Spindle{ 260 306 Id: int(rowId),
+6 -5
spindle/ingester.go
··· 59 59 if s.cfg.Server.Dev { 60 60 domain = s.cfg.Server.ListenAddr 61 61 } 62 - recordInstance := *record.Instance 62 + recordInstance := record.Instance 63 63 64 64 if recordInstance != domain { 65 65 l.Error("domain mismatch", "domain", recordInstance, "expected", domain) 66 - return fmt.Errorf("domain mismatch: %s != %s", *record.Instance, domain) 66 + return fmt.Errorf("domain mismatch: %s != %s", record.Instance, domain) 67 67 } 68 68 69 69 ok, err := s.e.E.Enforce(did, rbacDomain, rbacDomain, "server:invite") ··· 95 95 96 96 l := s.l.With("component", "ingester", "record", tangled.RepoNSID) 97 97 98 + l.Info("ingesting repo record") 99 + 98 100 switch e.Commit.Operation { 99 101 case models.CommitOperationCreate, models.CommitOperationUpdate: 100 102 raw := e.Commit.Record ··· 106 108 } 107 109 108 110 domain := s.cfg.Server.Hostname 109 - if s.cfg.Server.Dev { 110 - domain = s.cfg.Server.ListenAddr 111 - } 112 111 113 112 // no spindle configured for this repo 114 113 if record.Spindle == nil { 114 + l.Info("no spindle configured", "did", record.Owner, "name", record.Name) 115 115 return nil 116 116 } 117 117 118 118 // this repo did not want this spindle 119 119 if *record.Spindle != domain { 120 + l.Info("different spindle configured", "did", record.Owner, "name", record.Name, "spindle", *record.Spindle, "domain", domain) 120 121 return nil 121 122 } 122 123
+7 -1
spindle/server.go
··· 66 66 67 67 jq := queue.NewQueue(100, 2) 68 68 69 - collections := []string{tangled.SpindleMemberNSID} 69 + collections := []string{ 70 + tangled.SpindleMemberNSID, 71 + tangled.RepoNSID, 72 + } 70 73 jc, err := jetstream.NewJetstreamClient(cfg.Server.JetstreamEndpoint, "spindle", collections, nil, logger, d, false, false) 71 74 if err != nil { 72 75 return fmt.Errorf("failed to setup jetstream client: %w", err) ··· 140 143 mux := chi.NewRouter() 141 144 142 145 mux.HandleFunc("/events", s.Events) 146 + mux.HandleFunc("/owner", func(w http.ResponseWriter, r *http.Request) { 147 + w.Write([]byte(s.cfg.Server.Owner)) 148 + }) 143 149 mux.HandleFunc("/logs/{knot}/{rkey}/{name}", s.Logs) 144 150 return mux 145 151 }