Skip to content

Commit a922002

Browse files
authored
0.5.0 (#243)
* cmd: hydra token user should show id token in browser - closes #224 * cli: hydra clients import doesn't print client's secret - closes #221 * travis: ld flags are wrong - closes #242 * all: resolve naming inconsistencies in jwk set names used in hydra - closes #239 * sdk: resolve naming inconsistencies - closes #226 * docs: resolve gitbook issue with image assets * jwk: anonymous request can't read public keys - closes #253 * client: add ability to update client - closes #250 * core: document hard-wired JWK sets - closes #247 * docs: fix images in readme - closes #261
1 parent 3c3b93e commit a922002

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+535
-345
lines changed

.travis.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@ script:
3131
- $GOPATH/bin/hydra token client --skip-tls-verify
3232

3333
after_success:
34-
- gox -ldflags "-X main.Version=`git describe --tags` -X main.BuildTime=`TZ=UTC date -u '+%Y-%m-%dT%H:%M:%SZ'` -X main.GitHash=`git rev-parse HEAD`" -output "dist/{{.Dir}}-{{.OS}}-{{.Arch}}"
35-
# - ghr --username arekkas --token $GITHUB_TOKEN --replace --prerelease --debug pre-release dist/
34+
- gox -ldflags "-X github.com/ory-am/hydra/cmd.Version=`git describe --tags` -X github.com/ory-am/hydra/cmd.BuildTime=`TZ=UTC date -u '+%Y-%m-%dT%H:%M:%SZ'` -X github.com/ory-am/hydra/cmd.GitHash=`git rev-parse HEAD`" -output "dist/{{.Dir}}-{{.OS}}-{{.Arch}}"
3635

3736
deploy:
3837
provider: releases

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# ![Ory/Hydra](docs/dist/images/logo.png)
1+
# ![Ory/Hydra](docs/images/logo.png)
22

33
[![Join the chat at https://gitter.im/ory-am/hydra](https://img.shields.io/badge/join-chat-00cc99.svg)](https://gitter.im/ory-am/hydra?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
44
[![Join mailinglist](https://img.shields.io/badge/join-mailinglist-00cc99.svg)](https://groups.google.com/forum/#!forum/ory-hydra/new)
@@ -118,7 +118,7 @@ Hydra is packaged using [Docker](https://hub.docker.com/r/oryam/hydra/).
118118
6. **Open Source:** Hydra is licensed under Apache Version 2.0
119119
7. **Professional:** Hydra implements peer reviewed open standards published by [The Internet Engineering Task Force (IETF®)](https://www.ietf.org/) and the [OpenID Foundation](https://openid.net/)
120120
and under supervision of the [LMU Teaching and Research Unit Programming and Modelling Languages](http://www.en.pms.ifi.lmu.de). No funny business.
121-
8. <img src="docs/dist/images/monitoring.gif" width="45%" align="right"> **Real Time:** Operation is a lot easier with real time. There are no caches,
121+
8. <img src="docs/images/monitoring.gif" width="45%" align="right"> **Real Time:** Operation is a lot easier with real time. There are no caches,
122122
no invalidation strategies and no magic - just simple, cloud native pub-sub. Hydra leverages RethinkDB, so check out their real time database monitoring too!
123123

124124
<br clear="all">
@@ -188,7 +188,7 @@ The **[tutorial](https://ory-am.gitbooks.io/hydra/content/demo.html)** teaches y
188188
a RethinkDB instance and an exemplary identity provider written in React using docker compose.
189189
It will take you about 5 minutes to get complete the **[tutorial](https://ory-am.gitbooks.io/hydra/content/demo.html)**.
190190

191-
<img src="docs/dist/images/oauth2-flow.gif" alt="OAuth2 Flow">
191+
<img src="docs/images/oauth2-flow.gif" alt="OAuth2 Flow">
192192

193193
<br clear="all">
194194

client/handler.go

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"fmt"
66
"net/http"
77

8-
"github.com/go-errors/errors"
8+
"github.com/pkg/errors"
99
"github.com/julienschmidt/httprouter"
1010
"github.com/ory-am/common/rand/sequence"
1111
"github.com/ory-am/hydra/firewall"
@@ -33,6 +33,7 @@ func (h *Handler) SetRoutes(r *httprouter.Router) {
3333
r.GET(ClientsHandlerPath, h.GetAll)
3434
r.POST(ClientsHandlerPath, h.Create)
3535
r.GET(ClientsHandlerPath+"/:id", h.Get)
36+
r.PUT(ClientsHandlerPath+"/:id", h.Update)
3637
r.DELETE(ClientsHandlerPath+"/:id", h.Delete)
3738
}
3839

@@ -41,7 +42,7 @@ func (h *Handler) Create(w http.ResponseWriter, r *http.Request, _ httprouter.Pa
4142
var ctx = herodot.NewContext()
4243

4344
if err := json.NewDecoder(r.Body).Decode(&c); err != nil {
44-
h.H.WriteError(ctx, w, r, errors.New(err))
45+
h.H.WriteError(ctx, w, r, errors.Wrap(err, ""))
4546
return
4647
}
4748

@@ -59,7 +60,7 @@ func (h *Handler) Create(w http.ResponseWriter, r *http.Request, _ httprouter.Pa
5960
if len(c.Secret) == 0 {
6061
secret, err := sequence.RuneSequence(12, []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_-.,:;$%!&/()=?+*#<>"))
6162
if err != nil {
62-
h.H.WriteError(ctx, w, r, errors.New(err))
63+
h.H.WriteError(ctx, w, r, errors.Wrap(err, ""))
6364
return
6465
}
6566
c.Secret = string(secret)
@@ -77,6 +78,39 @@ func (h *Handler) Create(w http.ResponseWriter, r *http.Request, _ httprouter.Pa
7778
h.H.WriteCreated(ctx, w, r, ClientsHandlerPath+"/"+c.GetID(), &c)
7879
}
7980

81+
func (h *Handler) Update(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
82+
var c Client
83+
var ctx = herodot.NewContext()
84+
85+
if err := json.NewDecoder(r.Body).Decode(&c); err != nil {
86+
h.H.WriteError(ctx, w, r, errors.Wrap(err, ""))
87+
return
88+
}
89+
90+
if _, err := h.W.TokenAllowed(ctx, h.W.TokenFromRequest(r), &ladon.Request{
91+
Resource: ClientsResource,
92+
Action: "update",
93+
Context: ladon.Context{
94+
"owner": c.Owner,
95+
},
96+
}, Scope); err != nil {
97+
h.H.WriteError(ctx, w, r, err)
98+
return
99+
}
100+
101+
if len(c.Secret) > 0 && len(c.Secret) < 6 {
102+
h.H.WriteError(ctx, w, r, errors.New("The client secret must be at least 6 characters long"))
103+
}
104+
105+
c.ID = ps.ByName("id")
106+
if err := h.Manager.UpdateClient(&c); err != nil {
107+
h.H.WriteError(ctx, w, r, err)
108+
return
109+
}
110+
111+
h.H.WriteCreated(ctx, w, r, ClientsHandlerPath+"/"+c.GetID(), &c)
112+
}
113+
80114
func (h *Handler) GetAll(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
81115
var ctx = herodot.NewContext()
82116

client/manager.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ type Storage interface {
1515

1616
CreateClient(c *Client) error
1717

18+
UpdateClient(c *Client) error
19+
1820
DeleteClient(id string) error
1921

2022
GetClients() (map[string]Client, error)

client/manager_http.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ func (m *HTTPManager) GetClient(id string) (fosite.Client, error) {
3030
return m.GetConcreteClient(id)
3131
}
3232

33+
func (m *HTTPManager) UpdateClient(c *Client) error {
34+
var r = pkg.NewSuperAgent(pkg.JoinURL(m.Endpoint, c.ID).String())
35+
r.Client = m.Client
36+
r.Dry = m.Dry
37+
return r.Update(c)
38+
}
39+
3340
func (m *HTTPManager) CreateClient(c *Client) error {
3441
var r = pkg.NewSuperAgent(m.Endpoint.String())
3542
r.Client = m.Client

client/manager_memory.go

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ package client
33
import (
44
"sync"
55

6-
"github.com/go-errors/errors"
6+
"github.com/pkg/errors"
77
"github.com/ory-am/fosite"
88
"github.com/ory-am/fosite/hash"
99
"github.com/ory-am/hydra/pkg"
1010
"github.com/pborman/uuid"
11+
"github.com/imdario/mergo"
1112
)
1213

1314
type MemoryManager struct {
@@ -22,7 +23,7 @@ func (m *MemoryManager) GetConcreteClient(id string) (*Client, error) {
2223

2324
c, ok := m.Clients[id]
2425
if !ok {
25-
return nil, errors.New(pkg.ErrNotFound)
26+
return nil, errors.Wrap(pkg.ErrNotFound, "")
2627
}
2728
return &c, nil
2829
}
@@ -31,17 +32,40 @@ func (m *MemoryManager) GetClient(id string) (fosite.Client, error) {
3132
return m.GetConcreteClient(id)
3233
}
3334

35+
func (m *MemoryManager) UpdateClient(c *Client) error {
36+
o, err := m.GetClient(c.ID)
37+
if err != nil {
38+
return err
39+
}
40+
41+
if c.Secret == "" {
42+
c.Secret = string(o.GetHashedSecret())
43+
} else {
44+
h, err := m.Hasher.Hash([]byte(c.Secret))
45+
if err != nil {
46+
return errors.Wrap(err, "")
47+
}
48+
c.Secret = string(h)
49+
}
50+
if err := mergo.Merge(c, o); err != nil {
51+
return errors.Wrap(err, "")
52+
}
53+
54+
m.Clients[c.GetID()] = *c
55+
return nil
56+
}
57+
3458
func (m *MemoryManager) Authenticate(id string, secret []byte) (*Client, error) {
3559
m.RLock()
3660
defer m.RUnlock()
3761

3862
c, ok := m.Clients[id]
3963
if !ok {
40-
return nil, errors.New(pkg.ErrNotFound)
64+
return nil, errors.Wrap(pkg.ErrNotFound, "")
4165
}
4266

4367
if err := m.Hasher.Compare(c.GetHashedSecret(), secret); err != nil {
44-
return nil, errors.New(err)
68+
return nil, errors.Wrap(err, "")
4569
}
4670

4771
return &c, nil
@@ -57,7 +81,7 @@ func (m *MemoryManager) CreateClient(c *Client) error {
5781

5882
hash, err := m.Hasher.Hash([]byte(c.Secret))
5983
if err != nil {
60-
return errors.New(err)
84+
return errors.Wrap(err, "")
6185
}
6286
c.Secret = string(hash)
6387

client/manager_rethinkdb.go

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ import (
55
"time"
66

77
"github.com/Sirupsen/logrus"
8-
"github.com/go-errors/errors"
8+
"github.com/pkg/errors"
99
"github.com/ory-am/fosite"
1010
"github.com/ory-am/fosite/hash"
1111
"github.com/ory-am/hydra/pkg"
1212
"github.com/pborman/uuid"
1313
"golang.org/x/net/context"
1414
r "gopkg.in/dancannon/gorethink.v2"
15+
"github.com/imdario/mergo"
1516
)
1617

1718
type RethinkManager struct {
@@ -29,7 +30,7 @@ func (m *RethinkManager) GetConcreteClient(id string) (*Client, error) {
2930

3031
c, ok := m.Clients[id]
3132
if !ok {
32-
return nil, errors.New(pkg.ErrNotFound)
33+
return nil, errors.Wrap(pkg.ErrNotFound, "")
3334
}
3435
return &c, nil
3536
}
@@ -44,11 +45,11 @@ func (m *RethinkManager) Authenticate(id string, secret []byte) (*Client, error)
4445

4546
c, ok := m.Clients[id]
4647
if !ok {
47-
return nil, errors.New(pkg.ErrNotFound)
48+
return nil, errors.Wrap(pkg.ErrNotFound, "")
4849
}
4950

5051
if err := m.Hasher.Compare(c.GetHashedSecret(), secret); err != nil {
51-
return nil, errors.New(err)
52+
return nil, errors.Wrap(err, "")
5253
}
5354

5455
return &c, nil
@@ -59,11 +60,11 @@ func (m *RethinkManager) CreateClient(c *Client) error {
5960
c.ID = uuid.New()
6061
}
6162

62-
hash, err := m.Hasher.Hash([]byte(c.Secret))
63+
h, err := m.Hasher.Hash([]byte(c.Secret))
6364
if err != nil {
64-
return errors.New(err)
65+
return errors.Wrap(err, "")
6566
}
66-
c.Secret = string(hash)
67+
c.Secret = string(h)
6768

6869
if err := m.publishCreate(c); err != nil {
6970
return err
@@ -72,6 +73,32 @@ func (m *RethinkManager) CreateClient(c *Client) error {
7273
return nil
7374
}
7475

76+
func (m *RethinkManager) UpdateClient(c *Client) error {
77+
o, err := m.GetClient(c.ID)
78+
if err != nil {
79+
return err
80+
}
81+
82+
if c.Secret == "" {
83+
c.Secret = string(o.GetHashedSecret())
84+
} else {
85+
h, err := m.Hasher.Hash([]byte(c.Secret))
86+
if err != nil {
87+
return errors.Wrap(err, "")
88+
}
89+
c.Secret = string(h)
90+
}
91+
if err := mergo.Merge(c, o); err != nil {
92+
return errors.Wrap(err, "")
93+
}
94+
95+
if err := m.publishUpdate(c); err != nil {
96+
return err
97+
}
98+
99+
return nil
100+
}
101+
75102
func (m *RethinkManager) DeleteClient(id string) error {
76103
if err := m.publishDelete(id); err != nil {
77104
return err
@@ -95,7 +122,7 @@ func (m *RethinkManager) ColdStart() error {
95122
m.Clients = map[string]Client{}
96123
clients, err := m.Table.Run(m.Session)
97124
if err != nil {
98-
return errors.New(err)
125+
return errors.Wrap(err, "")
99126
}
100127

101128
var client Client
@@ -108,16 +135,23 @@ func (m *RethinkManager) ColdStart() error {
108135
return nil
109136
}
110137

138+
func (m *RethinkManager) publishUpdate(client *Client) error {
139+
if err := m.publishDelete(client.ID); err != nil {
140+
return err
141+
}
142+
return m.publishCreate(client)
143+
}
144+
111145
func (m *RethinkManager) publishCreate(client *Client) error {
112146
if _, err := m.Table.Insert(client).RunWrite(m.Session); err != nil {
113-
return errors.New(err)
147+
return errors.Wrap(err, "")
114148
}
115149
return nil
116150
}
117151

118152
func (m *RethinkManager) publishDelete(id string) error {
119153
if _, err := m.Table.Get(id).Delete().RunWrite(m.Session); err != nil {
120-
return errors.New(err)
154+
return errors.Wrap(err, "")
121155
}
122156
return nil
123157
}
@@ -126,7 +160,7 @@ func (m *RethinkManager) Watch(ctx context.Context) {
126160
go pkg.Retry(time.Second*15, time.Minute, func() error {
127161
clients, err := m.Table.Changes().Run(m.Session)
128162
if err != nil {
129-
return errors.New(err)
163+
return errors.Wrap(err, "")
130164
}
131165
defer clients.Close()
132166

@@ -148,7 +182,7 @@ func (m *RethinkManager) Watch(ctx context.Context) {
148182
}
149183

150184
if clients.Err() != nil {
151-
err = errors.New(clients.Err())
185+
err = errors.Wrap(clients.Err(), "")
152186
pkg.LogError(err)
153187
return err
154188
}

0 commit comments

Comments
 (0)