Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add API Key Based Authentication for Ballerina Twilio Connector #238

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,12 @@ This repository only contains the source code for the package.

> **Note**: Ensure that the Docker daemon is running before executing any tests.

4. Export Github Personal access token with read package permissions as follows,
SachinAkash01 marked this conversation as resolved.
Show resolved Hide resolved
```
export packageUser=<Username>
export packagePAT=<Personal access token>
```

### Build options

Execute the commands below to build from the source.
Expand Down
4 changes: 2 additions & 2 deletions ballerina/Ballerina.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
distribution = "2201.8.0"
SachinAkash01 marked this conversation as resolved.
Show resolved Hide resolved
org = "ballerinax"
name = "twilio"
version = "4.0.1"
SachinAkash01 marked this conversation as resolved.
Show resolved Hide resolved
version = "4.0.2"
authors = ["Ballerina"]
repository = "https://github.com/ballerina-platform/module-ballerinax-twilio"
keywords = ["Communication/Call & SMS", "Cost/Paid"]
icon = "icon.png"
license = ["Apache-2.0"]

[build-options]
observabilityIncluded = false
observabilityIncluded = true
34 changes: 18 additions & 16 deletions ballerina/Dependencies.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@

[ballerina]
dependencies-toml-version = "2"
distribution-version = "2201.8.4"
distribution-version = "2201.10.1"

