Skip to content

Commit

Permalink
Merge pull request #17 for v0.12.0 Release
Browse files Browse the repository at this point in the history
  • Loading branch information
jeevatkm authored Jul 7, 2018
2 parents 8bf553f + 0789988 commit 2e5e6f7
Show file tree
Hide file tree
Showing 20 changed files with 1,663 additions and 778 deletions.
5 changes: 4 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ branches:

go:
- 1.9
- "1.10"
- 1.x
- tip

go_import_path: aahframework.org/router.v0

before_install:
- bash <(curl -s https://aahframework.org/base-before-install) "vfs ahttp forge config essentials log security valpar"

install:
- go get -t -v ./...

Expand Down
24 changes: 14 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
# router - aah framework
[![Build Status](https://travis-ci.org/go-aah/router.svg?branch=master)](https://travis-ci.org/go-aah/router) [![codecov](https://codecov.io/gh/go-aah/router/branch/master/graph/badge.svg)](https://codecov.io/gh/go-aah/router/branch/master) [![Go Report Card](https://goreportcard.com/badge/aahframework.org/router.v0)](https://goreportcard.com/report/aahframework.org/router.v0) [![Version](https://img.shields.io/badge/version-0.11-blue.svg)](https://github.com/go-aah/router/releases/latest) [![GoDoc](https://godoc.org/aahframework.org/router.v0?status.svg)](https://godoc.org/aahframework.org/router.v0) [![License](https://img.shields.io/github/license/go-aah/router.svg)](LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@aahframework-55acee.svg)](https://twitter.com/aahframework)
<p align="center">
<img src="https://cdn.aahframework.org/assets/img/aah-logo-64x64.png" />
<h2 align="center">Router by aah framework</h2>
</p>
<p align="center">
<p align="center"><a href="https://travis-ci.org/go-aah/router"><img src="https://travis-ci.org/go-aah/router.svg?branch=master" alt="Build Status"></a> <a href="https://codecov.io/gh/go-aah/router/branch/master"><img src="https://codecov.io/gh/go-aah/router/branch/master/graph/badge.svg" alt="Code Coverage"></a> <a href="https://goreportcard.com/report/aahframework.org/router.v0"><img src="https://goreportcard.com/badge/aahframework.org/router.v0" alt="Go Report Card"></a> <a href="https://github.com/go-aah/router/releases/latest"><img src="https://img.shields.io/badge/version-0.12.0-blue.svg" alt="Release Version"></a> <a href="https://godoc.org/aahframework.org/router.v0"><img src="https://godoc.org/aahframework.org/router.v0?status.svg" alt="Godoc"></a> <a href="https://twitter.com/aahframework"><img src="https://img.shields.io/badge/twitter-@aahframework-55acee.svg" alt="Twitter @aahframework"></a></p>
</p>

***v0.11 [released](https://github.com/go-aah/router/releases/latest) and tagged on Mar 27, 2018***
[HTTP Router](http://docs.aahframework.org/routing.html) brings domain and sub-domains routing, it internally uses customized version of radix tree implementation from `github.com/julienschmidt/httprouter` developer by `@julienschmidt`.

HTTP Router it supports domain and sub-domains routing. It's built using radix tree routing algorithm of [httprouter](https://github.com/julienschmidt/httprouter) library.
### News

*`router` developed for aah framework. However, it's an independent library, can be used separately with any `Go` language project. Feel free to use it.*
* `v0.12.0` [released](https://github.com/go-aah/router/releases/latest) and tagged on Jul 06, 2018.

# Installation
#### Stable Version - Production Ready
```sh
# install the library
## Installation

```bash
go get -u aahframework.org/router.v0
```

Visit official website https://aahframework.org to learn more.
Visit official website https://aahframework.org to learn more about `aah` framework.
290 changes: 290 additions & 0 deletions authorization_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,290 @@
// Copyright (c) Jeevanandam M. (https://github.com/jeevatkm)
// aahframework.org/router source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.

package router

import (
"errors"
"testing"

"aahframework.org/config.v0"
"aahframework.org/security.v0"
"aahframework.org/security.v0/authz"
"aahframework.org/test.v0/assert"
)

func TestRouteAuthorizationConfig(t *testing.T) {
cfg, err := config.ParseString(`
user_info {
authorization {
roles = [
"hasrole(manager)",
"hasanyrole(role1, role2, role3)"
]
permissions = [
"ispermitted(newsletter:read,write)",
"ispermittedall(newsletter:read,write | newsletter:12345)"
]
}
}
`)
assert.Nil(t, err)

info, err := parseAuthorizationInfo(cfg, "user_info", &parentRouteInfo{AuthorizationInfo: &authorizationInfo{Satisfy: "either"}})
assert.Nil(t, err)
assert.NotNil(t, info)
assert.Equal(t, "either", info.Satisfy)
assert.Equal(t, []string{"manager"}, info.Roles["hasrole"])
assert.Equal(t, []string{"role1", "role2", "role3"}, info.Roles["hasanyrole"])
assert.Equal(t, []string{"newsletter:read,write"}, info.Permissions["ispermitted"])
assert.Equal(t, []string{"newsletter:read,write", "newsletter:12345"}, info.Permissions["ispermittedall"])
assert.True(t, len(info.String()) > 0)
}

func TestRouteAuthorizationConfigParentRoute(t *testing.T) {
cfg, err := config.ParseString(`
user_info {
}
`)
assert.Nil(t, err)

info, err := parseAuthorizationInfo(cfg, "user_info", &parentRouteInfo{
AuthorizationInfo: &authorizationInfo{
Satisfy: "either",
Roles: map[string][]string{
"hasrole": []string{"manager"},
"hasanyrole": []string{"role1", "role2", "role3"},
},
Permissions: map[string][]string{
"ispermitted": []string{"newsletter:read,write"},
"ispermittedall": []string{"newsletter:read,write", "newsletter:12345"},
},
},
})
assert.Nil(t, err)
assert.NotNil(t, info)
assert.Equal(t, "either", info.Satisfy)
assert.Equal(t, []string{"manager"}, info.Roles["hasrole"])
assert.Equal(t, []string{"role1", "role2", "role3"}, info.Roles["hasanyrole"])
assert.Equal(t, []string{"newsletter:read,write"}, info.Permissions["ispermitted"])
assert.Equal(t, []string{"newsletter:read,write", "newsletter:12345"}, info.Permissions["ispermittedall"])
}

func TestRouteAuthorizationConfigErrorRolesPermissions(t *testing.T) {
testcases := []struct {
label string
configStr string
err error
}{
{
label: "Test missing right bracket",
configStr: `
user_info {
authorization {
roles = [
"hasrole(manager",
"hasanyrole(role1, role2, role3)"
]
}
}
`,
err: errors.New("user_info.authorization.roles at index 1 have incorrect open/close brackets 'hasrole(manager'"),
},
{
label: "Test additional left bracket",
configStr: `
user_info {
authorization {
roles = [
"hasrole((manager)",
"hasanyrole(role1, role2, role3)"
]
}
}
`,
err: errors.New("user_info.authorization.roles at index 1 have incorrect open/close brackets 'hasrole((manager)'"),
},
{
label: "Test missing both brackets and inputs",
configStr: `
user_info {
authorization {
roles = [
"hasrole(manager)",
"hasanyrole"
]
}
}
`,
err: errors.New("user_info.authorization.roles at index 2 have incorrect open/close brackets 'hasanyrole'"),
},
{
label: "Test missing inputs",
configStr: `
user_info {
authorization {
roles = [
"hasrole(manager)",
"hasanyrole()"
]
}
}
`,
err: errors.New("user_info.authorization.roles at index 2 have func 'hasanyrole()' without input"),
},
{
label: "Test hasrole has more than one input",
configStr: `
user_info {
authorization {
roles = [
"hasrole(manager, role1)"
]
}
}
`,
err: errors.New("user_info.authorization.roles at index 1 have func 'hasrole' supports only one input param"),
},
{
label: "Test satisfy is both and permission is not configured",
configStr: `
user_info {
authorization {
satisfy = "both"
roles = [
"hasrole(manager)"
]
}
}
`,
err: errors.New("user_info.authorization.satisfy configured as 'both', however roles and permissions is not configured"),
},
{
label: "Test ispermitted has more than one input",
configStr: `
user_info {
authorization {
permissions = [
"ispermitted(newsletter:read,write | newsletter:12345)"
]
}
}
`,
err: errors.New("user_info.authorization.permissions at index 1 have func 'ispermitted' supports only one input param"),
},
}

for _, tc := range testcases {
t.Run(tc.label, func(t *testing.T) {
cfg, err := config.ParseString(tc.configStr)
assert.Nil(t, err)

info, err := parseAuthorizationInfo(cfg, "user_info", &parentRouteInfo{AuthorizationInfo: &authorizationInfo{Satisfy: "either"}})
assert.NotNil(t, err)
assert.Nil(t, info)
assert.Equal(t, tc.err, err)
})
}
}

func TestHasAccess(t *testing.T) {
allfuncsCfgStr := `
user_info {
authorization {
roles = [
"hasrole(manager)",
"hasanyrole(role1, role2, role3)",
"hasallroles(manager, role3)"
]
permissions = [
"ispermitted(newsletter:read,write)",
"ispermittedall(newsletter:read,write | newsletter:12345)"
]
}
}
`

testcases := []struct {
label string
configStr string
satisfy string
subjectRoles []string
subjectPermissions []string
result bool
}{
{
label: "All roles func and permissions func",
configStr: allfuncsCfgStr,
satisfy: "either",
subjectRoles: []string{"manager", "role3"},
subjectPermissions: []string{"newsletter:read,write", "newsletter:12345"},
result: true,
},
{
label: "Only roles check, satisfy: either",
configStr: allfuncsCfgStr,
satisfy: "either",
subjectRoles: []string{"manager", "role3"},
result: true,
},
{
label: "Only roles check, satisfy: both",
configStr: allfuncsCfgStr,
satisfy: "both",
subjectRoles: []string{"manager", "role3"},
},
{
label: "Only permissions check, satisfy: either",
configStr: allfuncsCfgStr,
satisfy: "either",
subjectPermissions: []string{"newsletter:read,write", "newsletter:12345"},
result: true,
},
{
label: "Only permissions check, satisfy: both",
configStr: allfuncsCfgStr,
satisfy: "both",
subjectPermissions: []string{"newsletter:read,write", "newsletter:12345"},
},
{
label: "All roles and permissions not exists",
configStr: allfuncsCfgStr,
satisfy: "either",
subjectRoles: []string{"notexist1", "notexist2"},
subjectPermissions: []string{"notexist:read,write", "notexist:12345"},
},
}

for _, tc := range testcases {
t.Run(tc.label, func(t *testing.T) {
cfg, err := config.ParseString(tc.configStr)
assert.Nil(t, err)

authInfo, err := parseAuthorizationInfo(cfg, "user_info", &parentRouteInfo{AuthorizationInfo: &authorizationInfo{Satisfy: tc.satisfy}})
assert.Nil(t, err)
assert.NotNil(t, authInfo)

r := &Route{authorizationInfo: authInfo}
result, _ := r.HasAccess(createSubject(tc.subjectRoles, tc.subjectPermissions))
assert.Equal(t, tc.result, result)
})
}

r := &Route{}
result, _ := r.HasAccess(createSubject([]string{"manager", "role3"}, []string{}))
assert.True(t, result)
}

func createSubject(roles []string, permissions []string) *security.Subject {
authInfo := authz.NewAuthorizationInfo()

authInfo.AddRole(roles...)
authInfo.AddPermissionString(permissions...)

return &security.Subject{
AuthorizationInfo: authInfo,
}
}
Loading

0 comments on commit 2e5e6f7

Please sign in to comment.