Skip to content

Commit c7eb84a

Browse files
authored
feat: Query auths and delete to logout (#15)
1 parent 42bd483 commit c7eb84a

File tree

2 files changed

+135
-0
lines changed

2 files changed

+135
-0
lines changed

pkg/auth/auth.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
const (
1919
CookieTokenName = "token"
2020

21+
sessionKeyID = "id"
2122
sessionKeyProvider = "provider"
2223
sessionKeyToken = "token"
2324

@@ -36,8 +37,10 @@ func RegisterAuthEndpoint(e *echo.Echo, hashKey, blockKey []byte, providers map[
3637
}))
3738

3839
g.OPTIONS("", func(c echo.Context) error { _ = c.NoContent(http.StatusNoContent); return nil })
40+
g.GET("", a.listAuth)
3941
g.POST("", a.createAuth)
4042
g.PUT("/:state", a.updateAuth)
43+
g.DELETE("/:state", a.delete)
4144

4245
return a.AuthMiddleware()
4346
}
@@ -53,6 +56,7 @@ type authentication struct {
5356
}
5457

5558
type AuthResource struct {
59+
ID string `json:"id,omitempty"`
5660
Idp string `json:"idp"`
5761
Path string `json:"path,omitempty"`
5862
AuthorizationURL string `json:"authorizationUrl,omitempty"`
@@ -195,6 +199,7 @@ func (a *auth) updateAuth(c echo.Context) error {
195199
Path: "/",
196200
MaxAge: 86400 * 30,
197201
}
202+
ts.Values[sessionKeyID] = state
198203
ts.Values[sessionKeyToken] = token
199204
ts.Values[sessionKeyProvider] = au.Idp
200205
err = ts.Save(c.Request(), c.Response())
@@ -218,3 +223,70 @@ func (a *auth) updateAuth(c echo.Context) error {
218223

219224
return nil
220225
}
226+
227+
func (a *auth) listAuth(c echo.Context) error {
228+
type list struct {
229+
Count int `json:"count"`
230+
Auths []string `json:"auths"`
231+
Included []interface{} `json:"@included,omitempty"`
232+
}
233+
234+
s, err := session.Get(CookieTokenName, c)
235+
if err != nil {
236+
_ = c.NoContent(http.StatusInternalServerError)
237+
return fmt.Errorf("unable to get session: %w", err)
238+
}
239+
240+
l := &list{
241+
Count: 0,
242+
Auths: []string{},
243+
}
244+
245+
id, ok := s.Values[sessionKeyID].(string)
246+
if !ok {
247+
return c.JSON(http.StatusOK, l)
248+
}
249+
250+
idp, ok := s.Values[sessionKeyProvider].(string)
251+
if !ok {
252+
return c.JSON(http.StatusOK, l)
253+
}
254+
255+
l.Count = 1
256+
l.Auths = append(l.Auths, "id")
257+
l.Included = []interface{}{
258+
&AuthResource{
259+
ID: id,
260+
Idp: idp,
261+
},
262+
}
263+
264+
return c.JSON(http.StatusOK, l)
265+
}
266+
267+
func (a *auth) delete(c echo.Context) error {
268+
state := c.Param("state")
269+
270+
s, err := session.Get(CookieTokenName, c)
271+
if err != nil {
272+
_ = c.NoContent(http.StatusInternalServerError)
273+
return fmt.Errorf("unable to get session: %w", err)
274+
}
275+
276+
id, ok := s.Values[sessionKeyID].(string)
277+
if !ok {
278+
return c.NoContent(http.StatusNotFound)
279+
}
280+
281+
if id != state {
282+
return c.NoContent(http.StatusNotFound)
283+
}
284+
285+
s.Options = &sessions.Options{MaxAge: -1}
286+
err = s.Save(c.Request(), c.Response())
287+
if err != nil {
288+
return fmt.Errorf("unable to remove auth session: %w", err)
289+
}
290+
291+
return c.NoContent(http.StatusNoContent)
292+
}

pkg/auth/auth_test.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,40 @@ func TestCreateAuth(t *testing.T) {
5757
}
5858
}
5959

60+
func TestListAuths(t *testing.T) {
61+
e := echo.New()
62+
63+
sStore := &sessionStoreMock{
64+
Sessions: map[string]*sessions.Session{},
65+
}
66+
mw := session.Middleware(sStore)
67+
ses := sessions.NewSession(sStore, CookieTokenName)
68+
sStore.Sessions[CookieTokenName] = ses
69+
70+
ses.Values[sessionKeyID] = "id"
71+
ses.Values[sessionKeyProvider] = "provider"
72+
73+
req := httptest.NewRequest(http.MethodGet, "/", nil)
74+
rec := httptest.NewRecorder()
75+
76+
c := e.NewContext(req, rec)
77+
mw(echo.NotFoundHandler)(c)
78+
79+
auth := &auth{}
80+
81+
err := auth.listAuth(c)
82+
if assert.NoError(t, err) {
83+
assert.Equal(t, http.StatusOK, rec.Code)
84+
data := map[string]interface{}{}
85+
assert.NoError(t, json.Unmarshal(rec.Body.Bytes(), &data))
86+
ids, ok := data["auths"].([]interface{})
87+
assert.True(t, ok)
88+
id, ok := ids[0].(string)
89+
assert.True(t, ok)
90+
assert.Equal(t, "id", id)
91+
}
92+
}
93+
6094
func TestUpdateAuth(t *testing.T) {
6195
e := echo.New()
6296
state := uuid.NewString()
@@ -114,6 +148,35 @@ func TestUpdateAuth(t *testing.T) {
114148
}
115149
}
116150

151+
func TestDelete(t *testing.T) {
152+
e := echo.New()
153+
154+
sStore := &sessionStoreMock{
155+
Sessions: map[string]*sessions.Session{},
156+
}
157+
mw := session.Middleware(sStore)
158+
ses := sessions.NewSession(sStore, CookieTokenName)
159+
sStore.Sessions[CookieTokenName] = ses
160+
161+
ses.Values[sessionKeyID] = "id"
162+
ses.Values[sessionKeyProvider] = "provider"
163+
164+
req := httptest.NewRequest(http.MethodDelete, "/", nil)
165+
rec := httptest.NewRecorder()
166+
167+
c := e.NewContext(req, rec)
168+
c.SetPath("/auths/:state")
169+
c.SetParamNames("state")
170+
c.SetParamValues("id")
171+
mw(echo.NotFoundHandler)(c)
172+
173+
auth := &auth{}
174+
err := auth.delete(c)
175+
if assert.NoError(t, err) {
176+
assert.Equal(t, http.StatusNoContent, rec.Code)
177+
}
178+
}
179+
117180
func TestAuthMiddleware(t *testing.T) {
118181
e := echo.New()
119182

0 commit comments

Comments
 (0)