Skip to content

Commit

Permalink
fix(authentication-service): added idp server controller for login an…
Browse files Browse the repository at this point in the history
…d discovery endpoint

BREAKING CHANGE:
  • Loading branch information
prernagp90 committed Jul 9, 2024
1 parent 1131668 commit 74b87f6
Show file tree
Hide file tree
Showing 14 changed files with 592 additions and 4 deletions.
10 changes: 9 additions & 1 deletion services/authentication-service/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,12 @@ AZURE_AUTH_COOKIE_KEY=

#iv is 12 bit

AZURE_AUTH_COOKIE_IV=
AZURE_AUTH_COOKIE_IV=
#COGNITO
COGNITO_AUTH_CALLBACK_URL=
COGNITO_AUTH_CLIENT_DOMAIN=
COGNITO_AUTH_CLIENT_ID=
COGNITO_AUTH_CLIENT_SECRET=
COGNITO_AUTH_REGION=

API_BASE_URL=
60 changes: 59 additions & 1 deletion services/authentication-service/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"info": {
"title": "Authentication Service",
"version": "1.0.0",
"description": "Authentication microservice",
"description": "Authentication microservice.",
"contact": {}
},
"paths": {
Expand Down Expand Up @@ -929,6 +929,7 @@
"description": "The syntax of the request entity is incorrect"
}
},
"deprecated": true,
"requestBody": {
"content": {
"application/json": {
Expand Down Expand Up @@ -1544,6 +1545,38 @@
"operationId": "LogoutController.cognitoLogout"
}
},
"/connect/auth": {
"post": {
"x-controller-name": "IdentityServerController",
"x-operation-name": "connectAuth",
"tags": [
"IdentityServerController"
],
"description": "POST Call for idp login",
"responses": {
"200": {
"description": "Token Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TokenResponse"
}
}
}
}
},
"requestBody": {
"content": {
"application/x-www-form-urlencoded": {
"schema": {
"$ref": "#/components/schemas/IdpAuthRequest"
}
}
}
},
"operationId": "IdentityServerController.connectAuth"
}
},
"/google/logout": {
"post": {
"x-controller-name": "LogoutController",
Expand Down Expand Up @@ -2470,6 +2503,31 @@
],
"additionalProperties": false
},
"IdpAuthRequest": {
"title": "IdpAuthRequest",
"type": "object",
"description": "This is signature for idp authentication request.",
"properties": {
"client_id": {
"type": "string",
"description": "This property is supposed to be a string and is a required field"
},
"client_secret": {
"type": "string",
"description": "This property is supposed to be a string and is a required field"
},
"auth_method": {
"type": "string",
"description": "This property is supposed to be a string and is a required field"
}
},
"required": [
"client_id",
"client_secret",
"auth_method"
],
"additionalProperties": false
},
"loopback.Count": {
"type": "object",
"title": "loopback.Count",
Expand Down
129 changes: 128 additions & 1 deletion services/authentication-service/openapi.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ headingLevel: 2

> Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.
Authentication microservice
Authentication microservice.

Base URLs:

Expand Down Expand Up @@ -4040,6 +4040,107 @@ To perform this operation, you must be authenticated by means of one of the foll
HTTPBearer
</aside>

<h1 id="authentication-service-identityservercontroller">IdentityServerController</h1>

## IdentityServerController.connectAuth

<a id="opIdIdentityServerController.connectAuth"></a>

> Code samples
```javascript
const inputBody = '{
"client_id": "string",
"client_secret": "string",
"auth_method": "string"
}';
const headers = {
'Content-Type':'application/x-www-form-urlencoded',
'Accept':'application/json'
};

fetch('/connect/auth',
{
method: 'POST',
body: inputBody,
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});

```

```javascript--nodejs
const fetch = require('node-fetch');
const inputBody = {
"client_id": "string",
"client_secret": "string",
"auth_method": "string"
};
const headers = {
'Content-Type':'application/x-www-form-urlencoded',
'Accept':'application/json'
};
fetch('/connect/auth',
{
method: 'POST',
body: JSON.stringify(inputBody),
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
```

`POST /connect/auth`

POST Call for idp login

> Body parameter
```yaml
client_id: string
client_secret: string
auth_method: string

```
<h3 id="identityservercontroller.connectauth-parameters">Parameters</h3>
|Name|In|Type|Required|Description|
|---|---|---|---|---|
|body|body|[IdpAuthRequest](#schemaidpauthrequest)|false|none|
> Example responses
> 200 Response
```json
{
"accessToken": "string",
"refreshToken": "string",
"expires": 0,
"pubnubToken": "string"
}
```

<h3 id="identityservercontroller.connectauth-responses">Responses</h3>

|Status|Meaning|Description|Schema|
|---|---|---|---|
|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|Token Response|[TokenResponse](#schematokenresponse)|

<aside class="success">
This operation does not require authentication
</aside>

# Schemas

<h2 id="tocS_LoginRequest">LoginRequest</h2>
Expand Down Expand Up @@ -4715,6 +4816,32 @@ ActiveUsersFilter
|userIdentity|string|true|none|none|
|userIdentifier|object|true|none|none|

<h2 id="tocS_IdpAuthRequest">IdpAuthRequest</h2>
<!-- backwards compatibility -->
<a id="schemaidpauthrequest"></a>
<a id="schema_IdpAuthRequest"></a>
<a id="tocSidpauthrequest"></a>
<a id="tocsidpauthrequest"></a>

```json
{
"client_id": "string",
"client_secret": "string",
"auth_method": "string"
}

```

IdpAuthRequest

### Properties

|Name|Type|Required|Restrictions|Description|
|---|---|---|---|---|
|client_id|string|true|none|This property is supposed to be a string and is a required field|
|client_secret|string|true|none|This property is supposed to be a string and is a required field|
|auth_method|string|true|none|This property is supposed to be a string and is a required field|

<h2 id="tocS_loopback.Count">loopback.Count</h2>
<!-- backwards compatibility -->
<a id="schemaloopback.count"></a>
Expand Down
3 changes: 2 additions & 1 deletion services/authentication-service/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sourceloop/authentication-service",
"version": "19.1.3",
"version": "19.1.4",
"description": "Authentication microservice.",
"keywords": [
"loopback-extension",
Expand All @@ -25,6 +25,7 @@
}
},
"scripts": {
"start": "node -r source-map-support/register .",
"prebuild": "npm run clean",
"build": "lb-tsc && npm run openapi-spec && npm run apidocs",
"build:watch": "lb-tsc --watch",
Expand Down
2 changes: 2 additions & 0 deletions services/authentication-service/src/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ import {repositories as sequelizeRepositories} from './repositories/sequelize';
import {MySequence} from './sequence';
import {
ActiveUserFilterBuilderService,
IdpLoginService,
LoginActivityHelperService,
LoginHelperService,
OtpService,
Expand Down Expand Up @@ -189,6 +190,7 @@ export class AuthenticationServiceComponent implements Component {
this.application
.bind('services.loginActivityHelperService')
.toClass(LoginActivityHelperService);
this.application.bind('services.IdpLoginService').toClass(IdpLoginService);

//set the userActivity to false by default
this.application
Expand Down
2 changes: 2 additions & 0 deletions services/authentication-service/src/controllers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
CognitoLoginController,
FacebookLoginController,
GoogleLoginController,
IdentityServerController,
InstagramLoginController,
KeycloakLoginController,
LoginController,
Expand Down Expand Up @@ -41,4 +42,5 @@ export const controllers = [
CognitoLoginController,
SamlLoginController,
LoginActivityController,
IdentityServerController,
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import {inject} from '@loopback/core';
import {get, getModelSchemaRef, post, requestBody} from '@loopback/rest';
import {
CONTENT_TYPE,
ErrorCodes,
OPERATION_SECURITY_SPEC,
STATUS_CODE,
X_TS_TYPE,
} from '@sourceloop/core';
import {authenticateClient, STRATEGY} from 'loopback4-authentication';
import {authorize} from 'loopback4-authorization';
import {IdpLoginService} from '../../../services';
import {
IdpAuthMethod,
IdpAuthRequest,
IdpConfiguration,
TokenResponse,
} from '../models';

export class IdentityServerController {
constructor(
@inject('services.IdpLoginService')
private readonly idpLoginHelperService: IdpLoginService,
) {}

@authenticateClient(STRATEGY.CLIENT_PASSWORD)
@authorize({permissions: ['*']})
@post('/connect/auth', {
description: 'POST Call for idp login',
responses: {
[STATUS_CODE.OK]: {
description: 'Token Response',
content: {
[CONTENT_TYPE.JSON]: {
schema: {[X_TS_TYPE]: TokenResponse},
},
},
},
},
})
async connectAuth(
@requestBody({
content: {
[CONTENT_TYPE.FORM_URLENCODED]: {
schema: getModelSchemaRef(IdpAuthRequest),
},
},
})
idpAuthRequest: IdpAuthRequest,
): Promise<void> {
switch (idpAuthRequest?.auth_method) {
case IdpAuthMethod.COGNITO:
await this.idpLoginHelperService.loginViaCognito();
break;
case IdpAuthMethod.GOOGLE:
await this.idpLoginHelperService.loginViaGoogle();
break;
case IdpAuthMethod.SAML:
await this.idpLoginHelperService.loginViaSaml();
break;
case IdpAuthMethod.FACEBOOK:
await this.idpLoginHelperService.loginViaFacebook();
break;
case IdpAuthMethod.APPLE:
await this.idpLoginHelperService.loginViaApple();
break;
case IdpAuthMethod.AZURE:
await this.idpLoginHelperService.loginViaAzure();
break;
case IdpAuthMethod.INSTAGRAM:
await this.idpLoginHelperService.loginViaInstagram();
break;
case IdpAuthMethod.KEYCLOAK:
await this.idpLoginHelperService.loginViaKeycloak();
break;
}
}

@authorize({permissions: ['*']})
@get('/.well-known/openid-configuration', {
security: OPERATION_SECURITY_SPEC,
description: 'To get the openid configuration',
responses: {
[STATUS_CODE.OK]: {
description: 'OpenId Configuration',
content: {
[CONTENT_TYPE.JSON]: IdpConfiguration,
},
},
...ErrorCodes,
},
})
async me(): Promise<void> {
this.idpLoginHelperService.getOpenIdConfiguration();
}
}
Loading

0 comments on commit 74b87f6

Please sign in to comment.