top
(README.md)
# go-user

This package provides a generic user role system for web applications. A database backend is required to store user information. Currently the following methods are supported:

* MongoDB (using mgo: https://labix.org/mgo)
* MySQL (using MySQL driver: https://github.com/go-sql-driver/mysql)

To add your own, implement the *Provider* interface and pass it to the manager.

## Installation

```
go get github.com/DeKugelschieber/go-user
```

Currently, both database drivers must be installed, even when only one is used. To change this you can remove the *_provider.go and *_provider_test.go from the module.

## Usage

First, create a manager to manage users and roles. There are two ways to create one:

```
var manager *user.Manager

func main() {
    // MongoDB provider, pass database and two collection names to be used,
    // where the first one is the user and the second one the role collection
    provider, err := user.NewMgoProvider(db, "user", "role")

    // creates a new manager by passing the provider
    manager, err = user.NewManager(provider)

    if err != nil {
        // ...
    }
}
```

```
func main() {
    provider, err := user.NewMgoProvider(db, "user", "role")

    if err := user.Init(provider); err != nil {
        // ...
    }

    // ...
}
```

The second method stores the manager instance within the package scope of "user". It can be accessed using Get():

```
manager := user.Get()
```

Now you can start to create users and roles. Lets begin with creating a role, which users can be assigned to. The role should allow to edit articles on a websiste:

```
// this will create a new role called "admin" with the right to edit articles:
role, err := manager.CreateRole("admin", map[string]bool{"edit_articles": true})

if err != nil {
    // ...
}

// this is how you can check a role is allowed to do something:
if role.GetRight("edit_articles") {
    // yes!
} else {
    // no!
}

// you can modify a role:
role.SetRight("edit_articles", false) // or RemoveRight("edit_articles")
role.Save()
```

Now we create a user and assign him to the "admin" role:

```
// this will create a new user with login "admin", email "admin@..." and password "password_as...", he will be assigned the admin role, which we created earlier
user, err := manager.CreateUser("admin", "admin@mypage.com", "password_as_clear_text", []Role{*role})

if err != nil {
    // ...
}

// we can now check if the user has the admin role:
if user.HasRole("admin") {
    // yes!
} else {
    // no!
}

// you can modify a user and his roles:
user.RemoveRole(role) // or pass a sample
user.Save()
```

Both, users and roles, can be aquired by the manager using a sample. The role name, user login and user email are case insensitive. Here is a short example to get the user we created:

```
user, err := manager.GetUser(&User{Name: "admin"})

if user == nil || err != nil {
    // not found or different error
}
```

When querying by multiple parameters, they are *and* connected. So the result will match all parameters you set in the sample. To add custom data to a user, use the *SetData()*, *GetData()* and *RemoveData()* methods provided by user. For the MySQL provider, only strings can be safed, so the objects to save must be serialized (e.g. to JSON). The MongoDB provider can store generic interfaces directly (exported fields only). Here is a quick example:

```
// works for both, MongoDB and MySQL provider
// use "bson" to store the field in MongoDB
type UserData struct {
    Firstname string `json:"firstname" bson:"firstname"`
    Lastname  string `json:"lastname" bson:"lastname"`
}

// when using MySQL, store strings or serialize them
asJson, _ := json.Marshal(UserData{"Max", "Mustermann"})
user.SetData("user_data", asJson)
err := user.Save()

if err != nil {
    // ...
}

// or, for MongoDB just store and obtain them directly
user.SetData("user_data", UserData{"Max", "Mustermann"})
err := user.Save()
//...
```

To encode users or roles to JSON, you can just marshal them. Exceptions are user roles, user data and role rights. They can be encoded to JSON by creating a struct which inherits from *User* or *Role* and set the missing fields by obtaining them using the getters of the objects.

For full documentation please visit https://godoc.org/github.com/DeKugelschieber/go-user.

## Test

To run the tests, you need to have a local MongoDB database installed. Call *go test src/github.com/DeKugelschieber/go-user* to run them, when GOPATH is set to your project root directory. For the MySQL provider you need to have the a MySQL database installed and created the schema. The database data must match the constants in *mysql_provider_test.go*.

## License

MIT

Imports 3 package(s) ΒΆ

  1. gopkg.in/mgo.v2/bson
  2. gopkg.in/mgo.v2
  3. github.com/go-sql-driver/mysql