1
0

Authentication with OpenID Connect providers (#713)

Add config docs

Lint

Move provider-related stuff to separate file

Refactor getting auth providers

Fix tests

Fix user tests

Fix openid tests

Add swagger docs

Fix lint

Fix lint issues

Fix checking if the user already exists

Make sure to create a new namespace for new users

Docs

Add tests for openid

Remove unnessecary err check

Consistently return nil users if creating a new user failed

Move sending confirmation email to separate function

Better variable names

Move checks to separate functions

Refactor creating user into seperate file

Fix creating new local users

Test creating new users from different issuers

Generate a random username right away if no preferred username has been given

Add todo

Cache openid providers

Add getting int clientids

Fix migration

Move creating tokens to auth package

Add getting or creating a third party user

Add parsing claims

Add retreiving auth tokens

Add token callback from openid package

Add check for provider key

Add routes

Start adding openid auth handler

Add config for openid auth

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/713
Co-Authored-By: konrad <konrad@kola-entertainments.de>
Co-Committed-By: konrad <konrad@kola-entertainments.de>
This commit is contained in:
konrad
2020-11-21 16:38:58 +00:00
parent f67fe2ce25
commit 2b5c9ae7a8
37 changed files with 1265 additions and 178 deletions

View File

@ -32,6 +32,58 @@ var doc = `{
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {
"/auth/openid/{provider}/callback": {
"post": {
"security": [
{
"JWTKeyAuth": []
}
],
"description": "After a redirect from the OpenID Connect provider to the frontend has been made with the authentication ` + "`" + `code` + "`" + `, this endpoint can be used to obtain a jwt token for that user and thus log them in.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"auth"
],
"summary": "Authenticate a user with OpenID Connect",
"parameters": [
{
"description": "The openid callback",
"name": "callback",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/openid.Callback"
}
},
{
"type": "integer",
"description": "The OpenID Connect provider key as returned by the /info endpoint",
"name": "provider",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/auth.Token"
}
},
"500": {
"description": "Internal error",
"schema": {
"$ref": "#/definitions/models.Message"
}
}
}
}
},
"/backgrounds/unsplash/image/{image}": {
"get": {
"security": [
@ -2426,7 +2478,7 @@ var doc = `{
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/v1.Token"
"$ref": "#/definitions/auth.Token"
}
},
"400": {
@ -3671,7 +3723,7 @@ var doc = `{
"200": {
"description": "The valid jwt auth token.",
"schema": {
"$ref": "#/definitions/v1.Token"
"$ref": "#/definitions/auth.Token"
}
},
"400": {
@ -6240,7 +6292,7 @@ var doc = `{
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/v1.Token"
"$ref": "#/definitions/auth.Token"
}
},
"400": {
@ -6352,6 +6404,14 @@ var doc = `{
}
},
"definitions": {
"auth.Token": {
"type": "object",
"properties": {
"token": {
"type": "string"
}
}
},
"background.Image": {
"type": "object",
"properties": {
@ -7430,6 +7490,34 @@ var doc = `{
}
}
},
"openid.Callback": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"scope": {
"type": "string"
}
}
},
"openid.Provider": {
"type": "object",
"properties": {
"auth_url": {
"type": "string"
},
"client_id": {
"type": "string"
},
"key": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"todoist.Migration": {
"type": "object",
"properties": {
@ -7577,14 +7665,6 @@ var doc = `{
}
}
},
"v1.Token": {
"type": "object",
"properties": {
"token": {
"type": "string"
}
}
},
"v1.UserAvatarProvider": {
"type": "object",
"properties": {
@ -7604,6 +7684,17 @@ var doc = `{
}
}
},
"v1.authInfo": {
"type": "object",
"properties": {
"local": {
"$ref": "#/definitions/v1.localAuthInfo"
},
"openid_connect": {
"$ref": "#/definitions/v1.openIDAuthInfo"
}
}
},
"v1.legalInfo": {
"type": "object",
"properties": {
@ -7615,9 +7706,37 @@ var doc = `{
}
}
},
"v1.localAuthInfo": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
}
}
},
"v1.openIDAuthInfo": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"providers": {
"type": "array",
"items": {
"$ref": "#/definitions/openid.Provider"
}
},
"redirect_url": {
"type": "string"
}
}
},
"v1.vikunjaInfos": {
"type": "object",
"properties": {
"auth": {
"$ref": "#/definitions/v1.authInfo"
},
"available_migrators": {
"type": "array",
"items": {

View File

@ -15,6 +15,58 @@
},
"basePath": "/api/v1",
"paths": {
"/auth/openid/{provider}/callback": {
"post": {
"security": [
{
"JWTKeyAuth": []
}
],
"description": "After a redirect from the OpenID Connect provider to the frontend has been made with the authentication `code`, this endpoint can be used to obtain a jwt token for that user and thus log them in.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"auth"
],
"summary": "Authenticate a user with OpenID Connect",
"parameters": [
{
"description": "The openid callback",
"name": "callback",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/openid.Callback"
}
},
{
"type": "integer",
"description": "The OpenID Connect provider key as returned by the /info endpoint",
"name": "provider",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/auth.Token"
}
},
"500": {
"description": "Internal error",
"schema": {
"$ref": "#/definitions/models.Message"
}
}
}
}
},
"/backgrounds/unsplash/image/{image}": {
"get": {
"security": [
@ -2409,7 +2461,7 @@
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/v1.Token"
"$ref": "#/definitions/auth.Token"
}
},
"400": {
@ -3654,7 +3706,7 @@
"200": {
"description": "The valid jwt auth token.",
"schema": {
"$ref": "#/definitions/v1.Token"
"$ref": "#/definitions/auth.Token"
}
},
"400": {
@ -6223,7 +6275,7 @@
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/v1.Token"
"$ref": "#/definitions/auth.Token"
}
},
"400": {
@ -6335,6 +6387,14 @@
}
},
"definitions": {
"auth.Token": {
"type": "object",
"properties": {
"token": {
"type": "string"
}
}
},
"background.Image": {
"type": "object",
"properties": {
@ -7413,6 +7473,34 @@
}
}
},
"openid.Callback": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"scope": {
"type": "string"
}
}
},
"openid.Provider": {
"type": "object",
"properties": {
"auth_url": {
"type": "string"
},
"client_id": {
"type": "string"
},
"key": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"todoist.Migration": {
"type": "object",
"properties": {
@ -7560,14 +7648,6 @@
}
}
},
"v1.Token": {
"type": "object",
"properties": {
"token": {
"type": "string"
}
}
},
"v1.UserAvatarProvider": {
"type": "object",
"properties": {
@ -7587,6 +7667,17 @@
}
}
},
"v1.authInfo": {
"type": "object",
"properties": {
"local": {
"$ref": "#/definitions/v1.localAuthInfo"
},
"openid_connect": {
"$ref": "#/definitions/v1.openIDAuthInfo"
}
}
},
"v1.legalInfo": {
"type": "object",
"properties": {
@ -7598,9 +7689,37 @@
}
}
},
"v1.localAuthInfo": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
}
}
},
"v1.openIDAuthInfo": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"providers": {
"type": "array",
"items": {
"$ref": "#/definitions/openid.Provider"
}
},
"redirect_url": {
"type": "string"
}
}
},
"v1.vikunjaInfos": {
"type": "object",
"properties": {
"auth": {
"$ref": "#/definitions/v1.authInfo"
},
"available_migrators": {
"type": "array",
"items": {

View File

@ -1,5 +1,10 @@
basePath: /api/v1
definitions:
auth.Token:
properties:
token:
type: string
type: object
background.Image:
properties:
id:
@ -795,6 +800,24 @@ definitions:
minLength: 1
type: string
type: object
openid.Callback:
properties:
code:
type: string
scope:
type: string
type: object
openid.Provider:
properties:
auth_url:
type: string
client_id:
type: string
key:
type: string
name:
type: string
type: object
todoist.Migration:
properties:
code:
@ -899,11 +922,6 @@ definitions:
minLength: 1
type: string
type: object
v1.Token:
properties:
token:
type: string
type: object
v1.UserAvatarProvider:
properties:
avatar_provider:
@ -916,6 +934,13 @@ definitions:
old_password:
type: string
type: object
v1.authInfo:
properties:
local:
$ref: '#/definitions/v1.localAuthInfo'
openid_connect:
$ref: '#/definitions/v1.openIDAuthInfo'
type: object
v1.legalInfo:
properties:
imprint_url:
@ -923,8 +948,26 @@ definitions:
privacy_policy_url:
type: string
type: object
v1.localAuthInfo:
properties:
enabled:
type: boolean
type: object
v1.openIDAuthInfo:
properties:
enabled:
type: boolean
providers:
items:
$ref: '#/definitions/openid.Provider'
type: array
redirect_url:
type: string
type: object
v1.vikunjaInfos:
properties:
auth:
$ref: '#/definitions/v1.authInfo'
available_migrators:
items:
type: string
@ -1021,6 +1064,39 @@ paths:
summary: User Avatar
tags:
- user
/auth/openid/{provider}/callback:
post:
consumes:
- application/json
description: After a redirect from the OpenID Connect provider to the frontend has been made with the authentication `code`, this endpoint can be used to obtain a jwt token for that user and thus log them in.
parameters:
- description: The openid callback
in: body
name: callback
required: true
schema:
$ref: '#/definitions/openid.Callback'
- description: The OpenID Connect provider key as returned by the /info endpoint
in: path
name: provider
required: true
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/auth.Token'
"500":
description: Internal error
schema:
$ref: '#/definitions/models.Message'
security:
- JWTKeyAuth: []
summary: Authenticate a user with OpenID Connect
tags:
- auth
/backgrounds/unsplash/image/{image}:
get:
description: Get an unsplash image. **Returns json on error.**
@ -2558,7 +2634,7 @@ paths:
"200":
description: OK
schema:
$ref: '#/definitions/v1.Token'
$ref: '#/definitions/auth.Token'
"400":
description: Invalid user password model.
schema:
@ -3354,7 +3430,7 @@ paths:
"200":
description: The valid jwt auth token.
schema:
$ref: '#/definitions/v1.Token'
$ref: '#/definitions/auth.Token'
"400":
description: Invalid link share object provided.
schema:
@ -4997,7 +5073,7 @@ paths:
"200":
description: OK
schema:
$ref: '#/definitions/v1.Token'
$ref: '#/definitions/auth.Token'
"400":
description: Only user token are available for renew.
schema: