Skip to content

Commit

Permalink
add privacy mode and role tests (fixes #185)
Browse files Browse the repository at this point in the history
* denied/remove
* denied/add
* invites/revoke
* members/remove
* notices/edit
* notices/add

also:
* add members.CheckAction helper
* fix muxrpc abort bug and update to v2.0.5
* strictly use SeeOther not 307 (fixes #149)
  • Loading branch information
cryptix committed May 14, 2021
1 parent 98c5a59 commit 385b98a
Show file tree
Hide file tree
Showing 24 changed files with 795 additions and 248 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ require (
github.com/volatiletech/sqlboiler-sqlite3 v0.0.0-20210314195744-a1c697a68aef // indirect
github.com/volatiletech/sqlboiler/v4 v4.5.0
github.com/volatiletech/strmangle v0.0.1
go.cryptoscope.co/muxrpc/v2 v2.0.4
go.cryptoscope.co/muxrpc/v2 v2.0.5
go.cryptoscope.co/netwrap v0.1.1
go.cryptoscope.co/secretstream v1.2.2
go.mindeco.de v1.11.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,8 @@ go.cryptoscope.co/muxrpc/v2 v2.0.2 h1:UdlGHY+EEYZpJz5HWnWz0r34pULYxJHfFTeqLvv+7s
go.cryptoscope.co/muxrpc/v2 v2.0.2/go.mod h1:MgaeojIkWY3lLuoNw1mlMT3b3jiZwOj/fgsoGZp/VNA=
go.cryptoscope.co/muxrpc/v2 v2.0.4 h1:NLN//zPt9UKFelnPNBh3fefrQ/TFylCflPZhKiDtK3U=
go.cryptoscope.co/muxrpc/v2 v2.0.4/go.mod h1:MgaeojIkWY3lLuoNw1mlMT3b3jiZwOj/fgsoGZp/VNA=
go.cryptoscope.co/muxrpc/v2 v2.0.5 h1:yZEp49Qx4KWF/DD+Hg+6vPrl4cjlcH0Ex5kzaz0XpMA=
go.cryptoscope.co/muxrpc/v2 v2.0.5/go.mod h1:MgaeojIkWY3lLuoNw1mlMT3b3jiZwOj/fgsoGZp/VNA=
go.cryptoscope.co/netwrap v0.1.0/go.mod h1:7zcYswCa4CT+ct54e9uH9+IIbYYETEMHKDNpzl8Ukew=
go.cryptoscope.co/netwrap v0.1.1 h1:JLzzGKEvrUrkKzu3iM0DhpHmt+L/gYqmpcf1lJMUyFs=
go.cryptoscope.co/netwrap v0.1.1/go.mod h1:7zcYswCa4CT+ct54e9uH9+IIbYYETEMHKDNpzl8Ukew=
Expand Down
2 changes: 1 addition & 1 deletion muxrpc/test/go/alias_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func TestAliasRegister(t *testing.T) {
r.Error(err)

var callErr *muxrpc.CallError
r.True(errors.As(err, &callErr), "expected a call error: %T", err)
r.True(errors.As(err, &callErr), "expected a call error: %T -- %s", err, err)
r.Equal(`alias ("bob") is already taken`, callErr.Message)

for _, bot := range theBots {
Expand Down
2 changes: 2 additions & 0 deletions roomdb/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ const (
ModeRestricted
)

var AllPrivacyModes = []PrivacyMode{ModeOpen, ModeCommunity, ModeRestricted}

// Implements the SQL marshaling interfaces (Scanner for Scan & Valuer for Value) for PrivacyMode

// Scan implements https://pkg.go.dev/database/sql#Scanner to read integers into a privacy mode
Expand Down
3 changes: 2 additions & 1 deletion roomsrv/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type Server struct {
closers multicloser.Closer

closed bool
closedMu sync.Mutex
closedMu *sync.Mutex
closeErr error

Network network.Network
Expand Down Expand Up @@ -87,6 +87,7 @@ func New(
opts ...Option,
) (*Server, error) {
var s Server
s.closedMu = new(sync.Mutex)

s.Members = membersdb
s.DeniedKeys = deniedkeysdb
Expand Down
14 changes: 7 additions & 7 deletions web/handlers/admin/aliases.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,38 +67,38 @@ func (h aliasesHandler) revoke(rw http.ResponseWriter, req *http.Request) {
return
}

defer http.Redirect(rw, req, redirectToMembers, http.StatusSeeOther)

aliasName := req.FormValue("name")

ctx := req.Context()

aliasEntry, err := h.db.Resolve(ctx, aliasName)
if err != nil {
h.r.Error(rw, req, http.StatusBadRequest, err)
h.flashes.AddError(rw, req, err)
return
}

// who is doing this request
currentMember := members.FromContext(ctx)
if currentMember == nil {
err := weberrors.ErrForbidden{Details: fmt.Errorf("not an member")}
h.r.Error(rw, req, http.StatusInternalServerError, err)
h.flashes.AddError(rw, req, err)
return
}

// ensure own alias or admin
if !aliasEntry.Feed.Equal(&currentMember.PubKey) && currentMember.Role != roomdb.RoleAdmin {
err := weberrors.ErrForbidden{Details: fmt.Errorf("not your alias or not an admin")}
h.r.Error(rw, req, http.StatusInternalServerError, err)
h.flashes.AddError(rw, req, err)
return
}

status := http.StatusTemporaryRedirect // TODO: should be SeeOther because it's method POST coming in
err = h.db.Revoke(ctx, aliasName)
if err != nil {
h.flashes.AddError(rw, req, err)
} else {
h.flashes.AddMessage(rw, req, "AdminMemberDetailsAliasRevoked")
return
}

http.Redirect(rw, req, redirectToMembers, status)
h.flashes.AddMessage(rw, req, "AdminMemberDetailsAliasRevoked")
}
4 changes: 2 additions & 2 deletions web/handlers/admin/aliases_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func TestAliasesRevoke(t *testing.T) {

addVals := url.Values{"name": []string{"the-name"}}
rec := ts.Client.PostForm(urlRevoke, addVals)
a.Equal(http.StatusTemporaryRedirect, rec.Code)
a.Equal(http.StatusSeeOther, rec.Code)
a.Equal(overviewURL.Path, rec.Header().Get("Location"))
a.True(len(rec.Result().Cookies()) > 0, "got a cookie")

Expand All @@ -77,7 +77,7 @@ func TestAliasesRevoke(t *testing.T) {
ts.AliasesDB.RevokeReturns(roomdb.ErrNotFound)
addVals = url.Values{"name": []string{"nope"}}
rec = ts.Client.PostForm(urlRevoke, addVals)
a.Equal(http.StatusTemporaryRedirect, rec.Code)
a.Equal(http.StatusSeeOther, rec.Code)
a.Equal(overviewURL.Path, rec.Header().Get("Location"))
a.True(len(rec.Result().Cookies()) > 0, "got a cookie")

Expand Down
26 changes: 23 additions & 3 deletions web/handlers/admin/denied_keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/ssb-ngi-pointer/go-ssb-room/roomdb"
weberrors "github.com/ssb-ngi-pointer/go-ssb-room/web/errors"
"github.com/ssb-ngi-pointer/go-ssb-room/web/members"
refs "go.mindeco.de/ssb-refs"
)

Expand All @@ -20,7 +21,8 @@ type deniedKeysHandler struct {

flashes *weberrors.FlashHelper

db roomdb.DeniedKeysService
db roomdb.DeniedKeysService
roomCfg roomdb.RoomConfig
}

const redirectToDeniedKeys = "/admin/denied"
Expand All @@ -29,6 +31,15 @@ func (h deniedKeysHandler) add(w http.ResponseWriter, req *http.Request) {
// always redirect
defer http.Redirect(w, req, redirectToDeniedKeys, http.StatusSeeOther)

ctx := req.Context()

_, err := members.CheckAllowed(ctx, h.roomCfg, members.ActionChangeDeniedKeys)
if err != nil {
err := weberrors.ErrNotAuthorized
h.flashes.AddError(w, req, err)
return
}

if req.Method != "POST" {
err := weberrors.ErrBadRequest{Where: "HTTP Method", Details: fmt.Errorf("expected POST not %s", req.Method)}
h.flashes.AddError(w, req, err)
Expand Down Expand Up @@ -109,7 +120,16 @@ func (h deniedKeysHandler) remove(rw http.ResponseWriter, req *http.Request) {
// always redirect
defer http.Redirect(rw, req, redirectToDeniedKeys, http.StatusSeeOther)

err := req.ParseForm()
ctx := req.Context()

_, err := members.CheckAllowed(ctx, h.roomCfg, members.ActionChangeDeniedKeys)
if err != nil {
err := weberrors.ErrNotAuthorized
h.flashes.AddError(rw, req, err)
return
}

err = req.ParseForm()
if err != nil {
err = weberrors.ErrBadRequest{Where: "Form data", Details: err}
h.flashes.AddError(rw, req, err)
Expand All @@ -123,7 +143,7 @@ func (h deniedKeysHandler) remove(rw http.ResponseWriter, req *http.Request) {
return
}

err = h.db.RemoveID(req.Context(), id)
err = h.db.RemoveID(ctx, id)
if err != nil {
h.flashes.AddError(rw, req, err)
} else {
Expand Down
Loading

0 comments on commit 385b98a

Please sign in to comment.