Pular para o conteúdo principal

API Overview

Esta visão geral mostra apenas como usar as APIs do Casbin e não explica como o Casbin é instalado ou como funciona. Você pode encontrar esses tutoriais aqui: Instalação do Casbin e Como o Casbin Funciona. Portanto, quando você começa a ler este tutorial, assumimos que você já instalou e importou o Casbin para o seu código.

API de Execução

Vamos começar com as APIs de Execução do Casbin. Carregaremos um modelo RBAC de model.conf e carregaremos políticas de policy.csv. Você pode aprender sobre a sintaxe do Modelo aqui, e não vamos discutir isso neste tutorial. Assumimos que você pode entender os arquivos de configuração abaixo:

model.conf

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[role_definition]
g = _, _

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act

policy.csv

p, admin, data1, read
p, admin, data1, write
p, admin, data2, read
p, admin, data2, write
p, alice, data1, read
p, bob, data2, write
g, amber, admin
g, abc, admin

Após ler os arquivos de configuração, por favor, leia o seguinte código.

// Load information from files.
enforcer, err := casbin.NewEnforcer("./example/model.conf", "./example/policy.csv")
if err != nil {
log.Fatalf("Error, detail: %s", err)
}
ok, err := enforcer.Enforce("alice", "data1", "read")

Este código carrega o modelo de controle de acesso e as políticas de arquivos locais. A função casbin.NewEnforcer() retornará um executor. Ela reconhecerá seus dois parâmetros como caminhos de arquivos e carregará os arquivos a partir daí. Erros ocorridos no processo são armazenados na variável err. Este código usa o adaptador padrão para carregar o modelo e as políticas, e claro, você pode alcançar o mesmo resultado usando um adaptador de terceiros.

O código ok, err := enforcer.Enforce("alice", "data1", "read") é usado para confirmar permissões de acesso. Se Alice pode acessar data1 com a operação de leitura, o valor retornado de ok será true; caso contrário, será false. Neste exemplo, o valor de ok é true.

EnforceEx API

Às vezes você pode se perguntar qual política permitiu a solicitação, então preparamos a função EnforceEx(). Você pode usá-la assim:

ok, reason, err := enforcer.EnforceEx("amber", "data1", "read")
fmt.Println(ok, reason) // true [admin data1 read]

A função EnforceEx() retornará a exata string de política no valor de retorno reason. Neste exemplo, amber é um papel de admin, então a política p, admin, data1, read permitiu que esta solicitação fosse true. A saída deste código está no comentário.

O Casbin forneceu muitas APIs semelhantes a esta. Essas APIs adicionam algumas funções extras às básicas. Elas incluem:

  • ok, err := enforcer.EnforceWithMatcher(matcher, request)

    Esta função usa um comparador.

  • ok, reason, err := enforcer.EnforceExWithMatcher(matcher, request)

    Esta é uma combinação de EnforceWithMatcher() e EnforceEx().

  • boolArray, err := enforcer.BatchEnforce(requests)

    Esta função permite uma lista de trabalhos e retorna um array.

Este é um caso de uso simples do Casbin. Você pode usar o Casbin para iniciar um servidor de autorização usando essas APIs. Vamos mostrar-lhe alguns outros tipos de APIs nos parágrafos seguintes.

API de Gerenciamento

API de Obtenção

Essas APIs são usadas para recuperar objetos específicos nas políticas. Neste exemplo, estamos carregando um executor e recuperando algo dele.

Por favor, dê uma olhada no seguinte código:

enforcer, err := casbin.NewEnforcer("./example/model.conf", "./example/policy.csv")
if err != nil {
fmt.Printf("Error, details: %s\n", err)
}
allSubjects := enforcer.GetAllSubjects()
fmt.Println(allSubjects)

Semelhante ao exemplo anterior, as primeiras quatro linhas são usadas para carregar informações necessárias de arquivos locais. Não vamos discutir isso aqui mais adiante.

O código allSubjects := enforcer.GetAllSubjects() recupera todos os sujeitos no arquivo de política e os retorna como um array. Em seguida, imprimimos esse array.

Normalmente, a saída do código deve ser:

[admin alice bob]

