gopex

package module
v0.0.0-...-f94fdd1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 16, 2018 License: Apache-2.0 Imports: 5 Imported by: 0

README

GO-PEX

CircleCI Codacy Badge Go Report Card GoDoc

A permissions system for Go structs

Developing APIs in Go is very common but so far there is no easy way to choose what to return accordingly to the user that did the request and to the action. To solve that, I created a library that allow developers to easily set permissions of the fields of a struct with Go tags.

How it works

The system uses the pex tag in each field to determine if a user has or not permission for that action in that field.

It is considered that a certain user type has permission if the permissions tag is not defined or if explicitly written in the tag that for a certain action, it has permission. Invalid actions or user types that doesn't exist in the tag are considered as not having permission.

Tag structure

The permission tag is a set of pairs between user type and permission like pex:"user:r,admin:rw". In this case user would have permission to read while admin would have permission to read and write.

Extract fields

Imagine you have this two structs

type Person struct {
    ID     int  `pex:"user:r,admin:rw"`
    Name string `pex:"user:r,admin:rw" json:"full_name"`
}

type Employee struct {
    Parent
    Income float32 `pex:"user:,admin:rw"`
}

And you queried the database to get the employees. Now suppose you want to return (ActionRead) the result to a regular user (userType = "user"). Of course you don't want to show the income of the employees to a regular user, you have to remove it. For that you leave the permission of user empty in the income field as you can see above. Then you just have to call extract fields function.

fields := ExtractFields(employee, userType, ActionRead)

This will return an interface that contains all the fields in the struct that the user has permission. The key in the result is the JSON key if the JSON tag exists otherwise its the field name.

{
  "ID": 1,
  "full_name": "John Doe"
}

If the userType = admin the result has the income included

{
  "ID": 1,
  "full_name": "John Doe",
  "Income": 1000.0
}

This can be applied to slices, pointers, maps and any kind of variables.

[
  {
    "ID": 1,
    "full_name": "John Doe",
    "Income": 1000.0
  },
  {
    "ID": 2,
    "full_name": "Jack Sparrow",
    "Income": 9999.99
  }
]

Clean struct

It is also possible to take advantage of the fields extraction to clean a struct, that is to set fields that user does not have permission to their zero values and the others to the result of the field extraction.

var cleanedObject *Employee
cleanedObject := CleanObject(employee, userType, ActionRead).(*Employee)

Possible actions

ActionRead: 0

ActionWrite: 1

Permission values

PermissionNone: Empty string

PermissionRead: "r"

PermissionWrite: "w"

PermissionReadWrite: "rw"

Documentation

Index

Constants

View Source
const (
	// ActionRead is used when the action is writing
	ActionRead = 0
	// ActionWrite is used when the action is reading
	ActionWrite = 1
)

Actions

View Source
const (
	// PermissionRead means it has reading permissions
	PermissionRead = "r"
	// PermissionWrite means it has write permissions
	PermissionWrite = "w"
)

Permissions

View Source
const PermissionTag = "pex"

PermissionTag is the tag to use in structs to specify the permissions of each field

Variables

This section is empty.

Functions

func CleanObject

func CleanObject(object interface{}, userType string, action uint) interface{}

CleanObject is a function that receives an object, cleans it by removing the values that the user has not access for that action and returns a pointer to the cleaned object

func ExtractFields

func ExtractFields(object interface{}, userType string, action uint) interface{}

ExtractFields extracts all the fields that a given user have access and returns a JSON interface of that object either its an array, slice or struct. It uses the json tag to get the field name, it it is not defined uses the field name of the struct.

func ExtractMapObjectsFields

func ExtractMapObjectsFields(object interface{}, userType string, action uint) interface{}

ExtractMapObjectsFields extracts all the fields that a given user have access and returns a JSON interface of an array of objects. It uses the json tag to get the field name of each of the objects, it it is not defined uses the field name of the struct.

func ExtractMultipleObjectsFields

func ExtractMultipleObjectsFields(object interface{}, userType string, action uint) interface{}

ExtractMultipleObjectsFields extracts all the fields that a given user have access and returns a JSON interface of an array of objects. It uses the json tag to get the field name of each of the objects, it it is not defined uses the field name of the struct.

func ExtractSingleObjectFields

func ExtractSingleObjectFields(object interface{}, userType string, action uint) interface{}

ExtractSingleObjectFields extracts all the fields that a given user have access and returns a JSON interface of that object. It uses the json tag to get the field name, it it is not defined uses the field name of the struct.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL