Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix rendering non-members on the dashboard #238

Merged
merged 3 commits into from
Jun 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 32 additions & 11 deletions web/handlers/admin/dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package admin

import (
"errors"
"fmt"
"net/http"
"time"
Expand All @@ -29,6 +30,7 @@ type dashboardHandler struct {

func (h dashboardHandler) overview(w http.ResponseWriter, req *http.Request) (interface{}, error) {
var (
err error
ctx = req.Context()
roomRef = h.netInfo.RoomID.Ref()

Expand All @@ -54,13 +56,19 @@ func (h dashboardHandler) overview(w http.ResponseWriter, req *http.Request) (in
}

// in the timeout case, nothing will happen here since the onlineRefs slice is empty
onlineMembers := make([]roomdb.Member, len(onlineRefs))
onlineUsers := make([]connectedUser, len(onlineRefs))
for i, ref := range onlineRefs {
var err error
onlineMembers[i], err = h.dbs.Members.GetByFeed(ctx, ref)
// try to get the member
onlineUsers[i].Member, err = h.dbs.Members.GetByFeed(ctx, ref)
if err != nil {
// TODO: do we want to show "external users" (non-members) on the dashboard?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The answer to that TODO comment apparently is "yes" 😄

return nil, fmt.Errorf("failed to lookup online member: %w", err)
if !errors.Is(err, roomdb.ErrNotFound) { // any other error can't be handled here
return nil, fmt.Errorf("failed to lookup online member: %w", err)
}

// if there is no member for this ref present it as role unknown
onlineUsers[i].ID = -1
onlineUsers[i].PubKey = ref
onlineUsers[i].Role = roomdb.RoleUnknown
}
}

Expand All @@ -80,12 +88,12 @@ func (h dashboardHandler) overview(w http.ResponseWriter, req *http.Request) (in
}

pageData := map[string]interface{}{
"RoomRef": roomRef,
"OnlineMembers": onlineMembers,
"OnlineCount": onlineCount,
"MemberCount": memberCount,
"InviteCount": inviteCount,
"DeniedCount": deniedCount,
"RoomRef": roomRef,
"OnlineUsers": onlineUsers,
"OnlineCount": onlineCount,
"MemberCount": memberCount,
"InviteCount": inviteCount,
"DeniedCount": deniedCount,
}

pageData["Flashes"], err = h.flashes.GetAll(w, req)
Expand All @@ -95,3 +103,16 @@ func (h dashboardHandler) overview(w http.ResponseWriter, req *http.Request) (in

return pageData, nil
}

// connectedUser defines how we want to present a connected user
type connectedUser struct {
roomdb.Member
}

// if the member has an alias, use the first one. Otherwise use the public key
func (dm connectedUser) String() string {
if len(dm.Aliases) > 0 {
return dm.Aliases[0].Name
}
return dm.PubKey.Ref()
}
82 changes: 82 additions & 0 deletions web/handlers/admin/dashboard_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package admin

import (
"bytes"
"context"
"net/http"
"testing"

"github.com/ssb-ngi-pointer/go-ssb-room/v2/roomdb"
"github.com/ssb-ngi-pointer/go-ssb-room/v2/web/router"
"github.com/ssb-ngi-pointer/go-ssb-room/v2/web/webassert"
"github.com/stretchr/testify/assert"
refs "go.mindeco.de/ssb-refs"
)

func TestDashboardSimple(t *testing.T) {
ts := newSession(t)
a := assert.New(t)

testRef := refs.FeedRef{Algo: "ed25519", ID: bytes.Repeat([]byte{0}, 32)}
ts.RoomState.AddEndpoint(testRef, nil) // 1 online
ts.MembersDB.CountReturns(4, nil) // 4 members
ts.InvitesDB.CountReturns(3, nil) // 3 invites
ts.DeniedKeysDB.CountReturns(2, nil) // 2 banned

dashURL := ts.URLTo(router.AdminDashboard)

html, resp := ts.Client.GetHTML(dashURL)
a.Equal(http.StatusOK, resp.Code, "wrong HTTP status code")

a.Equal("1", html.Find("#online-count").Text())
a.Equal("4", html.Find("#member-count").Text())
a.Equal("3", html.Find("#invite-count").Text())
a.Equal("2", html.Find("#denied-count").Text())

webassert.Localized(t, html, []webassert.LocalizedElement{
{"title", "AdminDashboardTitle"},
})
}

// make sure the dashboard renders when someone is connected that is not a member
func TestDashboardWithVisitors(t *testing.T) {
ts := newSession(t)
a := assert.New(t)

visitorRef := refs.FeedRef{Algo: "ed25519", ID: bytes.Repeat([]byte{0}, 32)}
memberRef := refs.FeedRef{Algo: "ed25519", ID: bytes.Repeat([]byte{1}, 32)}
ts.RoomState.AddEndpoint(visitorRef, nil)
ts.RoomState.AddEndpoint(memberRef, nil)

ts.MembersDB.CountReturns(1, nil)
// return a member for the member but not for the visitor
ts.MembersDB.GetByFeedStub = func(ctx context.Context, r refs.FeedRef) (roomdb.Member, error) {
if r.Equal(&memberRef) {
return roomdb.Member{ID: 23, Role: roomdb.RoleMember, PubKey: r}, nil
}
return roomdb.Member{}, roomdb.ErrNotFound
}

dashURL := ts.URLTo(router.AdminDashboard)

html, resp := ts.Client.GetHTML(dashURL)
a.Equal(http.StatusOK, resp.Code, "wrong HTTP status code")

a.Equal("2", html.Find("#online-count").Text())
a.Equal("1", html.Find("#member-count").Text())

memberList := html.Find("#connected-list a")
a.Equal(2, memberList.Length())

htmlVisitor := memberList.Eq(0)
a.Equal(visitorRef.Ref(), htmlVisitor.Text())
gotLink, has := htmlVisitor.Attr("href")
a.False(has, "visitor should not have a link to a details page: %v", gotLink)

htmlMember := memberList.Eq(1)
a.Equal(memberRef.Ref(), htmlMember.Text())
gotLink, has = htmlMember.Attr("href")
a.True(has, "member should have a link to a details page")
wantLink := ts.URLTo(router.AdminMemberDetails, "id", 23)
a.Equal(wantLink.String(), gotLink)
}
37 changes: 0 additions & 37 deletions web/handlers/admin/handler_test.go

This file was deleted.

16 changes: 5 additions & 11 deletions web/templates/admin/dashboard.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -80,27 +80,21 @@
</div>
</div>

<div class="mb-8">
<div class="mb-8" id="connected-list">
{{if gt .OnlineCount 0}}
<div class="ml-11 h-8 w-0.5 bg-gray-200"></div>
{{end}}

{{range .OnlineMembers}}
{{$member := .PubKey.Ref}}
{{$memberIsAlias := false}}
{{range $index, $alias := .Aliases}}
{{if eq $index 0}}
{{$member = $alias.Name}}
{{$memberIsAlias = true}}
{{end}}
{{end}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sweet to pull that logic into Go

{{range .OnlineUsers}}
<div class="ml-11 h-8 w-0.5 bg-gray-200"></div>
<div class="ml-11 relative h-3">
<div class="absolute inline-flex w-3 h-3 bg-green-500 rounded-full -left-1 -ml-px"></div>
<a
{{if gt .ID 0}}
href="{{urlTo "admin:member:details" "id" .ID}}"
{{end}}
class="absolute w-44 sm:w-auto -top-1.5 ml-5 pl-1 font-mono truncate flex-auto text-gray-700 hover:underline"
>{{$member}}</a>
>{{.String}}</a>
</div>
{{end}}
</div>
Expand Down