Você também pode mudar a função GetAllSubjects() para GetAllNamedSubjects() para obter a lista de sujeitos que aparecem na política nomeada atual.

Da mesma forma, preparamos funções GetAll para Objects, Actions, Roles. Para acessar essas funções, você simplesmente precisa substituir a palavra Subject no nome da função pela categoria desejada.

Além disso, há mais getters disponíveis para políticas. O método de chamada e os valores de retorno são semelhantes aos mencionados acima.

  • policy = e.GetPolicy() recupera todas as regras de autorização na política.
  • filteredPolicy := e.GetFilteredPolicy(0, "alice") recupera todas as regras de autorização na política com filtros de campo especificados.
  • namedPolicy := e.GetNamedPolicy("p") recupera todas as regras de autorização na política nomeada.
  • filteredNamedPolicy = e.GetFilteredNamedPolicy("p", 0, "bob") recupera todas as regras de autorização na política nomeada com filtros de campo especificados.
  • groupingPolicy := e.GetGroupingPolicy() recupera todas as regras de herança de papel na política.
  • filteredGroupingPolicy := e.GetFilteredGroupingPolicy(0, "alice") recupera todas as regras de herança de papel na política com filtros de campo especificados.
  • namedGroupingPolicy := e.GetNamedGroupingPolicy("g") recupera todas as regras de herança de papel na política.
  • namedGroupingPolicy := e.GetFilteredNamedGroupingPolicy("g", 0, "alice") recupera todas as regras de herança de papel na política com filtros de campo especificados.

Adicionar, Excluir, Atualizar API

Casbin oferece uma variedade de APIs para adicionar, excluir ou modificar políticas dinamicamente em tempo de execução.

O código a seguir demonstra como adicionar, remover e atualizar políticas, bem como verificar se uma política existe:

// load information from files
enforcer, err := casbin.NewEnforcer("./example/model.conf", "./example/policy.csv")
if err != nil {
fmt.Printf("Error, details: %s\n", err)
}

// add a policy and use HasPolicy() to confirm
enforcer.AddPolicy("added_user", "data1", "read")
hasPolicy := enforcer.HasPolicy("added_user", "data1", "read")
fmt.Println(hasPolicy) // true, the policy was added successfully

// remove a policy and use HasPolicy() to confirm
enforcer.RemovePolicy("alice", "data1", "read")
hasPolicy = enforcer.HasPolicy("alice", "data1", "read")
fmt.Println(hasPolicy) // false, the policy was removed successfully

// update a policy and use HasPolicy() to confirm
enforcer.UpdatePolicy([]string{"added_user", "data1", "read"}, []string{"added_user", "data1", "write"})
hasPolicy = enforcer.HasPolicy("added_user", "data1", "read")
fmt.Println(hasPolicy) // false, the original policy has expired
hasPolicy = enforcer.HasPolicy("added_user", "data1", "write")
fmt.Println(hasPolicy) // true, the new policy is in effect

Usando essas APIs, você pode editar suas políticas dinamicamente. Da mesma forma, fornecemos APIs semelhantes para FilteredPolicy, NamedPolicy, FilteredNamedPolicy, GroupingPolicy, NamedGroupingPolicy, FilteredGroupingPolicy, FilteredNamedGroupingPolicy. Para usá-las, basta substituir a palavra Policy no nome da função pela categoria apropriada.

Além disso, alterando os parâmetros para arrays, você pode realizar edição em lote de suas políticas.

Por exemplo, considere funções como esta:

enforcer.UpdatePolicy([]string{"eve", "data3", "read"}, []string{"eve", "data3", "write"})

Se mudarmos Policy para Policies e modificarmos os parâmetros da seguinte forma:

enforcer.UpdatePolicies([][]string{{"eve", "data3", "read"}, {"jack", "data3", "read"}}, [][]string{{"eve", "data3", "write"}, {"jack", "data3", "write"}})

então podemos realizar edição em lote dessas políticas.

As mesmas operações também podem ser aplicadas a GroupingPolicy, NamedGroupingPolicy.

AddEx API

Casbin oferece a série de APIs AddEx para ajudar os usuários a adicionar regras em lotes.

