+4
-2
appview/pages/pages.go
+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
-3
appview/pages/templates/layouts/repobase.html
+3
-4
appview/pages/templates/repo/branches.html
+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
+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
+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
+1
-1
appview/state/signer.go
+4
rbac/rbac.go
+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)