-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add api endpoint to list all authorized clients by user #954
Changes from 1 commit
adbcc5f
701e490
6857f36
8225b23
9806eb7
d0e4d9b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -64,6 +64,7 @@ func (h *Handler) SetRoutes(r *httprouter.Router) { | |
r.PUT(ConsentPath+"/:challenge/reject", h.RejectConsentRequest) | ||
|
||
r.DELETE("/oauth2/auth/sessions/login/:user", h.DeleteLoginSession) | ||
r.GET("/oauth2/auth/sessions/consent/:user", h.GetConsentSessions) | ||
r.DELETE("/oauth2/auth/sessions/consent/:user", h.DeleteUserConsentSession) | ||
r.DELETE("/oauth2/auth/sessions/consent/:user/:client", h.DeleteUserClientConsentSession) | ||
} | ||
|
@@ -133,6 +134,47 @@ func (h *Handler) DeleteUserClientConsentSession(w http.ResponseWriter, r *http. | |
w.WriteHeader(http.StatusNoContent) | ||
} | ||
|
||
// swagger:route GET /oauth2/auth/sessions/consent/{user} oAuth2 listUserClientConsentSessions | ||
// | ||
// List all consent sessions of a user | ||
// | ||
// This endpoint lists all user's granted consent sessions, including client and granted scope | ||
// | ||
// Consumes: | ||
// - application/json | ||
// | ||
// Produces: | ||
// - application/json | ||
// | ||
// Schemes: http, https | ||
// | ||
// Responses: | ||
// 200: handledConsentRequestList | ||
// 401: genericError | ||
// 403: genericError | ||
// 500: genericError | ||
|
||
func (h *Handler) GetConsentSessions(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { | ||
user := ps.ByName("user") | ||
if user == "" { | ||
h.H.WriteError(w, r, errors.WithStack(fosite.ErrInvalidRequest.WithDebug("Parameter user is not defined"))) | ||
return | ||
} | ||
|
||
sessions, err := h.M.FindPreviouslyGrantedConsentRequestsByUser(user) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, I adapted it. However, I was a bit unsure in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see, I don't think this solution will work with SQL as they don't support negative offset (I think). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh sorry, I didn't see that you duplicated the other method. Then it will obviously work. I agree that it's not the cleanest solution but it does get the job done for now. So from my side, this is fine. |
||
|
||
if err != nil { | ||
h.H.WriteError(w, r, err) | ||
return | ||
} | ||
|
||
for _, session := range sessions { | ||
session.ConsentRequest.Client = sanitizeClient(session.ConsentRequest.Client) | ||
} | ||
|
||
h.H.Write(w, r, sessions) | ||
} | ||
|
||
// swagger:route DELETE /oauth2/auth/sessions/login/{user} oAuth2 revokeAuthenticationSession | ||
// | ||
// Invalidates a user's authentication session | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -162,6 +162,22 @@ func (m *MemoryManager) VerifyAndInvalidateConsentRequest(verifier string) (*Han | |
} | ||
|
||
func (m *MemoryManager) FindPreviouslyGrantedConsentRequests(client string, subject string) ([]HandledConsentRequest, error) { | ||
var rs []HandledConsentRequest | ||
filteredByUser, _ := m.FindPreviouslyGrantedConsentRequestsByUser(subject) | ||
for _, c := range filteredByUser { | ||
if client != c.ConsentRequest.Client.GetID() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can revert this logic to |
||
continue | ||
} | ||
rs = append(rs, c) | ||
} | ||
if len(rs) == 0 { | ||
return []HandledConsentRequest{}, nil | ||
} | ||
|
||
return rs, nil | ||
} | ||
|
||
func (m *MemoryManager) FindPreviouslyGrantedConsentRequestsByUser(subject string) ([]HandledConsentRequest, error) { | ||
var rs []HandledConsentRequest | ||
for _, c := range m.handledConsentRequests { | ||
cr, err := m.GetConsentRequest(c.Challenge) | ||
|
@@ -171,10 +187,6 @@ func (m *MemoryManager) FindPreviouslyGrantedConsentRequests(client string, subj | |
return nil, err | ||
} | ||
|
||
if client != cr.Client.GetID() { | ||
continue | ||
} | ||
|
||
if subject != cr.Subject { | ||
continue | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -364,8 +364,34 @@ WHERE | |
return nil, sqlcon.HandleError(err) | ||
} | ||
|
||
return m.resolveHandledConsentRequests(a) | ||
} | ||
|
||
func (m *SQLManager) FindPreviouslyGrantedConsentRequestsByUser(subject string) ([]HandledConsentRequest, error) { | ||
var a []sqlHandledConsentRequest | ||
|
||
if err := m.db.Select(&a, m.db.Rebind(`SELECT h.* FROM | ||
hydra_oauth2_consent_request_handled as h | ||
JOIN | ||
hydra_oauth2_consent_request as r ON (h.challenge = r.challenge) | ||
WHERE | ||
r.subject=? AND r.skip=FALSE | ||
AND | ||
(h.error='{}' AND h.remember=TRUE) | ||
`), subject); err != nil { | ||
if err == sql.ErrNoRows { | ||
return nil, errors.WithStack(errNoPreviousConsentFound) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So one issue with this is that the HTTP handler function will return Please also add a test for this. It should check that In the handler, you may want to choose to ignore the error of type There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for your help and your feedback! I have gladly implemented your suggestions. However, I'm a little unsure at this point and need your help: Does Or did I misunderstand and the manager should generate and return an |
||
} | ||
return nil, sqlcon.HandleError(err) | ||
} | ||
|
||
return m.resolveHandledConsentRequests(a) | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove newline |
||
} | ||
|
||
func (m *SQLManager) resolveHandledConsentRequests(requests []sqlHandledConsentRequest) ([]HandledConsentRequest, error) { | ||
var aa []HandledConsentRequest | ||
for _, v := range a { | ||
for _, v := range requests { | ||
r, err := m.GetConsentRequest(v.Challenge) | ||
if err != nil { | ||
return nil, err | ||
|
@@ -376,12 +402,10 @@ WHERE | |
if v.RememberFor > 0 && v.RequestedAt.Add(time.Duration(v.RememberFor)*time.Second).Before(time.Now().UTC()) { | ||
continue | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Re-add newline |
||
va, err := v.toHandledConsentRequest(r) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Re-add newline |
||
aa = append(aa, *va) | ||
} | ||
|
||
|
@@ -390,4 +414,5 @@ WHERE | |
} | ||
|
||
return aa, nil | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove newline |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -96,7 +96,7 @@ type HandledConsentRequest struct { | |
// authorization will be remembered indefinitely. | ||
RememberFor int `json:"remember_for"` | ||
|
||
ConsentRequest *ConsentRequest `json:"-"` | ||
ConsentRequest *ConsentRequest `json:"consent_request"` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The problem with exposing this is that acceptance of the consent request could overwrite this value and potentially mess stuff up. I haven't checked if that's actually the case but it could be an issue in some regression. I think it would be ok to copy this struct 1:1 and there set the var foo HandledConsentRequest
var bar = NewTypeWithJSON(HandledConsentRequest) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I called it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about |
||
Error *RequestDeniedError `json:"-"` | ||
Challenge string `json:"-"` | ||
RequestedAt time.Time `json:"-"` | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the naming should be
listUserConsentSessions
. With the current naming, I would expect the method to be likelistUserClientConsentSessions(user, client string)