/engine/api/auth_consumer_test.go

https://github.com/ovh/cds · Go · 300 lines · 246 code · 48 blank · 6 comment · 0 complexity · bc63709e0e6a43349bc7eff8e0cac5ae MD5 · raw file

  1. package api
  2. import (
  3. "context"
  4. "encoding/json"
  5. "net/http"
  6. "net/http/httptest"
  7. "testing"
  8. "time"
  9. "github.com/stretchr/testify/assert"
  10. "github.com/stretchr/testify/require"
  11. "github.com/ovh/cds/engine/api/authentication"
  12. "github.com/ovh/cds/engine/api/authentication/builtin"
  13. "github.com/ovh/cds/engine/api/test/assets"
  14. "github.com/ovh/cds/sdk"
  15. )
  16. func Test_getConsumersByUserHandler(t *testing.T) {
  17. api, db, _ := newTestAPI(t)
  18. u, jwtRaw := assets.InsertLambdaUser(t, db)
  19. localConsumer, err := authentication.LoadConsumerByTypeAndUserID(context.TODO(), db, sdk.ConsumerLocal, u.ID,
  20. authentication.LoadConsumerOptions.WithAuthentifiedUser)
  21. require.NoError(t, err)
  22. consumer, _, err := builtin.NewConsumer(context.TODO(), db, sdk.RandomString(10), "", localConsumer, nil,
  23. sdk.NewAuthConsumerScopeDetails(sdk.AuthConsumerScopeUser))
  24. require.NoError(t, err)
  25. uri := api.Router.GetRoute(http.MethodGet, api.getConsumersByUserHandler, map[string]string{
  26. "permUsername": u.Username,
  27. })
  28. require.NotEmpty(t, uri)
  29. req := assets.NewJWTAuthentifiedRequest(t, jwtRaw, http.MethodGet, uri, nil)
  30. rec := httptest.NewRecorder()
  31. api.Router.Mux.ServeHTTP(rec, req)
  32. require.Equal(t, 200, rec.Code)
  33. var cs []sdk.AuthConsumer
  34. require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &cs))
  35. require.Equal(t, 2, len(cs))
  36. assert.Equal(t, localConsumer.ID, cs[0].ID)
  37. assert.Equal(t, consumer.ID, cs[1].ID)
  38. uri = api.Router.GetRoute(http.MethodGet, api.getConsumersByUserHandler, map[string]string{
  39. "permUsername": "me",
  40. })
  41. require.NotEmpty(t, uri)
  42. req = assets.NewJWTAuthentifiedRequest(t, jwtRaw, http.MethodGet, uri, nil)
  43. rec = httptest.NewRecorder()
  44. api.Router.Mux.ServeHTTP(rec, req)
  45. require.Equal(t, 200, rec.Code)
  46. require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &cs))
  47. require.Equal(t, 2, len(cs))
  48. assert.Equal(t, localConsumer.ID, cs[0].ID)
  49. assert.Equal(t, consumer.ID, cs[1].ID)
  50. }
  51. func Test_postConsumerByUserHandler(t *testing.T) {
  52. api, db, _ := newTestAPI(t)
  53. g := assets.InsertGroup(t, db)
  54. u, jwtRaw := assets.InsertLambdaUser(t, db, g)
  55. localConsumer, err := authentication.LoadConsumerByTypeAndUserID(context.TODO(), db, sdk.ConsumerLocal, u.ID)
  56. require.NoError(t, err)
  57. _, jwtRawAdmin := assets.InsertAdminUser(t, db)
  58. data := sdk.AuthConsumer{
  59. Name: sdk.RandomString(10),
  60. GroupIDs: []int64{g.ID},
  61. ScopeDetails: sdk.NewAuthConsumerScopeDetails(sdk.AuthConsumerScopeAccessToken),
  62. IssuedAt: time.Now(),
  63. }
  64. uri := api.Router.GetRoute(http.MethodPost, api.postConsumerByUserHandler, map[string]string{
  65. "permUsername": u.Username,
  66. })
  67. require.NotEmpty(t, uri)
  68. req := assets.NewJWTAuthentifiedRequest(t, jwtRawAdmin, http.MethodPost, uri, data)
  69. rec := httptest.NewRecorder()
  70. api.Router.Mux.ServeHTTP(rec, req)
  71. require.Equal(t, 403, rec.Code)
  72. uri = api.Router.GetRoute(http.MethodPost, api.postConsumerByUserHandler, map[string]string{
  73. "permUsername": u.Username,
  74. })
  75. require.NotEmpty(t, uri)
  76. req = assets.NewJWTAuthentifiedRequest(t, jwtRaw, http.MethodPost, uri, data)
  77. rec = httptest.NewRecorder()
  78. api.Router.Mux.ServeHTTP(rec, req)
  79. require.Equal(t, 201, rec.Code)
  80. var created sdk.AuthConsumerCreateResponse
  81. require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &created))
  82. assert.NotEmpty(t, created.Token)
  83. assert.Equal(t, data.Name, created.Consumer.Name)
  84. require.Equal(t, 1, len(created.Consumer.GroupIDs))
  85. assert.Equal(t, g.ID, created.Consumer.GroupIDs[0])
  86. require.Equal(t, 1, len(created.Consumer.ScopeDetails))
  87. assert.Equal(t, sdk.AuthConsumerScopeAccessToken, created.Consumer.ScopeDetails[0].Scope)
  88. assert.Equal(t, localConsumer.ID, *created.Consumer.ParentID)
  89. }
  90. func Test_deleteConsumerByUserHandler(t *testing.T) {
  91. api, db, _ := newTestAPI(t)
  92. u, jwtRaw := assets.InsertLambdaUser(t, db)
  93. localConsumer, err := authentication.LoadConsumerByTypeAndUserID(context.TODO(), db, sdk.ConsumerLocal, u.ID,
  94. authentication.LoadConsumerOptions.WithAuthentifiedUser)
  95. require.NoError(t, err)
  96. newConsumer, _, err := builtin.NewConsumer(context.TODO(), db, sdk.RandomString(10), "", localConsumer, nil,
  97. sdk.NewAuthConsumerScopeDetails(sdk.AuthConsumerScopeAccessToken))
  98. require.NoError(t, err)
  99. cs, err := authentication.LoadConsumersByUserID(context.TODO(), db, u.ID)
  100. require.NoError(t, err)
  101. assert.Equal(t, 2, len(cs))
  102. uri := api.Router.GetRoute(http.MethodDelete, api.deleteConsumerByUserHandler, map[string]string{
  103. "permUsername": u.Username,
  104. "permConsumerID": newConsumer.ID,
  105. })
  106. require.NotEmpty(t, uri)
  107. req := assets.NewJWTAuthentifiedRequest(t, jwtRaw, http.MethodDelete, uri, nil)
  108. rec := httptest.NewRecorder()
  109. api.Router.Mux.ServeHTTP(rec, req)
  110. require.Equal(t, 200, rec.Code)
  111. cs, err = authentication.LoadConsumersByUserID(context.TODO(), db, u.ID)
  112. require.NoError(t, err)
  113. assert.Equal(t, 1, len(cs))
  114. }
  115. func Test_postConsumerRegenByUserHandler(t *testing.T) {
  116. api, db, _ := newTestAPI(t)
  117. u, jwtRaw := assets.InsertLambdaUser(t, db)
  118. localConsumer, err := authentication.LoadConsumerByTypeAndUserID(context.TODO(), db, sdk.ConsumerLocal, u.ID,
  119. authentication.LoadConsumerOptions.WithAuthentifiedUser)
  120. require.NoError(t, err)
  121. // Test that we can't regen a no builtin consumer
  122. uri := api.Router.GetRoute(http.MethodPost, api.postConsumerRegenByUserHandler, map[string]string{
  123. "permUsername": u.Username,
  124. "permConsumerID": localConsumer.ID,
  125. })
  126. req := assets.NewJWTAuthentifiedRequest(t, jwtRaw, http.MethodPost, uri, sdk.AuthConsumerRegenRequest{})
  127. rec := httptest.NewRecorder()
  128. api.Router.Mux.ServeHTTP(rec, req)
  129. require.Equal(t, http.StatusForbidden, rec.Code)
  130. builtinConsumer, signinToken1, err := builtin.NewConsumer(context.TODO(), db, sdk.RandomString(10), "", localConsumer, nil,
  131. sdk.NewAuthConsumerScopeDetails(sdk.AuthConsumerScopeUser, sdk.AuthConsumerScopeAccessToken))
  132. require.NoError(t, err)
  133. session, err := authentication.NewSession(context.TODO(), db, builtinConsumer, 5*time.Minute, false)
  134. require.NoError(t, err, "cannot create session")
  135. jwt2, err := authentication.NewSessionJWT(session)
  136. require.NoError(t, err, "cannot create jwt")
  137. uri = api.Router.GetRoute(http.MethodGet, api.getUserHandler, map[string]string{
  138. "permUsernamePublic": "me",
  139. })
  140. require.NotEmpty(t, uri)
  141. req = assets.NewJWTAuthentifiedRequest(t, jwtRaw, http.MethodGet, uri, nil)
  142. rec = httptest.NewRecorder()
  143. api.Router.Mux.ServeHTTP(rec, req)
  144. require.Equal(t, http.StatusOK, rec.Code)
  145. req = assets.NewJWTAuthentifiedRequest(t, jwt2, http.MethodGet, uri, nil)
  146. rec = httptest.NewRecorder()
  147. api.Router.Mux.ServeHTTP(rec, req)
  148. require.Equal(t, http.StatusOK, rec.Code)
  149. // Wait 2 seconds before regen
  150. time.Sleep(2 * time.Second)
  151. uri = api.Router.GetRoute(http.MethodPost, api.postConsumerRegenByUserHandler, map[string]string{
  152. "permUsername": u.Username,
  153. "permConsumerID": builtinConsumer.ID,
  154. })
  155. req = assets.NewJWTAuthentifiedRequest(t, jwt2, http.MethodPost, uri, sdk.AuthConsumerRegenRequest{
  156. RevokeSessions: true,
  157. })
  158. rec = httptest.NewRecorder()
  159. api.Router.Mux.ServeHTTP(rec, req)
  160. require.Equal(t, http.StatusOK, rec.Code)
  161. var response sdk.AuthConsumerCreateResponse
  162. require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &response))
  163. t.Logf("%+v", response)
  164. session, err = authentication.NewSession(context.TODO(), db, builtinConsumer, 5*time.Minute, false)
  165. require.NoError(t, err)
  166. jwt3, err := authentication.NewSessionJWT(session)
  167. require.NoError(t, err)
  168. uri = api.Router.GetRoute(http.MethodGet, api.getUserHandler, map[string]string{
  169. "permUsernamePublic": "me",
  170. })
  171. // The new token should be ok
  172. req = assets.NewJWTAuthentifiedRequest(t, jwt3, http.MethodGet, uri, nil)
  173. rec = httptest.NewRecorder()
  174. api.Router.Mux.ServeHTTP(rec, req)
  175. require.Equal(t, http.StatusOK, rec.Code)
  176. // After the regen the old token should be invalidated because we choose to drop the sessions
  177. req = assets.NewJWTAuthentifiedRequest(t, jwt2, http.MethodGet, uri, nil)
  178. rec = httptest.NewRecorder()
  179. api.Router.Mux.ServeHTTP(rec, req)
  180. require.Equal(t, http.StatusUnauthorized, rec.Code)
  181. // the old signing token from the builtin consumer should be invalidated
  182. uri = api.Router.GetRoute(http.MethodPost, api.postAuthBuiltinSigninHandler, nil)
  183. req = assets.NewRequest(t, "POST", uri, sdk.AuthConsumerSigninRequest{
  184. "token": signinToken1,
  185. })
  186. rec = httptest.NewRecorder()
  187. api.Router.Mux.ServeHTTP(rec, req)
  188. require.Equal(t, http.StatusBadRequest, rec.Code)
  189. // the new signing token from the builtin consumer should be fine
  190. uri = api.Router.GetRoute(http.MethodPost, api.postAuthBuiltinSigninHandler, nil)
  191. req = assets.NewRequest(t, "POST", uri, sdk.AuthConsumerSigninRequest{
  192. "token": response.Token,
  193. })
  194. rec = httptest.NewRecorder()
  195. api.Router.Mux.ServeHTTP(rec, req)
  196. require.Equal(t, http.StatusOK, rec.Code)
  197. }
  198. func Test_getSessionsByUserHandler(t *testing.T) {
  199. api, db, _ := newTestAPI(t)
  200. u, jwtRaw := assets.InsertLambdaUser(t, db)
  201. localConsumer, err := authentication.LoadConsumerByTypeAndUserID(context.TODO(), db, sdk.ConsumerLocal, u.ID,
  202. authentication.LoadConsumerOptions.WithAuthentifiedUser)
  203. require.NoError(t, err)
  204. consumer, _, err := builtin.NewConsumer(context.TODO(), db, sdk.RandomString(10), "", localConsumer, nil,
  205. sdk.NewAuthConsumerScopeDetails(sdk.AuthConsumerScopeUser))
  206. require.NoError(t, err)
  207. s2, err := authentication.NewSession(context.TODO(), db, consumer, time.Second, false)
  208. require.NoError(t, err)
  209. s3, err := authentication.NewSession(context.TODO(), db, consumer, time.Second, false)
  210. require.NoError(t, err)
  211. uri := api.Router.GetRoute(http.MethodGet, api.getSessionsByUserHandler, map[string]string{
  212. "permUsername": u.Username,
  213. })
  214. require.NotEmpty(t, uri)
  215. req := assets.NewJWTAuthentifiedRequest(t, jwtRaw, http.MethodGet, uri, nil)
  216. rec := httptest.NewRecorder()
  217. api.Router.Mux.ServeHTTP(rec, req)
  218. require.Equal(t, 200, rec.Code)
  219. var ss []sdk.AuthSession
  220. require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &ss))
  221. require.Equal(t, 3, len(ss))
  222. assert.Equal(t, localConsumer.ID, ss[0].ConsumerID)
  223. assert.Equal(t, s2.ID, ss[1].ID)
  224. assert.Equal(t, s3.ID, ss[2].ID)
  225. }
  226. func Test_deleteSessionByUserHandler(t *testing.T) {
  227. api, db, _ := newTestAPI(t)
  228. u, jwtRaw := assets.InsertLambdaUser(t, db)
  229. localConsumer, err := authentication.LoadConsumerByTypeAndUserID(context.TODO(), db, sdk.ConsumerLocal, u.ID,
  230. authentication.LoadConsumerOptions.WithAuthentifiedUser)
  231. require.NoError(t, err)
  232. consumer, _, err := builtin.NewConsumer(context.TODO(), db, sdk.RandomString(10), "", localConsumer, nil,
  233. sdk.NewAuthConsumerScopeDetails(sdk.AuthConsumerScopeUser))
  234. require.NoError(t, err)
  235. s2, err := authentication.NewSession(context.TODO(), db, consumer, time.Second, false)
  236. require.NoError(t, err)
  237. ss, err := authentication.LoadSessionsByConsumerIDs(context.TODO(), db, []string{localConsumer.ID, consumer.ID})
  238. require.NoError(t, err)
  239. assert.Equal(t, 2, len(ss))
  240. uri := api.Router.GetRoute(http.MethodDelete, api.deleteSessionByUserHandler, map[string]string{
  241. "permUsername": u.Username,
  242. "permSessionID": s2.ID,
  243. })
  244. require.NotEmpty(t, uri)
  245. req := assets.NewJWTAuthentifiedRequest(t, jwtRaw, http.MethodDelete, uri, nil)
  246. rec := httptest.NewRecorder()
  247. api.Router.Mux.ServeHTTP(rec, req)
  248. require.Equal(t, 200, rec.Code)
  249. ss, err = authentication.LoadSessionsByConsumerIDs(context.TODO(), db, []string{localConsumer.ID, consumer.ID})
  250. require.NoError(t, err)
  251. assert.Equal(t, 1, len(ss))
  252. }