nugo

package module
v0.3.6 Latest Latest
Warning

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

Go to latest
Published: Jul 31, 2020 License: MIT Imports: 7 Imported by: 1

README

Package nugo provides a graph implementation suitable for access controlled resources.

Documentation

Overview

Package nugo provides a graph with unix style modes.

The graph is a set of linked nodes

root
  |
  +-- child
      sibling
      sibling
      |    |
      *    +-- child
               sibling
               ...

Each node references its parent aswell. In addition to the standard unix permission rwxrwxrwx another set of rwx are added to indicate anonymous access control. Permission bits for "Other" means other authenticated.

           rwxrwxrwxrwx    ModePerm
            n  u  g  o
            |  |  |  |
aNonymous --+  |  |  |
     User -----+  |  |
    Group --------+  |
    Other -----------+

Operations on the graph are not synchronized, this is left to any system using it.

Example
root := NewRoot("/")
root.Make("etc")
tmp := root.Make("tmp")
tmp.Make("y.txt")
root.Walk(NamePrinter(os.Stdout))
Output:

/etc
/tmp
/tmp/y.txt
Example (GraphManipulation)
root := NewRootNode("/", ModeSort)
root.MakeAll("etc", "tmp", "usr/")
tmp, _ := root.Find("/tmp")
tmp.MakeAll("y.txt", "dir")
tmp.DelChild("dir")

root.Walk(func(Child *Node, abspath string, w *Walker) {
	fmt.Fprintln(os.Stdout, abspath)
	if abspath == "/tmp/y.txt" {
		w.Stop()
	}
})
Output:

/etc
/tmp
/tmp/y.txt
Example (Sorted)
root := NewRootNode("/", ModeSort)
root.MakeAll("c", "b", "a")
b, _ := root.Find("/b")
b.MakeAll("2", "1", "3", "0", "2.5")
root.Walk(NamePrinter(os.Stdout))
Output:

/a
/b
/b/0
/b/1
/b/2
/b/2.5
/b/3
/c
Example (SortedDistinct)
root := NewRootNode("/", ModeSort|ModeDistinct)
b := root.Make("b")
b.MakeAll("2", "1", "1", "2")
root.Make("a")
root.Walk(NamePrinter(os.Stdout))
Output:

/a
/b
/b/1
/b/2

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Node

type Node struct {
	Name string
	Seal
	Content interface{}

	sync.RWMutex
	Parent  *Node
	Child   *Node
	Sibling *Node
}

Node names and links a sibling and a child.

func NewNode

func NewNode(name string) *Node

NewNode returns a new node with the given name url path escaped.

func NewRoot

func NewRoot(abspath string) *Node

NewRoot returns a new node with the name as is. It's the callers responsibility to make sure every basename is safe, Valid abspaths are "/" or "/mnt/usb". Defaults to mode ModeDir | ModeRoot.

func NewRootNode

func NewRootNode(abspath string, mode NodeMode) *Node

NewRootNode returns a root node with the additional given mode.

Example

NewRootNode is a way to root a tree at a given point. Only difference from NewNode is it can contain / in the name.

root := NewRoot("/mnt/usb")
a := root.Make("a")
a.MakeAll("file.txt")
root.Make("b")
root.Walk(NamePrinter(os.Stdout))
Output:

/mnt/usb/a
/mnt/usb/a/file.txt
/mnt/usb/b

func (*Node) AbsPath

func (me *Node) AbsPath() string

AbsPath returns the absolute path to this node.

func (*Node) Add

func (me *Node) Add(children ...*Node)

Add adds each child in sequence according to the NodeMode of the parent node. Add blocks if another add is in progress. For ModeDistinct an existing node with the same name is replaced.

func (*Node) CheckDir added in v0.3.3

func (me *Node) CheckDir() error

CheckDir returns nil if ModeDir is set

func (*Node) CheckRoot added in v0.3.3

func (me *Node) CheckRoot() error

CheckRoot returns nil if ModeRoot is set

func (*Node) Copy

func (me *Node) Copy() *Node

Copy returns a copy of the node without relations and no source.

func (*Node) DelChild

func (me *Node) DelChild(name string) *Node

DelChild removes the first child with the given name and returns the removed node

Example
root := NewRoot("/")
root.MakeAll("etc", "bin", "tmp", "usr/")
tmp, _ := root.Find("/tmp")
tmp.MakeAll("y.txt", "dir")

root.DelChild("etc")
root.DelChild("no such")
bin, _ := root.Find("/bin")
bin.DelChild("no such")
tmp.DelChild("dir")
tmp.DelChild("x.gz")
root.Walk(NamePrinter(os.Stdout))
Output:

/bin
/tmp
/tmp/y.txt
/usr%2F

func (*Node) Find

func (me *Node) Find(abspath string) (*Node, error)

Find returns the node matching the absolute path. This node must be a root node.

func (*Node) FirstChild

