Skip to content

Commit

Permalink
#37 security template funcs added
Browse files Browse the repository at this point in the history
  • Loading branch information
jeevatkm committed Jul 12, 2017
1 parent 3fa7dc8 commit 6af2408
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 15 deletions.
57 changes: 50 additions & 7 deletions security.go
Expand Up @@ -18,8 +18,11 @@ import (
)

const (
keyAuthcInfo = "_aahAuthcInfo"
keySubjectValue = "_aahSubject"
// KeyViewArgAuthcInfo key name is used to store `AuthenticationInfo` instance into `ViewArgs`.
KeyViewArgAuthcInfo = "_aahAuthcInfo"

// KeyViewArgSubject key name is used to store `Subject` instance into `ViewArgs`.
KeyViewArgSubject = "_aahSubject"
)

var appSecurityManager = security.New()
Expand Down Expand Up @@ -82,8 +85,8 @@ func (e *engine) doFormAuthcAndAuthz(ascheme scheme.Schemer, ctx *Context) flowR
// In Form authentication check session is already authentication if yes
// then continue the request flow immediately.
if ctx.Subject().IsAuthenticated() {
if ctx.Session().IsKeyExists(keyAuthcInfo) {
ctx.Subject().AuthenticationInfo = ctx.Session().Get(keyAuthcInfo).(*authc.AuthenticationInfo)
if ctx.Session().IsKeyExists(KeyViewArgAuthcInfo) {
ctx.Subject().AuthenticationInfo = ctx.Session().Get(KeyViewArgAuthcInfo).(*authc.AuthenticationInfo)

// TODO cache for AuthorizationInfo
ctx.Subject().AuthorizationInfo = formAuth.DoAuthorizationInfo(ctx.Subject().AuthenticationInfo)
Expand Down Expand Up @@ -123,7 +126,7 @@ func (e *engine) doFormAuthcAndAuthz(ascheme scheme.Schemer, ctx *Context) flowR

// Remove the credential
ctx.Subject().AuthenticationInfo.Credential = nil
ctx.Session().Set(keyAuthcInfo, ctx.Subject().AuthenticationInfo)
ctx.Session().Set(KeyViewArgAuthcInfo, ctx.Subject().AuthenticationInfo)

publishOnPostAuthEvent(ctx)

Expand Down Expand Up @@ -224,7 +227,7 @@ func tmplFlashValue(viewArgs map[string]interface{}, key string) interface{} {
}

// tmplIsAuthenticated method returns the value of `Session.IsAuthenticated`.
func tmplIsAuthenticated(viewArgs map[string]interface{}) interface{} {
func tmplIsAuthenticated(viewArgs map[string]interface{}) bool {
if sub := getSubjectFromViewArgs(viewArgs); sub != nil {
if sub.Session != nil {
return sub.Session.IsAuthenticated
Expand All @@ -233,8 +236,48 @@ func tmplIsAuthenticated(viewArgs map[string]interface{}) interface{} {
return false
}

// tmplHasRole method returns the value of `Subject.HasRole`.
func tmplHasRole(viewArgs map[string]interface{}, role string) bool {
if sub := getSubjectFromViewArgs(viewArgs); sub != nil {
return sub.HasRole(role)
}
return false
}

// tmplHasAllRoles method returns the value of `Subject.HasAllRoles`.
func tmplHasAllRoles(viewArgs map[string]interface{}, roles ...string) bool {
if sub := getSubjectFromViewArgs(viewArgs); sub != nil {
return sub.HasAllRoles(roles...)
}
return false
}

// tmplHasAnyRole method returns the value of `Subject.HasAnyRole`.
func tmplHasAnyRole(viewArgs map[string]interface{}, roles ...string) bool {
if sub := getSubjectFromViewArgs(viewArgs); sub != nil {
return sub.HasAnyRole(roles...)
}
return false
}

// tmplIsPermitted method returns the value of `Subject.IsPermitted`.
func tmplIsPermitted(viewArgs map[string]interface{}, permission string) bool {
if sub := getSubjectFromViewArgs(viewArgs); sub != nil {
return sub.IsPermitted(permission)
}
return false
}

// tmplIsPermittedAll method returns the value of `Subject.IsPermittedAll`.
func tmplIsPermittedAll(viewArgs map[string]interface{}, permissions ...string) bool {
if sub := getSubjectFromViewArgs(viewArgs); sub != nil {
return sub.IsPermittedAll(permissions...)
}
return false
}

func getSubjectFromViewArgs(viewArgs map[string]interface{}) *security.Subject {
if sv, found := viewArgs[keySubjectValue]; found {
if sv, found := viewArgs[KeyViewArgSubject]; found {
return sv.(*security.Subject)
}
return nil
Expand Down
28 changes: 22 additions & 6 deletions security_test.go
Expand Up @@ -33,7 +33,7 @@ func TestSecuritySessionStore(t *testing.T) {
func TestSecuritySessionTemplateFuns(t *testing.T) {
viewArgs := make(map[string]interface{})

assert.Nil(t, viewArgs[keySubjectValue])
assert.Nil(t, viewArgs[KeyViewArgSubject])

bv1 := tmplSessionValue(viewArgs, "my-testvalue")
assert.Nil(t, bv1)
Expand All @@ -45,8 +45,18 @@ func TestSecuritySessionTemplateFuns(t *testing.T) {
session.Set("my-testvalue", 38458473684763)
session.SetFlash("my-flashvalue", "user not found")

viewArgs[keySubjectValue] = &security.Subject{Session: session}
assert.NotNil(t, viewArgs[keySubjectValue])
assert.False(t, tmplHasRole(viewArgs, "role1"))
assert.False(t, tmplHasAllRoles(viewArgs, "role1", "role2", "role3"))
assert.False(t, tmplHasAnyRole(viewArgs, "role1", "role2", "role3"))
assert.False(t, tmplIsPermitted(viewArgs, "*"))
assert.False(t, tmplIsPermittedAll(viewArgs, "news:read,write", "manage:*"))

viewArgs[KeyViewArgSubject] = &security.Subject{
Session: session,
AuthenticationInfo: authc.NewAuthenticationInfo(),
AuthorizationInfo: authz.NewAuthorizationInfo(),
}
assert.NotNil(t, viewArgs[KeyViewArgSubject])

v1 := tmplSessionValue(viewArgs, "my-testvalue")
assert.Equal(t, 38458473684763, v1)
Expand All @@ -57,7 +67,13 @@ func TestSecuritySessionTemplateFuns(t *testing.T) {
v3 := tmplIsAuthenticated(viewArgs)
assert.False(t, v3)

delete(viewArgs, keySubjectValue)
assert.False(t, tmplHasRole(viewArgs, "role1"))
assert.False(t, tmplHasAllRoles(viewArgs, "role1", "role2", "role3"))
assert.False(t, tmplHasAnyRole(viewArgs, "role1", "role2", "role3"))
assert.False(t, tmplIsPermitted(viewArgs, "*"))
assert.False(t, tmplIsPermittedAll(viewArgs, "news:read,write", "manage:*"))

delete(viewArgs, KeyViewArgSubject)
v4 := tmplIsAuthenticated(viewArgs)
assert.False(t, v4)
}
Expand Down Expand Up @@ -135,13 +151,13 @@ func TestSecurityHandleAuthcAndAuthz(t *testing.T) {
assert.Nil(t, err)
r3 := httptest.NewRequest("POST", "http://localhost:8080/login", nil)
ctx2.Req = ahttp.ParseRequest(r3, &ahttp.Request{})
ctx2.Session().Set(keyAuthcInfo, testGetAuthenticationInfo())
ctx2.Session().Set(KeyViewArgAuthcInfo, testGetAuthenticationInfo())
result4 := e.handleAuthcAndAuthz(ctx2)
assert.True(t, result4 == flowCont)

// form auth not authenticated and no credentials
ctx2.Session().IsAuthenticated = false
delete(ctx2.Session().Values, keyAuthcInfo)
delete(ctx2.Session().Values, KeyViewArgAuthcInfo)
result5 := e.handleAuthcAndAuthz(ctx2)
assert.True(t, result5 == flowStop)

Expand Down
9 changes: 7 additions & 2 deletions view.go
Expand Up @@ -136,7 +136,7 @@ func (e *engine) resolveView(ctx *Context) {
htmlRdr.ViewArgs["AahVersion"] = Version
htmlRdr.ViewArgs["EnvProfile"] = AppProfile()
htmlRdr.ViewArgs["AppBuildInfo"] = AppBuildInfo()
htmlRdr.ViewArgs[keySubjectValue] = ctx.Subject()
htmlRdr.ViewArgs[KeyViewArgSubject] = ctx.Subject()

// find view template by convention if not provided
findViewTemplate(ctx)
Expand Down Expand Up @@ -235,7 +235,12 @@ func init() {
"fparam": tmplFormParam,
"qparam": tmplQueryParam,
"session": tmplSessionValue,
"isauthenticated": tmplIsAuthenticated,
"flash": tmplFlashValue,
"isauthenticated": tmplIsAuthenticated,
"hasrole": tmplHasRole,
"hasallroles": tmplHasAllRoles,
"hasanyrole": tmplHasAnyRole,
"ispermitted": tmplIsPermitted,
"ispermittedall": tmplIsPermittedAll,
})
}

0 comments on commit 6af2408

Please sign in to comment.