forked from tangled.org/core
Monorepo for Tangled — https://tangled.org

finish repo-settings page

Changed files
+52 -16
appview
pages
state
rbac
+4 -2
appview/pages/pages.go
···
}
type RepoSettingsParams struct {
-
LoggedInUser *auth.User
-
Collaborators [][]string
+
LoggedInUser *auth.User
+
RepoInfo RepoInfo
+
Collaborators [][]string
+
IsCollaboratorInviteAllowed bool
}
func (p *Pages) RepoSettings(w io.Writer, params RepoSettingsParams) error {
-3
appview/pages/templates/layouts/repobase.html
···
{{ end }}
</div>
-
{{ with .IsEmpty }}
-
{{ else }}
<div id="repo-links">
<nav>
<a href="/{{ .RepoInfo.FullName }}">summary</a>&nbsp;·
···
{{ end }}
</nav>
<div>
-
{{ end }}
{{ block "repoContent" . }} {{ end }}
+3 -4
appview/pages/templates/repo/branches.html
···
branches | {{ .RepoInfo.FullName }}
{{ end }}
-
{{ define "content" }}
-
{{ $name := .RepoInfo.Name }}
+
{{ define "repoContent" }}
<h3>branches</h3>
<div class="refs">
{{ range .Branches }}
<div>
<strong>{{ .Name }}</strong>
-
<a href="/{{ $name }}/tree/{{ .Name }}/">browse</a>
-
<a href="/{{ $name }}/log/{{ .Name }}">log</a>
+
<a href="/{{ $.RepoInfo.FullName }}/tree/{{ .Name }}/">browse</a>
+
<a href="/{{ $.RepoInfo.FullName }}/log/{{ .Name }}">log</a>
</div>
{{ end }}
</div>
+21 -4
appview/pages/templates/repo/settings.html
···
-
{{define "repoContent"}}
-
<main>
-
<h1>settings</h1>
-
</main>
+
{{ define "repoContent" }}
+
<h3>settings</h3>
+
<em>collaborators</em>
+
<ol>
+
{{ range .Collaborators }}
+
<li>
+
{{ index . 0 }} - {{ index . 3 }}
+
</li>
+
{{ else }}
+
<p>no members</p>
+
{{ end }}
+
</ol>
+
+
{{ if .IsCollaboratorInviteAllowed }}
+
<h3>add collaborator</h3>
+
<form hx-put="/{{ $.RepoInfo.FullName }}/settings/collaborator">
+
<label for="collaborator">did or handle:</label>
+
<input type="text" id="collaborator" name="collaborator" required>
+
<button type="text">add collaborator</button>
+
</form>
+
{{ end }}
{{end}}
+19 -2
appview/state/repo.go
···
return
}
+
log.Println(result)
+
user := s.auth.GetUser(r)
s.pages.RepoBranches(w, pages.RepoBranchesParams{
LoggedInUser: user,
···
}
log.Println(repoCollaborators)
+
isCollaboratorInviteAllowed := false
+
if user != nil {
+
ok, err := s.enforcer.IsCollaboratorInviteAllowed(user.Did, f.Knot, f.OwnerSlashRepo())
+
if err == nil && ok {
+
isCollaboratorInviteAllowed = true
+
}
+
}
+
s.pages.RepoSettings(w, pages.RepoSettingsParams{
-
LoggedInUser: user,
-
Collaborators: repoCollaborators,
+
LoggedInUser: user,
+
RepoInfo: pages.RepoInfo{
+
OwnerDid: f.OwnerDid(),
+
OwnerHandle: f.OwnerHandle(),
+
Name: f.RepoName,
+
SettingsAllowed: settingsAllowed(s, user, f),
+
},
+
Collaborators: repoCollaborators,
+
IsCollaboratorInviteAllowed: isCollaboratorInviteAllowed,
})
}
}
+1 -1
appview/state/signer.go
···
const (
Method = "POST"
)
-
endpoint := fmt.Sprintf("/{ownerDid}/{repoName}/collaborator/add")
+
endpoint := fmt.Sprintf("/%s/%s/collaborator/add", ownerDid, repoName)
body, _ := json.Marshal(map[string]interface{}{
"did": memberDid,
+4
rbac/rbac.go
···
return e.E.Enforce(user, domain, repo, "repo:settings")
}
+
func (e *Enforcer) IsCollaboratorInviteAllowed(user, domain, repo string) (bool, error) {
+
return e.E.Enforce(user, domain, repo, "repo:invite")
+
}
+
// keyMatch2Func is a wrapper for keyMatch2 to make it compatible with Casbin
func keyMatch2Func(args ...interface{}) (interface{}, error) {
name1 := args[0].(string)