Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
2d5a9b2
Added comments suggested by golint
pzduniak Nov 11, 2014
be85b62
Added keys model, keys table and KeysList handler
pzduniak Nov 11, 2014
b22c5fa
Added GET /keys/:id
pzduniak Nov 12, 2014
e2359f5
Added POST /keys, doesn't seem to work
pzduniak Nov 12, 2014
e27d5a7
Fixed keys.go
pzduniak Nov 12, 2014
1ce035e
Cleaned keys.go
pzduniak Nov 12, 2014
80d600f
Merge pull request #10 from lavab/feature/keys
pzduniak Nov 13, 2014
836a964
Implemented PUT /accounts/me
pzduniak Nov 14, 2014
b1a35e8
Removed SessionsList (replaced with GET /tokens)
pzduniak Nov 14, 2014
423cbad
Added DELETE /accounts/me
pzduniak Nov 14, 2014
aa35806
Added data wiping
pzduniak Nov 14, 2014
7a425fc
Updated POST /accounts
pzduniak Nov 16, 2014
f769da5
Added a classic registration toggle
pzduniak Nov 16, 2014
0b247da
Fixed a typo in a flag's name, added a new section to README.md
pzduniak Nov 16, 2014
0c2158f
Setting the default account type to beta
pzduniak Nov 16, 2014
24ea205
Added parts of account deletion and wipes
pzduniak Nov 16, 2014
d4f288e
Added DELETE /tokens/:id
pzduniak Nov 16, 2014
244f190
Forgot about a return
pzduniak Nov 16, 2014
c3f1031
Merge pull request #12 from lavab/feature/accounts
pzduniak Nov 16, 2014
b269cf2
Added GET /contacts
pzduniak Nov 16, 2014
9e86de4
Added basic request structs for /contacts
pzduniak Nov 16, 2014
5685866
Implemented POST /contacts
pzduniak Nov 16, 2014
2e6efa2
Added GET /contacts/:id
pzduniak Nov 16, 2014
534f6da
Implemented PUT /contacts/:id
pzduniak Nov 16, 2014
18f10ec
Changed c.Env["session"] to c.Env["token"]
pzduniak Nov 16, 2014
6dd9a45
Added DELETE /contacts/:id
pzduniak Nov 16, 2014
21ce1e3
Merge pull request #13 from lavab/feature/contacts
pzduniak Nov 17, 2014
489ff0d
Added some basic tests (that don't work)
pzduniak Nov 23, 2014
909c7b8
Fixed tests, added application/json as content-type for post requests
pzduniak Nov 23, 2014
4e711b3
Added tests for classic registration, fixed an issue in the request t…
pzduniak Nov 23, 2014
f96145c
Logging in test
pzduniak Nov 23, 2014
daa750d
Added accounts test
pzduniak Nov 26, 2014
1497d4a
Added acconts update test
pzduniak Nov 26, 2014
b3ae354
Added tests for delete and wipe
pzduniak Nov 26, 2014
d859ad1
Adding rethinkdb to tests
pzduniak Nov 26, 2014
6527077
Adding froce-yes to the build script
pzduniak Nov 26, 2014
1c47353
Changed the installation script for RethinkDB
pzduniak Nov 26, 2014
6b65ea8
Crapload of random usecase tests
pzduniak Nov 26, 2014
6eb734f
Removed some code from accounts to increase the coverage
pzduniak Nov 26, 2014
51f52fc
Added last tests to the accounts suite
pzduniak Nov 27, 2014
5340c8c
Get token test
pzduniak Nov 28, 2014
d97e673
Tokens tests #2
pzduniak Nov 29, 2014
d97a4b9
Token tests
pzduniak Nov 29, 2014
d08ab7d
Contacts create and list
pzduniak Nov 29, 2014
8a532ac
Contacts tests
pzduniak Nov 29, 2014
c881573
Finishing tests package
pzduniak Nov 30, 2014
5f93042
Reservation table
pzduniak Nov 30, 2014
37bf189
Reservations implementation
pzduniak Dec 3, 2014
1314297
Still bugged
pzduniak Dec 4, 2014
2331504
Merge pull request #14 from lavab/feature/tests
pzduniak Dec 4, 2014
ae998cb
Fixed tests
pzduniak Dec 4, 2014
a457b1a
Password security checks
pzduniak Dec 5, 2014
66e7656
Merge pull request #15 from lavab/feature/queued_registration
pzduniak Dec 9, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
language: go

go:
- 1.3.1
- 1.3.1

before_script:
- source /etc/lsb-release && echo "deb http://download.rethinkdb.com/apt $DISTRIB_CODENAME main" | sudo tee /etc/apt/sources.list.d/rethinkdb.list
- wget -qO- http://download.rethinkdb.com/apt/pubkey.gpg | sudo apt-key add -
- sudo apt-get update
- sudo apt-get install rethinkdb
- rethinkdb --bind all &
44 changes: 44 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,50 @@ curl --data "username=abc&password=def" localhost:5000/login
curl --header "Auth: <token>" localhost:5000/me
```

## Configuration variables

You can use either commandline flags:
```
{ api } master » ./api -help
Usage of api:
-bind=":5000": Network address used to bind
-classic_registration=false: Classic registration enabled?
-force_colors=false: Force colored prompt?
-log="text": Log formatter type. Either "json" or "text"
-rethinkdb_db="dev": Database name on the RethinkDB server
-rethinkdb_key="": Authentication key of the RethinkDB database
-rethinkdb_url="localhost:28015": Address of the RethinkDB database
-session_duration=72: Session duration expressed in hours
-version="v0": Shown API version
```

Or environment variables:
```
{ api } master » BIND=127.0.0.1:5000 CLASSIC_REGISTRATION=false \
FORCE_COLORS=false LOG=text RETHINKDB_DB=dev RETHINKDB_KEY="" \
RETHINKDB_URL=localhost:28015 SESSION_DURATION=72 VERSION=v0 ./api
```

Or configuration files:
```
{ api } master » cat api.conf
# lines beggining with a "#" character are treated as comments
bind :5000
classic_registration false
force_colors false
log text

rethinkdb_db dev
# configuration values can be empty
rethinkdb_key
# Keys and values can be also seperated by the "=" character
rethinkdb_url=localhost:28015

session_duration=72
version=v0
{ api } master » ./api -config api.conf
```

## Build status:

- `master` - [![Build Status](https://magnum.travis-ci.com/lavab/api.svg?token=kJbppXeTxzqpCVvt4t5X&branch=master)](https://magnum.travis-ci.com/lavab/api)
Expand Down
18 changes: 17 additions & 1 deletion db/default_crud.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,22 @@ func (d *Default) FindBy(key string, value interface{}) (*gorethink.Cursor, erro
return cursor, nil
}

func (d *Default) FindByAndCount(key string, value interface{}) (int, error) {
cursor, err := d.GetTable().Filter(map[string]interface{}{
key: value,
}).Count().Run(d.session)
if err != nil {
return 0, err
}

var count int
if err := cursor.One(&count); err != nil {
return 0, NewDatabaseError(d, err, "")
}

return count, nil
}

// FindByAndFetch retrieves a value by key and then fills results with the result.
func (d *Default) FindByAndFetch(key string, value interface{}, results interface{}) error {
cursor, err := d.FindBy(key, value)
Expand All @@ -137,7 +153,7 @@ func (d *Default) FindByAndFetch(key string, value interface{}, results interfac
return nil
}

// FindByFetchOne retrieves a value by key and then fills result with the first row of the result
// FindByAndFetchOne retrieves a value by key and then fills result with the first row of the result
func (d *Default) FindByAndFetchOne(key string, value interface{}, result interface{}) error {
cursor, err := d.FindBy(key, value)
if err != nil {
Expand Down
15 changes: 2 additions & 13 deletions db/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
)

// DatabaseError is the wrapper for RethinkDB errors that allows passing more data with the message
type DatabaseError struct {
err error
message string
Expand All @@ -20,23 +21,11 @@ func (d *DatabaseError) Error() string {
)
}

// NewDatabaseError creates a new DatabaseError, wraps err and adds a message
func NewDatabaseError(t RethinkTable, err error, message string) *DatabaseError {
return &DatabaseError{
err: err,
table: t,
message: message,
}
}

type ConnectionError struct {
error
WrongAuthKey bool
Unreachable bool
}

type NotFound struct {
error
Database bool
Table bool
Item bool
}
1 change: 1 addition & 0 deletions db/rethink_crud.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type RethinkReader interface {
FindBy(key string, value interface{}) (*rethink.Cursor, error)
FindByAndFetch(key string, value interface{}, results interface{}) error
FindByAndFetchOne(key string, value interface{}, result interface{}) error
FindByAndCount(key string, value interface{}) (int, error)

Where(filter map[string]interface{}) (*rethink.Cursor, error)
WhereAndFetch(filter map[string]interface{}, results interface{}) error
Expand Down
18 changes: 10 additions & 8 deletions db/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,23 @@ var (

// Indexes of tables in the database
var tableIndexes = map[string][]string{
"tokens": []string{"user", "user_id"},
"accounts": []string{"name"},
"emails": []string{"user_id"},
"drafts": []string{"user_id"},
"contacts": []string{},
"threads": []string{"user_id"},
"labels": []string{},
"keys": []string{},
"tokens": []string{"user", "user_id"},
"accounts": []string{"name"},
"emails": []string{"user_id"},
"drafts": []string{"user_id"},
"contacts": []string{},
"threads": []string{"user_id"},
"labels": []string{},
"keys": []string{},
"reservations": []string{},
}

// List of names of databases
var databaseNames = []string{
"prod",
"staging",
"dev",
"test",
}

// Setup configures the RethinkDB server
Expand Down
41 changes: 41 additions & 0 deletions db/table_accounts.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package db

import (
"errors"

"github.com/lavab/api/models"
)

// AccountsTable implements the CRUD interface for accounts
type AccountsTable struct {
RethinkCRUD

Tokens *TokensTable
}

// GetAccount returns an account with specified ID
Expand All @@ -30,3 +34,40 @@ func (users *AccountsTable) FindAccountByName(name string) (*models.Account, err

return &result, nil
}

func (a *AccountsTable) GetTokenOwner(token *models.Token) (*models.Account, error) {
user, err := a.GetAccount(token.Owner)
if err != nil {
// Try to remove the orphaned token
a.Tokens.DeleteID(token.ID)
return nil, errors.New("Account disabled")
}

return user, nil
}

func (a *AccountsTable) IsUsernameUsed(name string) (bool, error) {
count, err := a.FindByAndCount("name", name)
if err != nil {
return false, err
}

if count == 0 {
return false, nil
}

return true, nil
}

func (a *AccountsTable) IsEmailUsed(email string) (bool, error) {
count, err := a.FindByAndCount("alt_email", email)
if err != nil {
return false, err
}

if count == 0 {
return false, nil
}

return true, nil
}
42 changes: 42 additions & 0 deletions db/table_contacts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package db

import (
"github.com/lavab/api/models"
)

// Contacts implements the CRUD interface for tokens
type ContactsTable struct {
RethinkCRUD
}

// GetContact returns a token with specified name
func (c *ContactsTable) GetContact(id string) (*models.Contact, error) {
var result models.Contact

if err := c.FindFetchOne(id, &result); err != nil {
return nil, err
}

return &result, nil
}

// GetOwnedBy returns all contacts owned by id
func (c *ContactsTable) GetOwnedBy(id string) ([]*models.Contact, error) {
var result []*models.Contact

err := c.WhereAndFetch(map[string]interface{}{
"owner": id,
}, &result)
if err != nil {
return nil, err
}

return result, nil
}

// DeleteOwnedBy deletes all contacts owned by id
func (c *ContactsTable) DeleteOwnedBy(id string) error {
return c.Delete(map[string]interface{}{
"owner": id,
})
}
29 changes: 29 additions & 0 deletions db/table_keys.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package db

import (
"github.com/lavab/api/models"
)

type KeysTable struct {
RethinkCRUD
}

func (k *KeysTable) FindByName(name string) ([]*models.Key, error) {
var results []*models.Key

if err := k.FindByAndFetch("owner_name", name, &results); err != nil {
return nil, err
}

return results, nil
}

func (k *KeysTable) FindByFingerprint(fp string) (*models.Key, error) {
var result models.Key

if err := k.FindFetchOne(fp, &result); err != nil {
return nil, err
}

return &result, nil
}
32 changes: 32 additions & 0 deletions db/table_reservations.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package db

// ReservationsTable is a CRUD interface for accessing the "reservation" table
type ReservationsTable struct {
RethinkCRUD
}

func (r *ReservationsTable) IsUsernameUsed(name string) (bool, error) {
count, err := r.FindByAndCount("name", name)
if err != nil {
return false, err
}

if count == 0 {
return false, nil
}

return true, nil
}

func (r *ReservationsTable) IsEmailUsed(email string) (bool, error) {
count, err := r.FindByAndCount("email", email)
if err != nil {
return false, err
}

if count == 0 {
return false, nil
}

return true, nil
}
21 changes: 0 additions & 21 deletions db/table_sessions.go

This file was deleted.

28 changes: 28 additions & 0 deletions db/table_tokens.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package db

import (
"github.com/lavab/api/models"
)

// TokensTable implements the CRUD interface for tokens
type TokensTable struct {
RethinkCRUD
}

// GetToken returns a token with specified name
func (t *TokensTable) GetToken(id string) (*models.Token, error) {
var result models.Token

if err := t.FindFetchOne(id, &result); err != nil {
return nil, err
}

return &result, nil
}

// DeleteOwnedBy deletes all tokens owned by id
func (t *TokensTable) DeleteOwnedBy(id string) error {
return t.Delete(map[string]interface{}{
"owner": id,
})
}
Loading