Full Code of qor/roles for AI

master dcaf8a4646d8 cached
9 files
17.9 KB
4.7k tokens
44 symbols
1 requests
Download .txt
Repository: qor/roles
Branch: master
Commit: dcaf8a4646d8
Files: 9
Total size: 17.9 KB

Directory structure:
gitextract_2mbiqyvs/

├── .travis.yml
├── LICENSE.txt
├── README.md
├── global.go
├── permission.go
├── permissioner.go
├── role.go
├── role_manager.go
└── roles_test.go

================================================
FILE CONTENTS
================================================

================================================
FILE: .travis.yml
================================================
language: go
go:
  - "1.13"

script:
  - go test -v ./...


================================================
FILE: LICENSE.txt
================================================
The MIT License (MIT)
Copyright (c)  The Plant https://theplant.jp

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================
# Roles

Roles is an [authorization](https://en.wikipedia.org/wiki/Authorization) library for [Golang](http://golang.org/), it also integrates nicely with [QOR Admin](http://github.com/qor/admin).

[![GoDoc](https://godoc.org/github.com/qor/roles?status.svg)](https://godoc.org/github.com/qor/roles)
[![Build Status](https://travis-ci.com/qor/roles.svg?branch=master)](https://travis-ci.com/qor/roles)

## Usage

### Permission Modes

Permission modes are really the *roles* in [Roles](https://github.com/qor/roles). [Roles](https://github.com/qor/roles) has [5 default permission modes](https://github.com/qor/roles/blob/master/permission.go#L8-L12):

- roles.Read
- roles.Update
- roles.Create
- roles.Delete
- roles.CRUD   // CRUD means Read, Update, Create, Delete

You can use those permission modes, or create your own by [defining permissions](#define-permission).

### Permission Behaviors and Interactions

1. All roles in the Deny mapping for a permission mode are immediately denied without reference to the Allow mapping for that permission mode.

    *E.g.*
    ```go
    roles.Deny(roles.Delete, roles.Anyone).Allow(roles.Delete, "admin")
    ```
     will deny access to `admin` for the permission mode `roles.Delete`, despite the chained call to `Allow()`. *I.e.* `Allow()` has **NO** effect in this chain.

2. If there are **NO** roles in the Allow mapping for a permission mode, then `roles.Anyone` is allowed.

    *E.g.*
    ```go
    roles.Deny(roles.CRUD, "customer")
    ```
    will allow access for permission mode `roles.CRUD` to **any** role that is not a `customer` because the Allow mapping is empty and the blanket allow rule is in force.

3. If even one (1) Allow mapping exists, then only roles on that list will be allowed through.

    *E.g.*
    ```go
    roles.Allow(roles.READ, "admin")
    ```
    allows the `admin` role through and rejects **ALL** other roles.

The following is a flow diagram for a specific permission mode, *e.g.* `roles.READ`.

``` flow
st=>start: Input role
denied0=>end: Denied
allowed0=>end: Allowed
denied1=>end: Denied
allowed1=>end: Allowed
op0=>operation: Exists in Deny map?
op1=>operation: Allow map empty?
op2=>operation: Exists in Allow map?
cond0=>condition: Yes or No?
cond1=>condition: Yes or No?
cond2=>condition: Yes or No?

st->op0->cond0
cond0(no)->op1->cond1
cond0(yes)->denied0
cond1(yes)->allowed0
cond1(no)->op2->cond2
cond2(yes)->allowed1
cond2(no)->denied1
```

Please note that, when using [Roles](https://github.com/qor/roles) with [L10n](http://github.com/qor/l10n). The

```go
// allows the admin role through and rejects ALL other roles.
roles.Allow(roles.READ, "admin")
```

might be invalid because [L10n](http://github.com/qor/l10n) defined a [permission system](http://github.com/qor/l10n#editable-locales) that applys new roles to the current user. For example, There is a user with role "manager", the `EditableLocales` in the [L10n](http://github.com/qor/l10n) permission system returns true in current locale. Then this user actually has two roles "manager" and "locale_admin". because [L10n](http://github.com/qor/l10n) set `resource.Permission.Allow(roles.CRUD, "locale_admin")` to the resource. So the user could access this resource by the role "locale\_admin".

So you either use `Deny` instead which means swtich "white list" to "black list" or make the `EditableLocales` always return blank array which means disabled [L10n](http://github.com/qor/l10n) permission system.

### Define Permission

```go
import "github.com/qor/roles"

func main() {
  // Allow Permission
  permission := roles.Allow(roles.Read, "admin") // `admin` has `Read` permission, `admin` is a role name

  // Deny Permission
  permission := roles.Deny(roles.Create, "user") // `user` has no `Create` permission

  // Using Chain
  permission := roles.Allow(roles.CRUD, "admin").Allow(roles.Read, "visitor") // `admin` has `CRUD` permissions, `visitor` only has `Read` permission
  permission := roles.Allow(roles.CRUD, "admin").Deny(roles.Update, "user") // `admin` has `CRUD` permissions, `user` doesn't has `Update` permission

  // roles `Anyone` means for anyone
  permission := roles.Deny(roles.Update, roles.Anyone) // no one has update permission
}
```

### Check Permission

```go
import "github.com/qor/roles"

func main() {
  permission := roles.Allow(roles.CRUD, "admin").Deny(roles.Create, "manager").Allow(roles.Read, "visitor")

  // check if role `admin` has the Read permission
  permission.HasPermission(roles.Read, "admin")     // => true

  // check if role `admin` has the Create permission
  permission.HasPermission(roles.Create, "admin")     // => true

  // check if role `user` has the Read permission
  permission.HasPermission(roles.Read, "user")     // => true

  // check if role `user` has the Create permission
  permission.HasPermission(roles.Create, "user")     // => false

  // check if role `visitor` has the Read permission
  permission.HasPermission(roles.Read, "user")     // => true

  // check if role `visitor` has the Create permission
  permission.HasPermission(roles.Create, "user")     // => false

  // Check with multiple roles
  // check if role `admin` or `user` has the Create permission
  permission.HasPermission(roles.Create, "admin", "user")     // => true
}
```

### Register Roles

When checking permissions, you will need to know current user's *roles* first. This could quickly get out of hand if you have defined many *roles* based on lots of conditions - so [Roles](https://github.com/qor/roles) provides some helper methods to make it easier:

```go
import "github.com/qor/roles"

func main() {
  // Register roles based on some conditions
  roles.Register("admin", func(req *http.Request, currentUser interface{}) bool {
      return req.RemoteAddr == "127.0.0.1" || (currentUser.(*User) != nil && currentUser.(*User).Role == "admin")
  })

  roles.Register("user", func(req *http.Request, currentUser interface{}) bool {
    return currentUser.(*User) != nil
  })

  roles.Register("visitor", func(req *http.Request, currentUser interface{}) bool {
    return currentUser.(*User) == nil
  })

  // Get roles from a user
  matchedRoles := roles.MatchedRoles(httpRequest, user) // []string{"user", "admin"}

  // Check if role `user` or `admin` has Read permission
  permission.HasPermission(roles.Read, matchedRoles...)
}
```

## License

Released under the [MIT License](http://opensource.org/licenses/MIT).


================================================
FILE: global.go
================================================
package roles

import "net/http"

// Global global role instance
var Global = &Role{}

// Register register role with conditions
func Register(name string, fc Checker) {
	Global.Register(name, fc)
}

// Allow allows permission mode for roles
func Allow(mode PermissionMode, roles ...string) *Permission {
	return Global.Allow(mode, roles...)
}

// Deny deny permission mode for roles
func Deny(mode PermissionMode, roles ...string) *Permission {
	return Global.Deny(mode, roles...)
}

// Get role defination
func Get(name string) (Checker, bool) {
	return Global.Get(name)
}

// Remove role definition from global role instance
func Remove(name string) {
	Global.Remove(name)
}

// Reset role definitions from global role instance
func Reset() {
	Global.Reset()
}

// MatchedRoles return defined roles from user
func MatchedRoles(req *http.Request, user interface{}) []string {
	return Global.MatchedRoles(req, user)
}

// HasRole check if current user has role
func HasRole(req *http.Request, user interface{}, roles ...string) bool {
	return Global.HasRole(req, user)
}

// NewPermission initialize a new permission for default role
func NewPermission() *Permission {
	return Global.NewPermission()
}


================================================
FILE: permission.go
================================================
package roles

import (
	"errors"
	"fmt"
)

// PermissionMode permission mode
type PermissionMode string

const (
	// Create predefined permission mode, create permission
	Create PermissionMode = "create"
	// Read predefined permission mode, read permission
	Read PermissionMode = "read"
	// Update predefined permission mode, update permission
	Update PermissionMode = "update"
	// Delete predefined permission mode, deleted permission
	Delete PermissionMode = "delete"
	// CRUD predefined permission mode, create+read+update+delete permission
	CRUD PermissionMode = "crud"
)

// ErrPermissionDenied no permission error
var ErrPermissionDenied = errors.New("permission denied")

// Permission a struct contains permission definitions
type Permission struct {
	Role         *Role
	AllowedRoles map[PermissionMode][]string
	DeniedRoles  map[PermissionMode][]string
}

func includeRoles(roles []string, values []string) bool {
	for _, role := range roles {
		if role == Anyone {
			return true
		}

		for _, value := range values {
			if value == role {
				return true
			}
		}
	}
	return false
}

// Concat concat two permissions into a new one
func (permission *Permission) Concat(newPermission *Permission) *Permission {
	var result = Permission{
		Role:         Global,
		AllowedRoles: map[PermissionMode][]string{},
		DeniedRoles:  map[PermissionMode][]string{},
	}

	var appendRoles = func(p *Permission) {
		if p != nil {
			result.Role = p.Role

			for mode, roles := range p.DeniedRoles {
				result.DeniedRoles[mode] = append(result.DeniedRoles[mode], roles...)
			}

			for mode, roles := range p.AllowedRoles {
				result.AllowedRoles[mode] = append(result.AllowedRoles[mode], roles...)
			}
		}
	}

	appendRoles(newPermission)
	appendRoles(permission)
	return &result
}

// Allow allows permission mode for roles
func (permission *Permission) Allow(mode PermissionMode, roles ...string) *Permission {
	if mode == CRUD {
		return permission.Allow(Create, roles...).Allow(Update, roles...).Allow(Read, roles...).Allow(Delete, roles...)
	}

	if permission.AllowedRoles[mode] == nil {
		permission.AllowedRoles[mode] = []string{}
	}
	permission.AllowedRoles[mode] = append(permission.AllowedRoles[mode], roles...)
	return permission
}

// Deny deny permission mode for roles
func (permission *Permission) Deny(mode PermissionMode, roles ...string) *Permission {
	if mode == CRUD {
		return permission.Deny(Create, roles...).Deny(Update, roles...).Deny(Read, roles...).Deny(Delete, roles...)
	}

	if permission.DeniedRoles[mode] == nil {
		permission.DeniedRoles[mode] = []string{}
	}
	permission.DeniedRoles[mode] = append(permission.DeniedRoles[mode], roles...)
	return permission
}

// HasPermission check roles has permission for mode or not
func (permission Permission) HasPermission(mode PermissionMode, roles ...interface{}) bool {
	var roleNames []string
	for _, role := range roles {
		if r, ok := role.(string); ok {
			roleNames = append(roleNames, r)
		} else if roler, ok := role.(Roler); ok {
			roleNames = append(roleNames, roler.GetRoles()...)
		} else {
			fmt.Printf("invalid role %#v\n", role)
			return false
		}
	}

	if len(permission.DeniedRoles) != 0 {
		if DeniedRoles := permission.DeniedRoles[mode]; DeniedRoles != nil {
			if includeRoles(DeniedRoles, roleNames) {
				return false
			}
		}
	}

	// return true if haven't define allowed roles
	if len(permission.AllowedRoles) == 0 {
		return true
	}

	if AllowedRoles := permission.AllowedRoles[mode]; AllowedRoles != nil {
		if includeRoles(AllowedRoles, roleNames) {
			return true
		}
	}

	return false
}


================================================
FILE: permissioner.go
================================================
package roles

// Permissioner permissioner interface
type Permissioner interface {
	HasPermission(mode PermissionMode, roles ...interface{}) bool
}

// ConcatPermissioner concat permissioner
func ConcatPermissioner(ps ...Permissioner) Permissioner {
	var newPS []Permissioner
	for _, p := range ps {
		if p != nil {
			newPS = append(newPS, p)
		}
	}
	return permissioners(newPS)
}

type permissioners []Permissioner

// HasPermission check has permission for permissioners or not
func (ps permissioners) HasPermission(mode PermissionMode, roles ...interface{}) bool {
	for _, p := range ps {
		if p != nil && !p.HasPermission(mode, roles) {
			return false
		}
	}

	return true
}


================================================
FILE: role.go
================================================
package roles

import (
	"fmt"
	"net/http"
)

const (
	// Anyone is a role for any one
	Anyone = "*"
)

// Checker check current request match this role or not
type Checker func(req *http.Request, user interface{}) bool

// New initialize a new `Role`
func New() *Role {
	return &Role{}
}

// Role is a struct contains all roles definitions
type Role struct {
	definitions map[string]Checker
}

// Register register role with conditions
func (role *Role) Register(name string, fc Checker) {
	if role.definitions == nil {
		role.definitions = map[string]Checker{}
	}

	definition := role.definitions[name]
	if definition != nil {
		fmt.Printf("Role `%v` already defined, overwrited it!\n", name)
	}
	role.definitions[name] = fc
}

// NewPermission initialize permission
func (role *Role) NewPermission() *Permission {
	return &Permission{
		Role:         role,
		AllowedRoles: map[PermissionMode][]string{},
		DeniedRoles:  map[PermissionMode][]string{},
	}
}

// Allow allows permission mode for roles
func (role *Role) Allow(mode PermissionMode, roles ...string) *Permission {
	return role.NewPermission().Allow(mode, roles...)
}

// Deny deny permission mode for roles
func (role *Role) Deny(mode PermissionMode, roles ...string) *Permission {
	return role.NewPermission().Deny(mode, roles...)
}

// Get role defination
func (role *Role) Get(name string) (Checker, bool) {
	fc, ok := role.definitions[name]
	return fc, ok
}

// Remove role definition
func (role *Role) Remove(name string) {
	delete(role.definitions, name)
}

// Reset role definitions
func (role *Role) Reset() {
	role.definitions = map[string]Checker{}
}

// MatchedRoles return defined roles from user
func (role *Role) MatchedRoles(req *http.Request, user interface{}) (roles []string) {
	if definitions := role.definitions; definitions != nil {
		for name, definition := range definitions {
			if definition(req, user) {
				roles = append(roles, name)
			}
		}
	}
	return
}

// HasRole check if current user has role
func (role *Role) HasRole(req *http.Request, user interface{}, roles ...string) bool {
	if definitions := role.definitions; definitions != nil {
		for _, name := range roles {
			if definition, ok := definitions[name]; ok {
				if definition(req, user) {
					return true
				}
			}
		}
	}
	return false
}


================================================
FILE: role_manager.go
================================================
package roles

// Roler Roler interface
type Roler interface {
	GetRoles() []string
}


================================================
FILE: roles_test.go
================================================
package roles_test

import (
	"testing"

	"github.com/qor/roles"
)

func TestAllow(t *testing.T) {
	permission := roles.Allow(roles.Read, "api")

	if !permission.HasPermission(roles.Read, "api") {
		t.Errorf("API should has permission to Read")
	}

	if permission.HasPermission(roles.Update, "api") {
		t.Errorf("API should has no permission to Update")
	}

	if permission.HasPermission(roles.Read, "admin") {
		t.Errorf("admin should has no permission to Read")
	}

	if permission.HasPermission(roles.Update, "admin") {
		t.Errorf("admin should has no permission to Update")
	}
}

func TestDeny(t *testing.T) {
	permission := roles.Deny(roles.Create, "api")

	if !permission.HasPermission(roles.Read, "api") {
		t.Errorf("API should has permission to Read")
	}

	if !permission.HasPermission(roles.Update, "api") {
		t.Errorf("API should has permission to Update")
	}

	if permission.HasPermission(roles.Create, "api") {
		t.Errorf("API should has no permission to Update")
	}

	if !permission.HasPermission(roles.Read, "admin") {
		t.Errorf("admin should has permission to Read")
	}

	if !permission.HasPermission(roles.Create, "admin") {
		t.Errorf("admin should has permission to Update")
	}
}

func TestCRUD(t *testing.T) {
	permission := roles.Allow(roles.CRUD, "admin")
	if !permission.HasPermission(roles.Read, "admin") {
		t.Errorf("Admin should has permission to Read")
	}

	if !permission.HasPermission(roles.Update, "admin") {
		t.Errorf("Admin should has permission to Update")
	}

	if permission.HasPermission(roles.Read, "api") {
		t.Errorf("API should has no permission to Read")
	}

	if permission.HasPermission(roles.Update, "api") {
		t.Errorf("API should has no permission to Update")
	}
}

func TestAll(t *testing.T) {
	permission := roles.Allow(roles.Update, roles.Anyone)

	if permission.HasPermission(roles.Read, "api") {
		t.Errorf("API should has no permission to Read")
	}

	if !permission.HasPermission(roles.Update, "api") {
		t.Errorf("API should has permission to Update")
	}

	permission2 := roles.Deny(roles.Update, roles.Anyone)

	if !permission2.HasPermission(roles.Read, "api") {
		t.Errorf("API should has permission to Read")
	}

	if permission2.HasPermission(roles.Update, "api") {
		t.Errorf("API should has no permission to Update")
	}
}

func TestCustomizePermission(t *testing.T) {
	var customized roles.PermissionMode = "customized"
	permission := roles.Allow(customized, "admin")

	if !permission.HasPermission(customized, "admin") {
		t.Errorf("Admin should has customized permission")
	}

	if permission.HasPermission(roles.Read, "admin") {
		t.Errorf("Admin should has no permission to Read")
	}

	permission2 := roles.Deny(customized, "admin")

	if permission2.HasPermission(customized, "admin") {
		t.Errorf("Admin should has customized permission")
	}

	if !permission2.HasPermission(roles.Read, "admin") {
		t.Errorf("Admin should has no permission to Read")
	}
}
Download .txt
gitextract_2mbiqyvs/

├── .travis.yml
├── LICENSE.txt
├── README.md
├── global.go
├── permission.go
├── permissioner.go
├── role.go
├── role_manager.go
└── roles_test.go
Download .txt
SYMBOL INDEX (44 symbols across 6 files)

FILE: global.go
  function Register (line 9) | func Register(name string, fc Checker) {
  function Allow (line 14) | func Allow(mode PermissionMode, roles ...string) *Permission {
  function Deny (line 19) | func Deny(mode PermissionMode, roles ...string) *Permission {
  function Get (line 24) | func Get(name string) (Checker, bool) {
  function Remove (line 29) | func Remove(name string) {
  function Reset (line 34) | func Reset() {
  function MatchedRoles (line 39) | func MatchedRoles(req *http.Request, user interface{}) []string {
  function HasRole (line 44) | func HasRole(req *http.Request, user interface{}, roles ...string) bool {
  function NewPermission (line 49) | func NewPermission() *Permission {

FILE: permission.go
  type PermissionMode (line 9) | type PermissionMode
  constant Create (line 13) | Create PermissionMode = "create"
  constant Read (line 15) | Read PermissionMode = "read"
  constant Update (line 17) | Update PermissionMode = "update"
  constant Delete (line 19) | Delete PermissionMode = "delete"
  constant CRUD (line 21) | CRUD PermissionMode = "crud"
  type Permission (line 28) | type Permission struct
    method Concat (line 50) | func (permission *Permission) Concat(newPermission *Permission) *Permi...
    method Allow (line 77) | func (permission *Permission) Allow(mode PermissionMode, roles ...stri...
    method Deny (line 90) | func (permission *Permission) Deny(mode PermissionMode, roles ...strin...
    method HasPermission (line 103) | func (permission Permission) HasPermission(mode PermissionMode, roles ...
  function includeRoles (line 34) | func includeRoles(roles []string, values []string) bool {

FILE: permissioner.go
  type Permissioner (line 4) | type Permissioner interface
  function ConcatPermissioner (line 9) | func ConcatPermissioner(ps ...Permissioner) Permissioner {
  type permissioners (line 19) | type permissioners
    method HasPermission (line 22) | func (ps permissioners) HasPermission(mode PermissionMode, roles ...in...

FILE: role.go
  constant Anyone (line 10) | Anyone = "*"
  type Checker (line 14) | type Checker
  function New (line 17) | func New() *Role {
  type Role (line 22) | type Role struct
    method Register (line 27) | func (role *Role) Register(name string, fc Checker) {
    method NewPermission (line 40) | func (role *Role) NewPermission() *Permission {
    method Allow (line 49) | func (role *Role) Allow(mode PermissionMode, roles ...string) *Permiss...
    method Deny (line 54) | func (role *Role) Deny(mode PermissionMode, roles ...string) *Permissi...
    method Get (line 59) | func (role *Role) Get(name string) (Checker, bool) {
    method Remove (line 65) | func (role *Role) Remove(name string) {
    method Reset (line 70) | func (role *Role) Reset() {
    method MatchedRoles (line 75) | func (role *Role) MatchedRoles(req *http.Request, user interface{}) (r...
    method HasRole (line 87) | func (role *Role) HasRole(req *http.Request, user interface{}, roles ....

FILE: role_manager.go
  type Roler (line 4) | type Roler interface

FILE: roles_test.go
  function TestAllow (line 9) | func TestAllow(t *testing.T) {
  function TestDeny (line 29) | func TestDeny(t *testing.T) {
  function TestCRUD (line 53) | func TestCRUD(t *testing.T) {
  function TestAll (line 72) | func TestAll(t *testing.T) {
  function TestCustomizePermission (line 94) | func TestCustomizePermission(t *testing.T) {
Condensed preview — 9 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (20K chars).
[
  {
    "path": ".travis.yml",
    "chars": 58,
    "preview": "language: go\ngo:\n  - \"1.13\"\n\nscript:\n  - go test -v ./...\n"
  },
  {
    "path": "LICENSE.txt",
    "chars": 1091,
    "preview": "The MIT License (MIT)\nCopyright (c)  The Plant https://theplant.jp\n\nPermission is hereby granted, free of charge, to any"
  },
  {
    "path": "README.md",
    "chars": 6448,
    "preview": "# Roles\n\nRoles is an [authorization](https://en.wikipedia.org/wiki/Authorization) library for [Golang](http://golang.org"
  },
  {
    "path": "global.go",
    "chars": 1203,
    "preview": "package roles\n\nimport \"net/http\"\n\n// Global global role instance\nvar Global = &Role{}\n\n// Register register role with co"
  },
  {
    "path": "permission.go",
    "chars": 3593,
    "preview": "package roles\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\n// PermissionMode permission mode\ntype PermissionMode string\n\nconst (\n\t// Cr"
  },
  {
    "path": "permissioner.go",
    "chars": 682,
    "preview": "package roles\n\n// Permissioner permissioner interface\ntype Permissioner interface {\n\tHasPermission(mode PermissionMode, "
  },
  {
    "path": "role.go",
    "chars": 2297,
    "preview": "package roles\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n)\n\nconst (\n\t// Anyone is a role for any one\n\tAnyone = \"*\"\n)\n\n// Checker check"
  },
  {
    "path": "role_manager.go",
    "chars": 86,
    "preview": "package roles\n\n// Roler Roler interface\ntype Roler interface {\n\tGetRoles() []string\n}\n"
  },
  {
    "path": "roles_test.go",
    "chars": 2916,
    "preview": "package roles_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/qor/roles\"\n)\n\nfunc TestAllow(t *testing.T) {\n\tpermission := roles."
  }
]

About this extraction

This page contains the full source code of the qor/roles GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 9 files (17.9 KB), approximately 4.7k tokens, and a symbol index with 44 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!