Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ script:
- hydra clients create --id foobar
- hydra clients delete foobar
# Test token on arbitrary endpoints
- curl --header "Authorization: bearer $(hydra token client)" http://localhost:4444/clients
- |-
curl --header "Authorization: bearer $(hydra token client)" http://localhost:4444/clients
# Test token validation
- hydra token validate $(hydra token client)

Expand Down
34 changes: 31 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,15 @@
[![HTTP API Documentation](https://img.shields.io/badge/docs-http%20api-blue.svg)](http://docs.hdyra.apiary.io/)
[![Code Documentation](https://img.shields.io/badge/docs-godoc-blue.svg)](https://godoc.org/github.com/ory-am/hydra)

Hydra is a runnable server implementation of the OAuth 2.0 authorization framework and the OpenID Connect Core 1.0. Hydra acts as a middle-man infrastructure between your existing application and any OAuth 2.0 / OpenID Connect clients that consume your APIs.
Hydra is a runnable server implementation of the OAuth 2.0 authorization framework and the OpenID Connect Core 1.0.

Hydra is different from [keycloak](https://github.com/keycloak/keycloak), [coreos/dex](https://github.com/coreos/dex),
[IdentityServer3](http://identityserver.io/), and others because those projects usually solve the whole authentication,
authorization, user and profile management stack. While they usually integrate with LDAP or other common standards,
they will not always be able to cover 100% of what you need. Hydra however externalises
the concern of authentication to the *consent app* and works with 2fa, retina scan, touch id, or your 5 years
old, legacy, PHP login app. Hydra acts as a middle-man infrastructure between your existing application and
any OAuth 2.0 / OpenID Connect clients that consume your APIs.

Join our [newsletter](http://eepurl.com/bKT3N9) to stay on top of new developments.
We answer basic support requests on [Google Groups](https://groups.google.com/forum/#!forum/ory-hydra/new) and [Gitter](https://gitter.im/ory-am/hydra)
Expand All @@ -46,7 +54,10 @@ the access control SDK [Ladon](https://github.com/ory-am/ladon).
- [HTTP API Documentation](#http-api-documentation)
- [Command Line Documentation](#command-line-documentation)
- [Develop](#develop)
- [Third-party libraries and projects](#third-party-libraries-and-projects)
- [Hydra Ecosystem](#hydra-ecosystem)
- [Libraries](#libraries)
- [Articles](#articles)
- [Testimonials](#testimonials)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

Expand Down Expand Up @@ -200,6 +211,23 @@ docker run --name some-rethink -d -p 8080:8080 -p 28015:28015 rethinkdb
DATABASE_URL=rethinkdb://localhost:28015/hydra go run main.go host
```

## Third-party libraries and projects
## Hydra Ecosystem

This is a list of useful links for working with Hydra:

### Libraries

* [Hydra middleware for Gin](https://github.com/janekolszak/gin-hydra)
* [Exemplary consent app](https://github.com/ory-am/hydra-idp-react/)
* [Hydra NodeJS SDK](https://github.com/ory-am/hydra-js)
* [Identity Provider SDK for Go](https://github.com/janekolszak/idp)

### Articles

* [Creating an oauth2 custom lamda authorizer for use with Amazons (AWS) API Gateway using Hydra](https://blogs.edwardwilde.com/2017/01/12/creating-an-oauth2-custom-lamda-authorizer-for-use-with-amazons-aws-api-gateway-using-hydra/)
* Warning, Hydra has changed a lot since this article: [Hydra: Run your own Identity and Access Management service in <5 Minutes](https://blog.gopheracademy.com/advent-2015/hydra-auth/)

## Testimonials

Ping @arekkas on gitter if you want your project / company listed here. The testimonial is optional,
but we would really appreciate it.
46 changes: 46 additions & 0 deletions config/backend_connections.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
r "gopkg.in/dancannon/gorethink.v2"
"gopkg.in/redis.v5"
"strings"
"runtime"
)

type MemoryConnection struct{}
Expand Down Expand Up @@ -53,9 +54,54 @@ func (c *SQLConnection) GetDatabase() *sqlx.DB {
logrus.Fatalf("Could not connect to SQL: %s", err)
}



maxConns := maxParallelism() * 2
if v := c.URL.Query().Get("max_conns"); v != "" {
s, err := strconv.ParseInt(v, 10, 64)
if err != nil {
logrus.Warnf("max_conns value %s could not be parsed to int: %s", v, err)
} else {
maxConns = int(s)
}
}

maxIdleConns := maxParallelism()
if v := c.URL.Query().Get("max_idle_conns"); v != "" {
s, err := strconv.ParseInt(v, 10, 64)
if err != nil {
logrus.Warnf("max_idle_conns value %s could not be parsed to int: %s", v, err)
} else {
maxIdleConns = int(s)
}
}

maxConnLifetime := time.Duration(0)
if v := c.URL.Query().Get("max_conn_lifetime"); v != "" {
s, err := time.ParseDuration(v)
if err != nil {
logrus.Warnf("max_conn_lifetime value %s could not be parsed to int: %s", v, err)
} else {
maxConnLifetime = s
}
}

c.db.SetMaxOpenConns(maxConns)
c.db.SetMaxIdleConns(maxIdleConns)
c.db.SetConnMaxLifetime(maxConnLifetime)

return c.db
}

func maxParallelism() int {
maxProcs := runtime.GOMAXPROCS(0)
numCPU := runtime.NumCPU()
if maxProcs < numCPU {
return maxProcs
}
return numCPU
}

type RethinkDBConnection struct {
session *r.Session
URL *url.URL
Expand Down
12 changes: 12 additions & 0 deletions jwk/manager_sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,17 @@ func (m *SQLManager) AddKeySet(set string, keys *jose.JsonWebKeySet) error {
for _, key := range keys.Keys {
out, err := json.Marshal(key)
if err != nil {
if re := tx.Rollback(); re != nil {
return errors.Wrap(err, re.Error())
}
return errors.WithStack(err)
}

encrypted, err := m.Cipher.Encrypt(out)
if err != nil {
if re := tx.Rollback(); re != nil {
return errors.Wrap(err, re.Error())
}
return errors.WithStack(err)
}

Expand All @@ -98,11 +104,17 @@ func (m *SQLManager) AddKeySet(set string, keys *jose.JsonWebKeySet) error {
Version: 0,
Key: encrypted,
}); err != nil {
if re := tx.Rollback(); re != nil {
return errors.Wrap(err, re.Error())
}
return errors.WithStack(err)
}
}

if err := tx.Commit(); err != nil {
if re := tx.Rollback(); re != nil {
return errors.Wrap(err, re.Error())
}
return errors.WithStack(err)
}
return nil
Expand Down
2 changes: 1 addition & 1 deletion oauth2/fosite_store_redis.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type redisSchema struct {
RequestedAt time.Time `json:"requestedAt"`
Client *client.Client `json:"client"`
Scopes fosite.Arguments `json:"scopes"`
GrantedScopes fosite.Arguments `json:"grantedScopes""`
GrantedScopes fosite.Arguments `json:"grantedScopes"`
Form url.Values `json:"form"`
Session json.RawMessage `json:"session"`
}
Expand Down
12 changes: 12 additions & 0 deletions warden/group/manager_sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,17 @@ func (m *SQLManager) AddGroupMembers(group string, subjects []string) error {
}
for _, subject := range subjects {
if _, err := tx.Exec(m.DB.Rebind("INSERT INTO hydra_warden_group_member (group_id, member) VALUES (?, ?)"), group, subject); err != nil {
if re := tx.Rollback(); re != nil {
return errors.Wrap(err, re.Error())
}
return errors.WithStack(err)
}
}

if err := tx.Commit(); err != nil {
if re := tx.Rollback(); re != nil {
return errors.Wrap(err, re.Error())
}
return errors.Wrap(err, "Could not commit transaction")
}
return nil
Expand All @@ -101,11 +107,17 @@ func (m *SQLManager) RemoveGroupMembers(group string, subjects []string) error {
}
for _, subject := range subjects {
if _, err := m.DB.Exec(m.DB.Rebind("DELETE FROM hydra_warden_group_member WHERE member=? AND group_id=?"), subject, group); err != nil {
if re := tx.Rollback(); re != nil {
return errors.Wrap(err, re.Error())
}
return errors.WithStack(err)
}
}

if err := tx.Commit(); err != nil {
if re := tx.Rollback(); re != nil {
return errors.Wrap(err, re.Error())
}
return errors.Wrap(err, "Could not commit transaction")
}
return nil
Expand Down