forked from tangled.org/core
Monorepo for Tangled

finish repo-settings page

Changed files
+52 -16
appview
pages
state
rbac
+4 -2
appview/pages/pages.go
··· 242 242 } 243 243 244 244 type RepoSettingsParams struct { 245 - LoggedInUser *auth.User 246 - Collaborators [][]string 245 + LoggedInUser *auth.User 246 + RepoInfo RepoInfo 247 + Collaborators [][]string 248 + IsCollaboratorInviteAllowed bool 247 249 } 248 250 249 251 func (p *Pages) RepoSettings(w io.Writer, params RepoSettingsParams) error {
-3
appview/pages/templates/layouts/repobase.html
··· 11 11 {{ end }} 12 12 </div> 13 13 14 - {{ with .IsEmpty }} 15 - {{ else }} 16 14 <div id="repo-links"> 17 15 <nav> 18 16 <a href="/{{ .RepoInfo.FullName }}">summary</a>&nbsp;· ··· 23 21 {{ end }} 24 22 </nav> 25 23 <div> 26 - {{ end }} 27 24 28 25 {{ block "repoContent" . }} {{ end }} 29 26
+3 -4
appview/pages/templates/repo/branches.html
··· 2 2 branches | {{ .RepoInfo.FullName }} 3 3 {{ end }} 4 4 5 - {{ define "content" }} 6 - {{ $name := .RepoInfo.Name }} 5 + {{ define "repoContent" }} 7 6 <h3>branches</h3> 8 7 <div class="refs"> 9 8 {{ range .Branches }} 10 9 <div> 11 10 <strong>{{ .Name }}</strong> 12 - <a href="/{{ $name }}/tree/{{ .Name }}/">browse</a> 13 - <a href="/{{ $name }}/log/{{ .Name }}">log</a> 11 + <a href="/{{ $.RepoInfo.FullName }}/tree/{{ .Name }}/">browse</a> 12 + <a href="/{{ $.RepoInfo.FullName }}/log/{{ .Name }}">log</a> 14 13 </div> 15 14 {{ end }} 16 15 </div>
+21 -4
appview/pages/templates/repo/settings.html
··· 1 - {{define "repoContent"}} 2 - <main> 3 - <h1>settings</h1> 4 - </main> 1 + {{ define "repoContent" }} 2 + <h3>settings</h3> 3 + <em>collaborators</em> 4 + <ol> 5 + {{ range .Collaborators }} 6 + <li> 7 + {{ index . 0 }} - {{ index . 3 }} 8 + </li> 9 + {{ else }} 10 + <p>no members</p> 11 + {{ end }} 12 + </ol> 13 + 14 + {{ if .IsCollaboratorInviteAllowed }} 15 + <h3>add collaborator</h3> 16 + <form hx-put="/{{ $.RepoInfo.FullName }}/settings/collaborator"> 17 + <label for="collaborator">did or handle:</label> 18 + <input type="text" id="collaborator" name="collaborator" required> 19 + <button type="text">add collaborator</button> 20 + </form> 21 + {{ end }} 5 22 {{end}} 6 23
+19 -2
appview/state/repo.go
··· 251 251 return 252 252 } 253 253 254 + log.Println(result) 255 + 254 256 user := s.auth.GetUser(r) 255 257 s.pages.RepoBranches(w, pages.RepoBranchesParams{ 256 258 LoggedInUser: user, ··· 379 381 } 380 382 log.Println(repoCollaborators) 381 383 384 + isCollaboratorInviteAllowed := false 385 + if user != nil { 386 + ok, err := s.enforcer.IsCollaboratorInviteAllowed(user.Did, f.Knot, f.OwnerSlashRepo()) 387 + if err == nil && ok { 388 + isCollaboratorInviteAllowed = true 389 + } 390 + } 391 + 382 392 s.pages.RepoSettings(w, pages.RepoSettingsParams{ 383 - LoggedInUser: user, 384 - Collaborators: repoCollaborators, 393 + LoggedInUser: user, 394 + RepoInfo: pages.RepoInfo{ 395 + OwnerDid: f.OwnerDid(), 396 + OwnerHandle: f.OwnerHandle(), 397 + Name: f.RepoName, 398 + SettingsAllowed: settingsAllowed(s, user, f), 399 + }, 400 + Collaborators: repoCollaborators, 401 + IsCollaboratorInviteAllowed: isCollaboratorInviteAllowed, 385 402 }) 386 403 } 387 404 }
+1 -1
appview/state/signer.go
··· 118 118 const ( 119 119 Method = "POST" 120 120 ) 121 - endpoint := fmt.Sprintf("/{ownerDid}/{repoName}/collaborator/add") 121 + endpoint := fmt.Sprintf("/%s/%s/collaborator/add", ownerDid, repoName) 122 122 123 123 body, _ := json.Marshal(map[string]interface{}{ 124 124 "did": memberDid,
+4
rbac/rbac.go
··· 163 163 return e.E.Enforce(user, domain, repo, "repo:settings") 164 164 } 165 165 166 + func (e *Enforcer) IsCollaboratorInviteAllowed(user, domain, repo string) (bool, error) { 167 + return e.E.Enforce(user, domain, repo, "repo:invite") 168 + } 169 + 166 170 // keyMatch2Func is a wrapper for keyMatch2 to make it compatible with Casbin 167 171 func keyMatch2Func(args ...interface{}) (interface{}, error) { 168 172 name1 := args[0].(string)