|
|
@ -1,5 +1,5 @@
|
|
|
|
import {Controller} from '../../http/Controller'
|
|
|
|
import {Controller} from '../../http/Controller'
|
|
|
|
import {Injectable} from '../../di'
|
|
|
|
import {Inject, Injectable} from '../../di'
|
|
|
|
import {ResponseObject, Route} from '../../http/routing/Route'
|
|
|
|
import {ResponseObject, Route} from '../../http/routing/Route'
|
|
|
|
import {Request} from '../../http/lifecycle/Request'
|
|
|
|
import {Request} from '../../http/lifecycle/Request'
|
|
|
|
import {Session} from '../../http/session/Session'
|
|
|
|
import {Session} from '../../http/session/Session'
|
|
|
@ -20,6 +20,7 @@ import {redirect} from '../../http/response/RedirectResponseFactory'
|
|
|
|
import {AuthRequiredMiddleware} from '../middleware/AuthRequiredMiddleware'
|
|
|
|
import {AuthRequiredMiddleware} from '../middleware/AuthRequiredMiddleware'
|
|
|
|
import {one} from '../../http/response/api'
|
|
|
|
import {one} from '../../http/response/api'
|
|
|
|
import {AuthenticatableRepository} from '../types'
|
|
|
|
import {AuthenticatableRepository} from '../types'
|
|
|
|
|
|
|
|
import {Logging} from '../../service/Logging'
|
|
|
|
|
|
|
|
|
|
|
|
export enum GrantType {
|
|
|
|
export enum GrantType {
|
|
|
|
Client = 'client_credentials',
|
|
|
|
Client = 'client_credentials',
|
|
|
@ -31,6 +32,9 @@ export const grantTypes: GrantType[] = [GrantType.Client, GrantType.Code, GrantT
|
|
|
|
|
|
|
|
|
|
|
|
@Injectable()
|
|
|
|
@Injectable()
|
|
|
|
export class OAuth2Server extends Controller {
|
|
|
|
export class OAuth2Server extends Controller {
|
|
|
|
|
|
|
|
@Inject()
|
|
|
|
|
|
|
|
protected readonly logging!: Logging
|
|
|
|
|
|
|
|
|
|
|
|
public static routes(): void {
|
|
|
|
public static routes(): void {
|
|
|
|
Route.get('/oauth2/authorize')
|
|
|
|
Route.get('/oauth2/authorize')
|
|
|
|
.alias('@oauth2:authorize')
|
|
|
|
.alias('@oauth2:authorize')
|
|
|
@ -53,8 +57,7 @@ export class OAuth2Server extends Controller {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
issue(request: Request, client: OAuth2Client): Awaitable<ResponseObject> {
|
|
|
|
issue(request: Request, client: OAuth2Client): Awaitable<ResponseObject> {
|
|
|
|
const grant = request.safe('grant_type')
|
|
|
|
const grant = request.safe('grant_type').in(grantTypes)
|
|
|
|
.in(grantTypes)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( grant === GrantType.Client ) {
|
|
|
|
if ( grant === GrantType.Client ) {
|
|
|
|
return this.issueFromClient(request, client)
|
|
|
|
return this.issueFromClient(request, client)
|
|
|
@ -70,6 +73,13 @@ export class OAuth2Server extends Controller {
|
|
|
|
const username = this.request.safe('username').string()
|
|
|
|
const username = this.request.safe('username').string()
|
|
|
|
const password = this.request.safe('password').string()
|
|
|
|
const password = this.request.safe('password').string()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.logging.verbose('Attempting password grant token issue...')
|
|
|
|
|
|
|
|
this.logging.verbose({
|
|
|
|
|
|
|
|
scope,
|
|
|
|
|
|
|
|
username,
|
|
|
|
|
|
|
|
client,
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const userRepo = <AuthenticatableRepository> request.make(AuthenticatableRepository)
|
|
|
|
const userRepo = <AuthenticatableRepository> request.make(AuthenticatableRepository)
|
|
|
|
const user = await userRepo.getByIdentifier(username)
|
|
|
|
const user = await userRepo.getByIdentifier(username)
|
|
|
|
if ( !user || !(await user.validateCredential(password)) ) {
|
|
|
|
if ( !user || !(await user.validateCredential(password)) ) {
|
|
|
@ -121,9 +131,16 @@ export class OAuth2Server extends Controller {
|
|
|
|
throw new HTTPError(HTTPStatus.BAD_REQUEST)
|
|
|
|
throw new HTTPError(HTTPStatus.BAD_REQUEST)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.logging.debug('Client auth parts:')
|
|
|
|
|
|
|
|
this.logging.debug(authParts)
|
|
|
|
|
|
|
|
|
|
|
|
const clientRepo = <ClientRepository> request.make(ClientRepository)
|
|
|
|
const clientRepo = <ClientRepository> request.make(ClientRepository)
|
|
|
|
const [clientId, clientSecret] = authParts
|
|
|
|
const [clientId, clientSecret] = authParts
|
|
|
|
const client = await clientRepo.find(clientId)
|
|
|
|
const client = await clientRepo.find(clientId)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.logging.verbose('Client:')
|
|
|
|
|
|
|
|
this.logging.verbose(client)
|
|
|
|
|
|
|
|
|
|
|
|
if ( !client || client.secret !== clientSecret ) {
|
|
|
|
if ( !client || client.secret !== clientSecret ) {
|
|
|
|
throw new HTTPError(HTTPStatus.UNAUTHORIZED)
|
|
|
|
throw new HTTPError(HTTPStatus.UNAUTHORIZED)
|
|
|
|
}
|
|
|
|
}
|
|
|
|