[[package]]
org = "ballerina"
name = "auth"
version = "2.10.0"
version = "2.12.0"
dependencies = [
{org = "ballerina", name = "crypto"},
{org = "ballerina", name = "jballerina.java"},
Expand All @@ -22,7 +22,7 @@ dependencies = [
[[package]]
org = "ballerina"
name = "cache"
version = "3.7.1"
version = "3.8.0"
dependencies = [
{org = "ballerina", name = "constraint"},
{org = "ballerina", name = "jballerina.java"},
Expand All @@ -44,7 +44,7 @@ modules = [
[[package]]
org = "ballerina"
name = "crypto"
version = "2.5.0"
version = "2.7.2"
dependencies = [
{org = "ballerina", name = "jballerina.java"},
{org = "ballerina", name = "time"}
Expand All @@ -53,7 +53,7 @@ dependencies = [
[[package]]
org = "ballerina"
name = "file"
version = "1.9.0"
version = "1.10.0"
dependencies = [
{org = "ballerina", name = "io"},
{org = "ballerina", name = "jballerina.java"},
Expand All @@ -64,7 +64,7 @@ dependencies = [
[[package]]
org = "ballerina"
name = "http"
version = "2.10.7"
version = "2.12.2"
dependencies = [
{org = "ballerina", name = "auth"},
{org = "ballerina", name = "cache"},
Expand Down Expand Up @@ -96,7 +96,7 @@ modules = [
[[package]]
org = "ballerina"
name = "io"
version = "1.6.0"
version = "1.6.1"
dependencies = [
{org = "ballerina", name = "jballerina.java"},
{org = "ballerina", name = "lang.value"}
Expand All @@ -110,10 +110,11 @@ version = "0.0.0"
[[package]]
org = "ballerina"
name = "jwt"
version = "2.10.0"
version = "2.13.0"
dependencies = [
{org = "ballerina", name = "cache"},
{org = "ballerina", name = "crypto"},
{org = "ballerina", name = "io"},
{org = "ballerina", name = "jballerina.java"},
{org = "ballerina", name = "lang.int"},
{org = "ballerina", name = "lang.string"},
Expand Down Expand Up @@ -207,7 +208,7 @@ dependencies = [
[[package]]
org = "ballerina"
name = "log"
version = "2.9.0"
version = "2.10.0"
dependencies = [
{org = "ballerina", name = "io"},
{org = "ballerina", name = "jballerina.java"},
Expand All @@ -221,17 +222,18 @@ modules = [
[[package]]
org = "ballerina"
name = "mime"
version = "2.9.0"
version = "2.10.1"
dependencies = [
{org = "ballerina", name = "io"},
{org = "ballerina", name = "jballerina.java"},
{org = "ballerina", name = "lang.int"}
{org = "ballerina", name = "lang.int"},
{org = "ballerina", name = "log"}
]

[[package]]
org = "ballerina"
name = "oauth2"
version = "2.10.0"
version = "2.12.0"
dependencies = [
{org = "ballerina", name = "cache"},
{org = "ballerina", name = "crypto"},
Expand All @@ -244,7 +246,7 @@ dependencies = [
[[package]]
org = "ballerina"
name = "observe"
version = "1.2.2"
version = "1.3.0"
dependencies = [
{org = "ballerina", name = "jballerina.java"}
]
Expand Down Expand Up @@ -277,6 +279,7 @@ version = "0.0.0"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "jballerina.java"},
{org = "ballerina", name = "lang.array"},
{org = "ballerina", name = "lang.error"}
]
modules = [
Expand All @@ -286,7 +289,7 @@ modules = [
[[package]]
org = "ballerina"
name = "time"
version = "2.4.0"
version = "2.5.0"
dependencies = [
{org = "ballerina", name = "jballerina.java"}
]
Expand Down Expand Up @@ -324,8 +327,7 @@ dependencies = [
{org = "ballerina", name = "log"},
{org = "ballerina", name = "os"},
{org = "ballerina", name = "test"},
{org = "ballerina", name = "url"},
{org = "ballerinai", name = "observe"}
{org = "ballerina", name = "url"}
]
modules = [
{org = "ballerinax", packageName = "twilio", moduleName = "twilio"},
Expand Down
36 changes: 34 additions & 2 deletions ballerina/client.bal
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ public isolated client class Client {
# + serviceUrl - URL of the target service
# + return - An error if connector initialization failed
public isolated function init(ConnectionConfig config, string serviceUrl = "https://api.twilio.com") returns error? {
self.accountSid = config.auth.username;
self.generatedClient = check new (config, serviceUrl);
self.accountSid = config.auth.accountSid;
oas:ConnectionConfig oasConnectionConfig = getOasConnectionConfig(config);
self.generatedClient = check new (oasConnectionConfig, serviceUrl);
}
# Retrieves a collection of Accounts belonging to the account used to make the request
#
Expand Down Expand Up @@ -2097,3 +2098,34 @@ public isolated client class Client {
return self.generatedClient->deleteUserDefinedMessageSubscription(accountSid ?: self.accountSid, callSid, sid);
}
}

isolated function getOasConnectionConfig(ConnectionConfig config) returns oas:ConnectionConfig => {
auth: getAuthConfig(config.auth),
httpVersion: config.httpVersion,
http1Settings: config.http1Settings,
http2Settings: config.http2Settings,
timeout: config.timeout,
forwarded: config.forwarded,
poolConfig: config.poolConfig,
cache: config.cache,
circuitBreaker: config.circuitBreaker,
compression: config.compression,
retryConfig: config.retryConfig,
responseLimits: config.responseLimits,
secureSocket: config.secureSocket,
proxy: config.proxy,
validation: config.validation
};

isolated function getAuthConfig(AuthTokenConfig|ApiKeyConfig config) returns http:CredentialsConfig {
if config is AuthTokenConfig {
return {
username: config.accountSid,
password: config.authToken
};
}
return {
username: config.apiKey,
password: config.apiSecret
};
}
4 changes: 4 additions & 0 deletions ballerina/tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ accountSid="<your-twilio-account-sid>"
authToken="<your-twilio-auth-token>"
toPhoneNumber="<your-test-phone-number>"
fromPhoneNumber="<your-twilio-phone-number>"
apiKey="<your-twilio-api-key>"
apiSecret="<your-twilio-api-secret>"
```

#### Using Environment Variables
Expand All @@ -68,6 +70,8 @@ export ACCOUNT_SID="<your-twilio-account-sid>"
export AUTH_TOKEN="<your-twilio-auth-token>"
export TO_PHONE="<your-test-phone-number>"
export TWILIO_PHONE="<your-twilio-phone-number>"
export API_KEY="<your-twilio-api-key>"
export API_SECRET="<your-twilio-api-secret>"
```

Then, run the following command to run the tests:
Expand Down
6 changes: 4 additions & 2 deletions ballerina/tests/tests.bal
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ configurable string accountSid = isTestOnLiveServer ? os:getEnv("ACCOUNT_SID"):
configurable string authToken = isTestOnLiveServer ? os:getEnv("AUTH_TOKEN"): "AU12345678901234567890123456789012";
configurable string toPhoneNumber = isTestOnLiveServer ? os:getEnv("TO_PHONE"): "+011234567890";
configurable string fromPhoneNumber = isTestOnLiveServer ? os:getEnv("TWILIO_PHONE"): "+098765432101";
configurable string apiKey = isTestOnLiveServer ? os:getEnv("API_KEY"): "SCdegjk35502ga02bbr5311h909a02t3x5";
ayeshLK marked this conversation as resolved.
Show resolved Hide resolved
configurable string apiSecret = isTestOnLiveServer ? os:getEnv("API_SECRET"): "c4N1odgh7szhjRNSQz6ve4iCkqgH5WBx";

Client twilio = test:mock(Client);

Expand Down Expand Up @@ -73,10 +75,10 @@ CreateMessageRequest msgReq = {
function initializeClientsForTwilioServer () returns error? {
if (isTestOnLiveServer) {
log:printInfo("Running tests on actual server");
twilio = check new ({auth: {username: accountSid, password: authToken}});
twilio = check new ({auth: {accountSid: accountSid, authToken: authToken}});
} else {
log:printInfo("Running tests on mock server");
twilio = check new ({auth: {username: accountSid, password: authToken}}, serviceUrl = "http://localhost:9090/");
twilio = check new ({auth: {accountSid: accountSid, authToken: authToken}}, serviceUrl = "http://localhost:9090/");
}
}
@test:Config {
Expand Down
23 changes: 22 additions & 1 deletion ballerina/types.bal
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import ballerina/http;
@display {label: "Connection Config"}
public type ConnectionConfig record {|
# Configurations related to client authentication
http:CredentialsConfig auth;
AuthTokenConfig | ApiKeyConfig auth;
SachinAkash01 marked this conversation as resolved.
Show resolved Hide resolved
# The HTTP version understood by the client
http:HttpVersion httpVersion = http:HTTP_2_0;
# Configurations related to HTTP/1.x protocol
Expand Down Expand Up @@ -55,6 +55,27 @@ public type ConnectionConfig record {|
boolean validation = true;
|};

# Twilio Auth token Based Authentication
SachinAkash01 marked this conversation as resolved.
Show resolved Hide resolved
#
# + accountSid - Twilio account SID
# + authToken - Twilio authentication token of the account
public type AuthTokenConfig record {|
SachinAkash01 marked this conversation as resolved.
Show resolved Hide resolved
string accountSid;
string authToken;
|};

# Twilio API Key Based Authentication
SachinAkash01 marked this conversation as resolved.
Show resolved Hide resolved
#
# + apiKey - Twilio API key SID
# + apiSecret - Twilio API key Secret
# + accountSid - Twilio account SID
@display{label: "API Key Based Connection Config"}
SachinAkash01 marked this conversation as resolved.
Show resolved Hide resolved
public type ApiKeyConfig record {|
string apiKey;
string apiSecret;
string accountSid;
|};

# Provides settings related to HTTP/1.x protocol.
public type ClientHttp1Settings record {|
# Specifies whether to reuse a connection for multiple requests
Expand Down
Loading