AddPoliciesEx(rules [][]string) (bool, error)
AddNamedPoliciesEx(ptype string, rules [][]string) (bool, error)
AddGroupingPoliciesEx(rules [][]string) (bool, error)
AddNamedGroupingPoliciesEx(ptype string, rules [][]string) (bool, error)
SelfAddPoliciesEx(sec string, ptype string, rules [][]string) (bool, error)

A diferença entre esses métodos e os métodos sem o sufixo Ex é que, se uma das regras já existir, eles continuarão verificando a próxima regra em vez de retornar falso imediatamente.

Por exemplo, vamos comparar AddPolicies e AddPoliciesEx.

Você pode executar e observar o seguinte código copiando-o para o teste sob casbin.

func TestDemo(t *testing.T) {
e, err := NewEnforcer("examples/basic_model.conf", "examples/basic_policy.csv")
if err != nil {
fmt.Printf("Error, details: %s\n", err)
}
e.ClearPolicy()
e.AddPolicy("user1", "data1", "read")
fmt.Println(e.GetPolicy())
testGetPolicy(t, e, [][]string{{"user1", "data1", "read"}})

// policy {"user1", "data1", "read"} now exists

// Use AddPolicies to add rules in batches
ok, _ := e.AddPolicies([][]string{{"user1", "data1", "read"}, {"user2", "data2", "read"}})
fmt.Println(e.GetPolicy())
// {"user2", "data2", "read"} failed to add because {"user1", "data1", "read"} already exists
// AddPolicies returns false and no other policies are checked, even though they may not exist in the existing ruleset
// ok == false
fmt.Println(ok)
testGetPolicy(t, e, [][]string{{"user1", "data1", "read"}})

// Use AddPoliciesEx to add rules in batches
ok, _ = e.AddPoliciesEx([][]string{{"user1", "data1", "read"}, {"user2", "data2", "read"}})
fmt.Println(e.GetPolicy())
// {"user2", "data2", "read"} is added successfully
// because AddPoliciesEx automatically filters the existing {"user1", "data1", "read"}
// ok == true
fmt.Println(ok)
testGetPolicy(t, e, [][]string{{"user1", "data1", "read"}, {"user2", "data2", "read"}})
}

RBAC API

Casbin oferece algumas APIs para você modificar o modelo RBAC e as políticas. Se você está familiarizado com RBAC, você pode facilmente usar essas APIs.

Aqui, nós apenas mostramos como usar as APIs RBAC do Casbin e não falaremos sobre RBAC em si. Você pode obter mais detalhes aqui.

Usamos o seguinte código para carregar o modelo e as políticas, como antes.

enforcer, err := casbin.NewEnforcer("./example/model.conf", "./example/policy.csv")
if err != nil {
fmt.Printf("Error, details: %s\n", err)
}

Então, podemos usar uma instância do Enforcer enforcer para acessar essas APIs.

roles, err := enforcer.GetRolesForUser("amber")
fmt.Println(roles) // [admin]
users, err := enforcer.GetUsersForRole("admin")
fmt.Println(users) // [amber abc]

GetRolesForUser() retorna um array que contém todos os papéis que amber tem. Neste exemplo, amber tem apenas um papel, que é admin, então o array roles é [admin]. Da mesma forma, você pode usar GetUsersForRole() para obter os usuários que pertencem a um papel. O valor de retorno desta função também é um array.

enforcer.HasRoleForUser("amber", "admin") // true

Você pode usar HasRoleForUser() para confirmar se o usuário pertence ao papel. Neste exemplo, amber é membro de admin, então o valor de retorno da função é true.

fmt.Println(enforcer.Enforce("bob", "data2", "write")) // true
enforcer.DeletePermission("data2", "write")
fmt.Println(enforcer.Enforce("bob", "data2", "write")) // false

Você pode usar DeletePermission() para excluir uma permissão.

fmt.Println(enforcer.Enforce("alice", "data1", "read")) // true
enforcer.DeletePermissionForUser("alice", "data1", "read")
fmt.Println(enforcer.Enforce("alice", "data1", "read")) // false

E usar DeletePermissionForUser() para excluir uma permissão para um usuário.

Casbin tem muitas APIs como esta. Seus métodos de chamada e valores de retorno têm o mesmo estilo que as APIs acima. Você pode encontrar essas APIs nos próximos documentos.