From d827664a69cbe31761afe56f78f4494990f5c024 Mon Sep 17 00:00:00 2001 From: Sebastian Tobie Date: Thu, 21 Jan 2021 21:48:59 +0100 Subject: [PATCH] extended the Menu so it can use the Account information. --- menus/menus.go | 33 ++++++++++++++++- menus/menus_test.go | 89 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 menus/menus_test.go diff --git a/menus/menus.go b/menus/menus.go index dbcd930..3379182 100644 --- a/menus/menus.go +++ b/menus/menus.go @@ -6,6 +6,26 @@ import ( "go.sebtobie.de/httpserver/auth" ) +type Rauth int + +// +const ( + ReqAuthAbsent Rauth = -1 + ReqAuthUnspec Rauth = 0 + ReqAuthRequired Rauth = 1 +) + +var rauthmap = map[Rauth]string{ + ReqAuthAbsent: "Authentication Absent", + ReqAuthRequired: "Authntication Required", + ReqAuthUnspec: "Authentication irrelevant", +} + +// String is to Statisfy th Stringer interface +func (r *Rauth) String() string { + return rauthmap[*r] +} + // Menu is an Interface to give the server infos about menuitems type Menu interface { Name() string @@ -27,6 +47,7 @@ type MenuItem struct { ItemAltText string ItemURL *url.URL ItemChildren []Menu + RequireAuth Rauth } // Name returns the name of the Item. @@ -54,8 +75,16 @@ func (m *MenuItem) Children() []Menu { } // Enabled returns always true -func (*MenuItem) Enabled(auth.Account) bool { - return true +func (m *MenuItem) Enabled(a auth.Account) bool { + switch m.RequireAuth { + case ReqAuthAbsent: + return true && a.Anonymous() + case ReqAuthUnspec: + return true + case ReqAuthRequired: + return true && !a.Anonymous() + } + return false } var _ Menu = &MenuItem{} diff --git a/menus/menus_test.go b/menus/menus_test.go new file mode 100644 index 0000000..3ff9e07 --- /dev/null +++ b/menus/menus_test.go @@ -0,0 +1,89 @@ +package menus_test + +import ( + "fmt" + "testing" + + "github.com/gin-gonic/gin" + "go.sebtobie.de/httpserver/menus" +) + +type account struct { + auth bool +} + +func (a *account) Anonymous() bool { + return !a.auth +} + +func (*account) Get(string) interface{} { + return nil +} + +func (*account) List() []string { + return []string{} +} + +func (*account) Redirect(*gin.Context) { +} + +type Case struct { + menu menus.MenuItem + authenticated bool + seen bool +} + +func (c *Case) String() string { + return fmt.Sprintf("%v ,authenticated: %t,seen: %t", c.menu.RequireAuth.String(), c.authenticated, c.seen) +} + +func gencases(t *testing.T) []Case { + cases := make([]Case, 0, 6) + for _, authenticated := range []bool{true, false} { + for _, require := range []menus.Rauth{menus.ReqAuthAbsent, menus.ReqAuthRequired, menus.ReqAuthUnspec} { + switch require { + case menus.ReqAuthAbsent: + c := Case{ + menu: menus.MenuItem{ + RequireAuth: require, + }, + authenticated: authenticated, + seen: true && !authenticated, + } + cases = append(cases, c) + t.Logf("Absent Case, athenticated: %t, seen: %t", authenticated, c.seen) + case menus.ReqAuthRequired: + c := Case{ + menu: menus.MenuItem{ + RequireAuth: require, + }, + authenticated: authenticated, + seen: true && authenticated, + } + cases = append(cases, c) + t.Logf("Required Case, athenticated: %t, seen: %t", authenticated, c.seen) + case menus.ReqAuthUnspec: + c := Case{ + menu: menus.MenuItem{ + RequireAuth: require, + }, + authenticated: authenticated, + seen: true, + } + cases = append(cases, c) + t.Logf("Uspec Case, athenticated: %t, seen: %t", authenticated, c.seen) + } + } + } + t.Log(cap(cases), len(cases)) + return cases +} + +func TestMenuAuth(t *testing.T) { + cases := gencases(t) + for _, input := range cases { + if s := input.menu.Enabled(&account{input.authenticated}); s != input.seen { + t.Errorf("Test failed. %s, is seen: %t", input.String(), s) + } + } +}