Update and rename pgacl to postgresql-acl.
This commit is contained in:
parent
897609878f
commit
fab7bd3daf
|
@ -1,7 +0,0 @@
|
|||
package pgacl
|
||||
|
||||
// ACL is a generic interface that all pgacl types must adhere to
|
||||
type ACL interface {
|
||||
// String creates a PostgreSQL compatible ACL string
|
||||
String() string
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
package pgacl
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Schema models the privileges of a schema
|
||||
type Schema struct {
|
||||
Role string
|
||||
Create bool
|
||||
CreateGrant bool
|
||||
Usage bool
|
||||
UsageGrant bool
|
||||
}
|
||||
|
||||
const numSchemaOpts = 4
|
||||
|
||||
// NewSchema parses a PostgreSQL ACL string for a schema and returns a Schema
|
||||
// object
|
||||
func NewSchema(aclStr string) (Schema, error) {
|
||||
acl := Schema{}
|
||||
idx := strings.IndexByte(aclStr, '=')
|
||||
if idx == -1 {
|
||||
return Schema{}, fmt.Errorf("invalid aclStr format: %+q", aclStr)
|
||||
}
|
||||
|
||||
acl.Role = aclStr[:idx]
|
||||
|
||||
aclLen := len(aclStr)
|
||||
var i int
|
||||
withGrant := func() bool {
|
||||
if i+1 >= aclLen {
|
||||
return false
|
||||
}
|
||||
|
||||
if aclStr[i+1] == '*' {
|
||||
i++
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
for i = idx + 1; i < aclLen; i++ {
|
||||
switch aclStr[i] {
|
||||
case 'C':
|
||||
acl.Create = true
|
||||
if withGrant() {
|
||||
acl.CreateGrant = true
|
||||
}
|
||||
case 'U':
|
||||
acl.Usage = true
|
||||
if withGrant() {
|
||||
acl.UsageGrant = true
|
||||
}
|
||||
default:
|
||||
return Schema{}, fmt.Errorf("invalid byte %c in schema ACL at %d: %+q", aclStr[i], i, aclStr)
|
||||
}
|
||||
}
|
||||
|
||||
return acl, nil
|
||||
}
|
||||
|
||||
// String creates a PostgreSQL native output for the ACLs that apply to a
|
||||
// schema.
|
||||
func (s Schema) String() string {
|
||||
b := new(bytes.Buffer)
|
||||
b.Grow(len(s.Role) + numSchemaOpts + 1)
|
||||
|
||||
fmt.Fprint(b, s.Role, "=")
|
||||
|
||||
if s.Usage {
|
||||
fmt.Fprint(b, "U")
|
||||
if s.UsageGrant {
|
||||
fmt.Fprint(b, "*")
|
||||
}
|
||||
}
|
||||
|
||||
if s.Create {
|
||||
fmt.Fprint(b, "C")
|
||||
if s.CreateGrant {
|
||||
fmt.Fprint(b, "*")
|
||||
}
|
||||
}
|
||||
|
||||
return b.String()
|
||||
}
|
|
@ -0,0 +1,270 @@
|
|||
package acl
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/lib/pq"
|
||||
)
|
||||
|
||||
// ACL represents a single PostgreSQL `aclitem` entry.
|
||||
type ACL struct {
|
||||
Privileges Privileges
|
||||
GrantOptions Privileges
|
||||
Role string
|
||||
GrantedBy string
|
||||
}
|
||||
|
||||
// GetGrantOption returns true if the acl has the grant option set for the
|
||||
// specified priviledge.
|
||||
func (a ACL) GetGrantOption(priv Privileges) bool {
|
||||
if a.GrantOptions&priv != 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// GetPriviledge returns true if the acl has the specified priviledge set.
|
||||
func (a ACL) GetPrivilege(priv Privileges) bool {
|
||||
if a.Privileges&priv != 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Parse parses a PostgreSQL aclitem string and returns an ACL
|
||||
func Parse(aclStr string) (ACL, error) {
|
||||
acl := ACL{}
|
||||
idx := strings.IndexByte(aclStr, '=')
|
||||
if idx == -1 {
|
||||
return ACL{}, fmt.Errorf("invalid aclStr format: %+q", aclStr)
|
||||
}
|
||||
|
||||
acl.Role = aclStr[:idx]
|
||||
|
||||
aclLen := len(aclStr)
|
||||
var i int
|
||||
withGrant := func() bool {
|
||||
if i+1 >= aclLen {
|
||||
return false
|
||||
}
|
||||
|
||||
if aclStr[i+1] == '*' {
|
||||
i++
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
SCAN:
|
||||
for i = idx + 1; i < aclLen; i++ {
|
||||
switch aclStr[i] {
|
||||
case 'w':
|
||||
acl.Privileges |= Update
|
||||
if withGrant() {
|
||||
acl.GrantOptions |= Update
|
||||
}
|
||||
case 'r':
|
||||
acl.Privileges |= Select
|
||||
if withGrant() {
|
||||
acl.GrantOptions |= Select
|
||||
}
|
||||
case 'a':
|
||||
acl.Privileges |= Insert
|
||||
if withGrant() {
|
||||
acl.GrantOptions |= Insert
|
||||
}
|
||||
case 'd':
|
||||
acl.Privileges |= Delete
|
||||
if withGrant() {
|
||||
acl.GrantOptions |= Delete
|
||||
}
|
||||
case 'D':
|
||||
acl.Privileges |= Truncate
|
||||
if withGrant() {
|
||||
acl.GrantOptions |= Truncate
|
||||
}
|
||||
case 'x':
|
||||
acl.Privileges |= References
|
||||
if withGrant() {
|
||||
acl.GrantOptions |= References
|
||||
}
|
||||
case 't':
|
||||
acl.Privileges |= Trigger
|
||||
if withGrant() {
|
||||
acl.GrantOptions |= Trigger
|
||||
}
|
||||
case 'X':
|
||||
acl.Privileges |= Execute
|
||||
if withGrant() {
|
||||
acl.GrantOptions |= Execute
|
||||
}
|
||||
case 'U':
|
||||
acl.Privileges |= Usage
|
||||
if withGrant() {
|
||||
acl.GrantOptions |= Usage
|
||||
}
|
||||
case 'C':
|
||||
acl.Privileges |= Create
|
||||
if withGrant() {
|
||||
acl.GrantOptions |= Create
|
||||
}
|
||||
case 'T':
|
||||
acl.Privileges |= Temporary
|
||||
if withGrant() {
|
||||
acl.GrantOptions |= Temporary
|
||||
}
|
||||
case 'c':
|
||||
acl.Privileges |= Connect
|
||||
if withGrant() {
|
||||
acl.GrantOptions |= Connect
|
||||
}
|
||||
case '/':
|
||||
if i+1 <= aclLen {
|
||||
acl.GrantedBy = aclStr[i+1:]
|
||||
}
|
||||
break SCAN
|
||||
default:
|
||||
return ACL{}, fmt.Errorf("invalid byte %c in aclitem at %d: %+q", aclStr[i], i, aclStr)
|
||||
}
|
||||
}
|
||||
|
||||
return acl, nil
|
||||
}
|
||||
|
||||
// String produces a PostgreSQL aclitem-compatible string
|
||||
func (a ACL) String() string {
|
||||
b := new(bytes.Buffer)
|
||||
bitMaskStr := permString(a.Privileges, a.GrantOptions)
|
||||
role := a.Role
|
||||
grantedBy := a.GrantedBy
|
||||
|
||||
b.Grow(len(role) + len("=") + len(bitMaskStr) + len("/") + len(grantedBy))
|
||||
|
||||
fmt.Fprint(b, role, "=", bitMaskStr)
|
||||
|
||||
if grantedBy != "" {
|
||||
fmt.Fprint(b, "/", grantedBy)
|
||||
}
|
||||
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// permString is a small helper function that emits the permission bitmask as a
|
||||
// string.
|
||||
func permString(perms, grantOptions Privileges) string {
|
||||
b := new(bytes.Buffer)
|
||||
b.Grow(int(numPrivileges) * 2)
|
||||
|
||||
// From postgresql/src/include/utils/acl.h:
|
||||
//
|
||||
// /* string holding all privilege code chars, in order by bitmask position */
|
||||
// #define ACL_ALL_RIGHTS_STR "arwdDxtXUCTc"
|
||||
if perms&Insert != 0 {
|
||||
fmt.Fprint(b, "a")
|
||||
if grantOptions&Insert != 0 {
|
||||
fmt.Fprint(b, "*")
|
||||
}
|
||||
}
|
||||
|
||||
if perms&Select != 0 {
|
||||
fmt.Fprint(b, "r")
|
||||
if grantOptions&Select != 0 {
|
||||
fmt.Fprint(b, "*")
|
||||
}
|
||||
}
|
||||
|
||||
if perms&Update != 0 {
|
||||
fmt.Fprint(b, "w")
|
||||
if grantOptions&Update != 0 {
|
||||
fmt.Fprint(b, "*")
|
||||
}
|
||||
}
|
||||
|
||||
if perms&Delete != 0 {
|
||||
fmt.Fprint(b, "d")
|
||||
if grantOptions&Delete != 0 {
|
||||
fmt.Fprint(b, "*")
|
||||
}
|
||||
}
|
||||
|
||||
if perms&Truncate != 0 {
|
||||
fmt.Fprint(b, "D")
|
||||
if grantOptions&Truncate != 0 {
|
||||
fmt.Fprint(b, "*")
|
||||
}
|
||||
}
|
||||
|
||||
if perms&References != 0 {
|
||||
fmt.Fprint(b, "x")
|
||||
if grantOptions&References != 0 {
|
||||
fmt.Fprint(b, "*")
|
||||
}
|
||||
}
|
||||
|
||||
if perms&Trigger != 0 {
|
||||
fmt.Fprint(b, "t")
|
||||
if grantOptions&Trigger != 0 {
|
||||
fmt.Fprint(b, "*")
|
||||
}
|
||||
}
|
||||
|
||||
if perms&Execute != 0 {
|
||||
fmt.Fprint(b, "X")
|
||||
if grantOptions&Execute != 0 {
|
||||
fmt.Fprint(b, "*")
|
||||
}
|
||||
}
|
||||
|
||||
if perms&Usage != 0 {
|
||||
fmt.Fprint(b, "U")
|
||||
if grantOptions&Usage != 0 {
|
||||
fmt.Fprint(b, "*")
|
||||
}
|
||||
}
|
||||
|
||||
if perms&Create != 0 {
|
||||
fmt.Fprint(b, "C")
|
||||
if grantOptions&Create != 0 {
|
||||
fmt.Fprint(b, "*")
|
||||
}
|
||||
}
|
||||
|
||||
if perms&Temporary != 0 {
|
||||
fmt.Fprint(b, "T")
|
||||
if grantOptions&Temporary != 0 {
|
||||
fmt.Fprint(b, "*")
|
||||
}
|
||||
}
|
||||
|
||||
if perms&Connect != 0 {
|
||||
fmt.Fprint(b, "c")
|
||||
if grantOptions&Connect != 0 {
|
||||
fmt.Fprint(b, "*")
|
||||
}
|
||||
}
|
||||
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// quoteRole is a small helper function that handles the quoting of a role name,
|
||||
// or PUBLIC, if no role is specified.
|
||||
func quoteRole(role string) string {
|
||||
if role == "" {
|
||||
return "PUBLIC"
|
||||
}
|
||||
|
||||
return pq.QuoteIdentifier(role)
|
||||
}
|
||||
|
||||
// validRights checks to make sure a given acl's permissions and grant options
|
||||
// don't exceed the specified mask valid privileges.
|
||||
func validRights(acl ACL, validPrivs Privileges) bool {
|
||||
if (acl.Privileges|validPrivs) == validPrivs &&
|
||||
(acl.GrantOptions|validPrivs) == validPrivs {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package acl
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Column models the privileges of a column aclitem
|
||||
type Column struct {
|
||||
ACL
|
||||
}
|
||||
|
||||
// NewColumn parses an ACL object and returns a Column object.
|
||||
func NewColumn(acl ACL) (Column, error) {
|
||||
if !validRights(acl, validColumnPrivs) {
|
||||
return Column{}, fmt.Errorf("invalid flags set for column (%+q), only %+q allowed", permString(acl.Privileges, acl.GrantOptions), validColumnPrivs)
|
||||
}
|
||||
|
||||
return Column{ACL: acl}, nil
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package acl
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Database models the privileges of a database aclitem
|
||||
type Database struct {
|
||||
ACL
|
||||
}
|
||||
|
||||
// NewDatabase parses an ACL object and returns a Database object.
|
||||
func NewDatabase(acl ACL) (Database, error) {
|
||||
if !validRights(acl, validDatabasePrivs) {
|
||||
return Database{}, fmt.Errorf("invalid flags set for database (%+q), only %+q allowed", permString(acl.Privileges, acl.GrantOptions), validDatabasePrivs)
|
||||
}
|
||||
|
||||
return Database{ACL: acl}, nil
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package acl
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Domain models the privileges of a domain aclitem
|
||||
type Domain struct {
|
||||
ACL
|
||||
}
|
||||
|
||||
// NewDomain parses an ACL object and returns a Domain object.
|
||||
func NewDomain(acl ACL) (Domain, error) {
|
||||
if !validRights(acl, validDomainPrivs) {
|
||||
return Domain{}, fmt.Errorf("invalid flags set for domain (%+q), only %+q allowed", permString(acl.Privileges, acl.GrantOptions), validDomainPrivs)
|
||||
}
|
||||
|
||||
return Domain{ACL: acl}, nil
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package acl
|
||||
|
||||
import "fmt"
|
||||
|
||||
// ForeignDataWrapper models the privileges of a domain aclitem
|
||||
type ForeignDataWrapper struct {
|
||||
ACL
|
||||
}
|
||||
|
||||
// NewForeignDataWrapper parses an ACL object and returns a ForeignDataWrapper object.
|
||||
func NewForeignDataWrapper(acl ACL) (ForeignDataWrapper, error) {
|
||||
if !validRights(acl, validForeignDataWrapperPrivs) {
|
||||
return ForeignDataWrapper{}, fmt.Errorf("invalid flags set for domain (%+q), only %+q allowed", permString(acl.Privileges, acl.GrantOptions), validForeignDataWrapperPrivs)
|
||||
}
|
||||
|
||||
return ForeignDataWrapper{ACL: acl}, nil
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package acl
|
||||
|
||||
import "fmt"
|
||||
|
||||
// ForeignServer models the privileges of a foreign server aclitem
|
||||
type ForeignServer struct {
|
||||
ACL
|
||||
}
|
||||
|
||||
// NewForeignServer parses an ACL object and returns a ForeignServer object.
|
||||
func NewForeignServer(acl ACL) (ForeignServer, error) {
|
||||
if !validRights(acl, validForeignServerPrivs) {
|
||||
return ForeignServer{}, fmt.Errorf("invalid flags set for foreign server (%+q), only %+q allowed", permString(acl.Privileges, acl.GrantOptions), validForeignServerPrivs)
|
||||
}
|
||||
|
||||
return ForeignServer{ACL: acl}, nil
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package acl
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Function models the privileges of a function aclitem
|
||||
type Function struct {
|
||||
ACL
|
||||
}
|
||||
|
||||
// NewFunction parses an ACL object and returns a Function object.
|
||||
func NewFunction(acl ACL) (Function, error) {
|
||||
if !validRights(acl, validFunctionPrivs) {
|
||||
return Function{}, fmt.Errorf("invalid flags set for function (%+q), only %+q allowed", permString(acl.Privileges, acl.GrantOptions), validFunctionPrivs)
|
||||
}
|
||||
|
||||
return Function{ACL: acl}, nil
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package acl
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Language models the privileges of a language aclitem
|
||||
type Language struct {
|
||||
ACL
|
||||
}
|
||||
|
||||
// NewLanguage parses an ACL object and returns a Language object.
|
||||
func NewLanguage(acl ACL) (Language, error) {
|
||||
if !validRights(acl, validLanguagePrivs) {
|
||||
return Language{}, fmt.Errorf("invalid flags set for language (%+q), only %+q allowed", permString(acl.Privileges, acl.GrantOptions), validLanguagePrivs)
|
||||
}
|
||||
|
||||
return Language{ACL: acl}, nil
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package acl
|
||||
|
||||
import "fmt"
|
||||
|
||||
// LargeObject models the privileges of a large object aclitem
|
||||
type LargeObject struct {
|
||||
ACL
|
||||
}
|
||||
|
||||
// NewLargeObject parses an ACL object and returns a LargeObject object.
|
||||
func NewLargeObject(acl ACL) (LargeObject, error) {
|
||||
if !validRights(acl, validLargeObjectPrivs) {
|
||||
return LargeObject{}, fmt.Errorf("invalid flags set for large object (%+q), only %+q allowed", permString(acl.Privileges, acl.GrantOptions), validLargeObjectPrivs)
|
||||
}
|
||||
|
||||
return LargeObject{ACL: acl}, nil
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package acl
|
||||
|
||||
// Privileges represents a PostgreSQL ACL bitmask
|
||||
type Privileges uint16
|
||||
|
||||
// See postgresql/src/include/utils/acl.h for inspiration. Like PostgreSQL,
|
||||
// "rights" refer to the combined grant option and privilege bits fields.
|
||||
const (
|
||||
NoPrivs Privileges = 0
|
||||
|
||||
// Ordering taken from postgresql/src/include/nodes/parsenodes.h
|
||||
Insert Privileges = 1 << iota
|
||||
Select
|
||||
Update
|
||||
Delete
|
||||
Truncate
|
||||
References
|
||||
Trigger
|
||||
Execute
|
||||
Usage
|
||||
Create
|
||||
Temporary
|
||||
Connect
|
||||
|
||||
numPrivileges
|
||||
)
|
||||
|
||||
const (
|
||||
validColumnPrivs = Insert | Select | Update | References
|
||||
validDatabasePrivs = Create | Temporary | Connect
|
||||
validDomainPrivs = Usage
|
||||
validForeignDataWrapperPrivs = Usage
|
||||
validForeignServerPrivs = Usage
|
||||
validFunctionPrivs = Execute
|
||||
validLanguagePrivs = Usage
|
||||
validLargeObjectPrivs = Select | Update
|
||||
validSchemaPrivs = Usage | Create
|
||||
validSequencePrivs = Usage | Select | Update
|
||||
validTablePrivs = Insert | Select | Update | Delete | Truncate | References | Trigger
|
||||
validTablespacePrivs = Create
|
||||
validTypePrivs = Usage
|
||||
)
|
|
@ -0,0 +1,109 @@
|
|||
package acl
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"github.com/lib/pq"
|
||||
)
|
||||
|
||||
// Schema models the privileges of a schema aclitem
|
||||
type Schema struct {
|
||||
ACL
|
||||
}
|
||||
|
||||
// NewSchema parses an ACL object and returns a Schema object.
|
||||
func NewSchema(acl ACL) (Schema, error) {
|
||||
if !validRights(acl, validSchemaPrivs) {
|
||||
return Schema{}, fmt.Errorf("invalid flags set for schema (%+q), only %+q allowed", permString(acl.Privileges, acl.GrantOptions), validSchemaPrivs)
|
||||
}
|
||||
|
||||
return Schema{ACL: acl}, nil
|
||||
}
|
||||
|
||||
// Merge adds the argument's attributes to the receiver for values that are
|
||||
// composable or not set and returns a new Schema object with the resulting
|
||||
// values. Be careful with the role "" which is implicitly interpreted as the
|
||||
// PUBLIC role.
|
||||
func (s Schema) Merge(x Schema) Schema {
|
||||
role := s.Role
|
||||
if role == "" {
|
||||
role = x.Role
|
||||
}
|
||||
|
||||
grantedBy := s.GrantedBy
|
||||
if grantedBy == "" {
|
||||
grantedBy = x.GrantedBy
|
||||
}
|
||||
|
||||
return Schema{
|
||||
ACL{
|
||||
Privileges: s.Privileges | x.Privileges,
|
||||
GrantOptions: s.GrantOptions | x.GrantOptions,
|
||||
Role: role,
|
||||
GrantedBy: grantedBy,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Grants returns a list of SQL queries that constitute the privileges specified
|
||||
// in the receiver for the target schema.
|
||||
func (s Schema) Grants(target string) []string {
|
||||
const maxQueries = 2
|
||||
queries := make([]string, 0, maxQueries)
|
||||
|
||||
if s.GetPrivilege(Create) {
|
||||
b := bytes.NewBufferString("GRANT CREATE ON SCHEMA ")
|
||||
fmt.Fprint(b, pq.QuoteIdentifier(target), " TO ", quoteRole(s.Role))
|
||||
|
||||
if s.GetGrantOption(Create) {
|
||||
fmt.Fprint(b, " WITH GRANT OPTION")
|
||||
}
|
||||
|
||||
queries = append(queries, b.String())
|
||||
}
|
||||
|
||||
if s.GetPrivilege(Usage) {
|
||||
b := bytes.NewBufferString("GRANT USAGE ON SCHEMA ")
|
||||
fmt.Fprint(b, pq.QuoteIdentifier(target), " TO ", quoteRole(s.Role))
|
||||
|
||||
if s.GetGrantOption(Usage) {
|
||||
fmt.Fprint(b, " WITH GRANT OPTION")
|
||||
}
|
||||
|
||||
queries = append(queries, b.String())
|
||||
}
|
||||
|
||||
return queries
|
||||
}
|
||||
|
||||
// Revokes returns a list of SQL queries that remove the privileges specified
|
||||
// in the receiver from the target schema.
|
||||
func (s Schema) Revokes(target string) []string {
|
||||
const maxQueries = 2
|
||||
queries := make([]string, 0, maxQueries)
|
||||
|
||||
if s.GetPrivilege(Create) {
|
||||
b := bytes.NewBufferString("REVOKE")
|
||||
if s.GetGrantOption(Create) {
|
||||
fmt.Fprint(b, " GRANT OPTION FOR")
|
||||
}
|
||||
|
||||
fmt.Fprint(b, " CREATE ON SCHEMA ")
|
||||
fmt.Fprint(b, pq.QuoteIdentifier(target), " FROM ", quoteRole(s.Role))
|
||||
queries = append(queries, b.String())
|
||||
}
|
||||
|
||||
if s.GetPrivilege(Usage) {
|
||||
b := bytes.NewBufferString("REVOKE")
|
||||
if s.GetGrantOption(Usage) {
|
||||
fmt.Fprint(b, " GRANT OPTION FOR")
|
||||
}
|
||||
|
||||
fmt.Fprint(b, " USAGE ON SCHEMA ")
|
||||
fmt.Fprint(b, pq.QuoteIdentifier(target), " FROM ", quoteRole(s.Role))
|
||||
queries = append(queries, b.String())
|
||||
}
|
||||
|
||||
return queries
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package acl
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Sequence models the privileges of a sequence aclitem
|
||||
type Sequence struct {
|
||||
ACL
|
||||
}
|
||||
|
||||
// NewSequence parses a PostgreSQL ACL string for a sequence and returns a Sequence
|
||||
// object
|
||||
func NewSequence(acl ACL) (Sequence, error) {
|
||||
if !validRights(acl, validSequencePrivs) {
|
||||
return Sequence{}, fmt.Errorf("invalid flags set for sequence (%+q), only %+q allowed", permString(acl.Privileges, acl.GrantOptions), validSequencePrivs)
|
||||
}
|
||||
|
||||
return Sequence{ACL: acl}, nil
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package acl
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Table models the privileges of a table aclitem
|
||||
type Table struct {
|
||||
ACL
|
||||
}
|
||||
|
||||
// NewTable parses a PostgreSQL ACL string for a table and returns a Table
|
||||
// object
|
||||
func NewTable(acl ACL) (Table, error) {
|
||||
if !validRights(acl, validTablePrivs) {
|
||||
return Table{}, fmt.Errorf("invalid flags set for table (%+q), only %+q allowed", permString(acl.Privileges, acl.GrantOptions), validTablePrivs)
|
||||
}
|
||||
|
||||
return Table{ACL: acl}, nil
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package acl
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Tablespace models the privileges of a tablespace aclitem
|
||||
type Tablespace struct {
|
||||
ACL
|
||||
}
|
||||
|
||||
// NewTablespace parses an ACL object and returns a Tablespace object.
|
||||
func NewTablespace(acl ACL) (Tablespace, error) {
|
||||
if !validRights(acl, validTablespacePrivs) {
|
||||
return Tablespace{}, fmt.Errorf("invalid flags set for tablespace (%+q), only %+q allowed", permString(acl.Privileges, acl.GrantOptions), validTablespacePrivs)
|
||||
}
|
||||
|
||||
return Tablespace{ACL: acl}, nil
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package acl
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Type models the privileges of a type aclitem
|
||||
type Type struct {
|
||||
ACL
|
||||
}
|
||||
|
||||
// NewType parses an ACL object and returns a Type object.
|
||||
func NewType(acl ACL) (Type, error) {
|
||||
if !validRights(acl, validTypePrivs) {
|
||||
return Type{}, fmt.Errorf("invalid flags set for type (%+q), only %+q allowed", permString(acl.Privileges, acl.GrantOptions), validTypePrivs)
|
||||
}
|
||||
|
||||
return Type{ACL: acl}, nil
|
||||
}
|
|
@ -2271,10 +2271,10 @@
|
|||
"revisionTime": "2016-10-27T15:40:24Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "fCtp8mJPTtEMkpDz8TgRtJzMYw0=",
|
||||
"path": "github.com/sean-/pgacl",
|
||||
"revision": "3d9f301f1bf3d5b590119b28132d2e8d5d1f1a62",
|
||||
"revisionTime": "2016-12-15T16:51:43Z"
|
||||
"checksumSHA1": "tEKRyau4iRjmq2iwJbduD9RhN5s=",
|
||||
"path": "github.com/sean-/postgresql-acl",
|
||||
"revision": "d10489e5d217ebe9c23470c4d0ba7081a6d1e799",
|
||||
"revisionTime": "2016-12-25T12:04:19Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "BqtlwAjgFuHsVVdnw+dGSe+CKLM=",
|
||||
|
|
Loading…
Reference in New Issue