func (me *Node) FirstChild() *Node

FirstChild returns the first child or nil if there are no children.

Example (ListAllChildren)
root := NewRoot("/")
root.MakeAll("a", "b")
c := root.FirstChild()
for {
	if c == nil {
		break
	}
	fmt.Fprintln(os.Stdout, c.Name)
	c = c.Sibling
}
Output:

a
b

func (*Node) IsDir

func (me *Node) IsDir() bool

IsDir returns true if ModeDir is set.

func (*Node) IsRoot

func (me *Node) IsRoot() bool

IsRoot returns true if ModeRoot is set.

func (*Node) LastChild

func (me *Node) LastChild() *Node

LastChild returns the last child or nil if there are no children.

func (*Node) Make

func (me *Node) Make(name string) *Node

Make creates and adds the named child returning the new node. See Add method for mode inheritence.

func (*Node) MakeAll

func (me *Node) MakeAll(names ...string) []*Node

MakeAll creates and adds the named children

func (*Node) SetMode added in v0.3.1

func (my *Node) SetMode(Mode NodeMode)

SetMode sets mode of this node.

Example
n := NewNode("node")
n.Mode = 01755
fmt.Println(n)
n.SetMode(ModeDir)
fmt.Println(n)
Output:

---xrwxr-xr-x 0 0 node
d--xrwxr-xr-x 0 0 node

func (*Node) SetPerm

func (my *Node) SetPerm(perm NodeMode)

SetPerm permission bits of this node.

func (*Node) SetSeal

func (my *Node) SetSeal(uid, gid int, Mode NodeMode)

SetSeal sets ownership and permission mode of the this node.

func (*Node) String

func (me *Node) String() string

String todo

func (*Node) UnsetMode

func (me *Node) UnsetMode(mask NodeMode)

UnsetMode unsets the given mode

Example
n := NewNode("node")
n.Mode = ModeDir | 01755
fmt.Println(n)
n.UnsetMode(ModeDir)
fmt.Println(n)
Output:

d--xrwxr-xr-x 0 0 node
---xrwxr-xr-x 0 0 node

func (*Node) Walk

func (me *Node) Walk(fn Visitor)

Walk over each node until Walker is stopped.

type NodeMode

type NodeMode uint32

A NodeMode represents a node's mode and permission bits.

const (
	ModeDir      NodeMode = 1 << (32 - 1 - iota)
	ModeSort              // sorted by name
	ModeDistinct          // no duplicate children
	ModeRoot

	ModeType NodeMode = ModeSort | ModeDistinct
	ModePerm NodeMode = 07777
)

func (NodeMode) String

func (m NodeMode) String() string

String returns the bits as string using rwx notation for each bit.

type Seal

type Seal struct {
	UID  int // owner
	GID  int // group
	Mode NodeMode
}

func (Seal) String

func (l Seal) String() string

type Sealed

type Sealed interface {
	Seal() Seal
}

type Visitor

type Visitor func(node *Node, abspath string, w *Walker)

Visitor is called during a walk with a specific node and the absolute path to that node. Use the given Walker to stop if needed. For root nodes the parent is nil.

func NamePrinter

func NamePrinter(writer io.Writer) Visitor

NamePrinter writes abspath to the given writer.

func NodeLogger

func NodeLogger(l fox.Logger) Visitor

NodeLogger logs permissions and ownership with each node

Example
root := NewRootNode("/", ModeSort|ModeDistinct)
root.SetSeal(1, 1, 01755)
tmp := root.Make("tmp")
tmp.Make("sub")
l := fox.NewSyncLog(os.Stdout)
root.Walk(NodeLogger(l))
Output:

d--xrwxr-xr-x 1 1 /tmp
d--xrwxr-xr-x 1 1 /tmp/sub

func NodePrinter

func NodePrinter(writer io.Writer) Visitor

NodePrinter writes permissions and ownership with each node

Example
root := NewRootNode("/", ModeSort|ModeDistinct)
root.SetSeal(1, 1, 01755)
root.Make("etc") // inherits parent mode
root.Walk(NodePrinter(os.Stdout))
Output:

d--xrwxr-xr-x 1 1 /etc

type Walker

type Walker struct {
	// contains filtered or unexported fields
}

Walker holds state of a walk.

func NewWalker

func NewWalker() *Walker

NewWalker returns a recursive walker

func (*Walker) SetRecursive

func (me *Walker) SetRecursive(r bool)

SetRecursive

func (*Walker) SkipChild added in v0.3.0

func (me *Walker) SkipChild()

Skip tells the walker not do descend into this node if it's in recursive mode and the node is a directory.

func (*Walker) Stop

func (me *Walker) Stop()

Stop the Walker from your visitor.

func (*Walker) Walk

func (me *Walker) Walk(node *Node, fn Visitor)

Walk calls the Visitor for the given nodes children and siblings. The given node is not visited.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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