Logging In

In this tutorial you will learn about how to program using the BUZZ server APIs. At the end of this tutorial, you will know how to access the various BUZZ services and authenticate.

BUZZ Services

There are two main services. The first is the Administration Service (AKA the Provisioning Service). This provides access to your company-wide (tenant) configuration information, user (subscriber) management, conferences, calls, voicemails, as well as authentication. The second is the Instant Messaging (IM) Service. This is also known as the Matrix Service because it uses the Matrix protocol. The IM Service handles rooms and messages. Both of these are accessible through REST interfaces over HTTPS. They both use Basic authentication for logging in, but then they use bearer tokens for subsequent requests.

But before you can access these BUZZ services, you must first create a secure connection with them. Each service has its own API for authentication, and each utilizes a separate bearer token for subsequent requests.

Preparation

The first step is to get a BUZZ account.

After you have created your account, make sure that you have your credentials, which are:

  • Your BUZZ username, which is your email address. In our examples, we will be using “user@example.com” in lieu of this.
  • Your BUZZ password. In our examples we will use “password” as a placeholder.
  • The URL of server you’re connected to (e.g. https://buzz-example.dialogic.com)

You will need to know these to complete this tutorial. The Matrix IM Service credentials are not provided to you, and will be retrieved programmatically as we will soon cover.

Logging into the BUZZ Administration Service

NOTE: This article covers logging in as a subscriber. To log in as an administrator for a company or a tenant, refer to the Company Administration tutorial.

Let’s start with a bit of programming. Write a function that takes the username, password and server URL as input, and will return the response as a JSON map which we will need later.

Logging in

import requests
import json

def buzz_login(user, pass, server):
    url = server + "/api/subscriberSecurityLogin"
    response = requests.get(url, auth=(username, password))
    return json.loads(response)

response = buzz_login("user@example.com", "password", "https://buzz-example.dialogic.com")
interface BuzzApi {
    @GET("/api/subscriberSecurityLogin")
    fun subscriberSecurityLogin(@Header("Authorization") authHeader: String)
    :Call
}

class BuzzApiController {
    private val buzzApi: BuzzApi

    init {
        val retrofit = Retrofit.Builder()
            .baseUrl(server)
            .addConverterFactory(MoshiConverterFactory.create())
            .build()
        buzzApi = retrofit.create(BuzzApi::class.java)
    }

    fun login(auth: String): Call {
        return buzzApi.subscriberSecurityLogin(auth)
    }
}


private fun buzzLogin(user: String, pass: String) {
    val base = "$user:$pass"
    val authHeader = "Basic ${Base64.getEncoder().encodeToString(base.toByteArray())}"

    val callResponse = buzzApi.login(authHeader)
    val response = callResponse.execute()
    buzzLoginSuccess(response);
}
function buzz_login(user, pass, server, callback) {
    if (!server.endsWith("/")) {
        server += "/";
    }
    $.ajax({
        url: server + "api/subscriberSecurityLogin",
        headers: {
            "Authorization": "Basic " + btoa(user + ":" + pass)
        },
        method: "GET",
        success: function(result) {
            buzz_login_success(result, callback);
        },
        error: function(xhr, status, errorThrown) {
            console.log("Error logging into BUZZ. " + xhr.status + " " + xhr.text + " " + errorThrown);
            alert("Cannot log into BUZZ. Please check your credentials and server address.");
        }
    });
}

buzz_login("user@example.com", "password", "https://buzz-cc-test.dialogic.com", function() { console.log("success!"); });
@Autowired
private RestTemplate rest;

@Autowired
private ObjectMapper mapper;

public String buzzLogin(String username, String password, String server) {
    String plainCreds = username + ":" + password;
    byte[] plainCredsBytes = plainCreds.getBytes();
    byte[] base64CredsBytes = Base64.getEncoder().encode(plainCredsBytes);
    String base64Creds = new String(base64CredsBytes);

    HttpHeaders headers = new HttpHeaders();
    headers.add("Authorization", "Basic " + base64Creds);

    HttpEntity request<String> = new HttpEntity<>(headers);

    if (!server.endsWith("/")) {
        server += "/";
    }

    try {
        ResponseEntity<String> response = rest.exchange(server + "api/subscriberSecurityLogin", HttpMethod.GET, request, String.class);
        if (response.getStatusCode().is2xxSuccessful()) {
            JsonNode loginResponse = mapper.readValue(response.getBody(), JsonNode.class);
            return loginSuccessful(loginResponse);
        }
        return "Error logging into BUZZ server: " + response.toString();
    } catch (HttpClientErrorException e) {
        return "Error logging into BUZZ server: " + e.getStatusCode().toString();
    } catch (Exception e2) {
        return "Problem logging into BUZZ server: " + e2.toString();
    }
} 
var server = ""

func buzzLogin(username: String, password: String, server: String, callback: @escaping () -> Void) {
    self.server = server
    if !self.server.hasSuffix("/") {
        self.server += "/";
    }

    let loginString = String(format: "%@:%@", username, password)
    let loginData = loginString.data(using: String.Encoding.utf8)!
    let base64LoginString = loginData.base64EncodedString()

    // create the request
    let url = URL(string: self.server + "api/subscriberSecurityLogin")!
    let session = URLSession.shared
    var request = URLRequest(url: url)
    request.httpMethod = "GET"
    request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
        guard error == nil else {
            print(error)
            return
        }
        guard let data = data else {
            return
        }

        do {
            if let result = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
                self.loginSuccessful(response: result, callback: callback)
            }
        } catch let error {
            print(error.localizedDescription)
        }
    })
    task.resume()
}

 

The response from the Buzz login call will contain a JSON object with many values. We will only need four of these values. One is the “access_token” which we need for subsequent access to the Administration Service. Another one is the “matrixUrl” which is the address of the IM Service that we will need later. The last two are needed to log into the matrix server: “username” and “authenticationPwd” as we’ll see shortly.

matrix_username = response["username"].text)
matrix_password = response["authenticationPwd"]
matrix_server = response["matrixUrl"]
token = response["access_token"]
private fun buzzLoginSuccess(response: SubscriberSecurityLogin) {
    val matrixUsername = response.body().username.toString()
    val matrixPassword = response.body().authenticationPwd.toString()
    matrixServer = response.body().matrixUrl.toString()
    matrixLogin(matrixUsername, matrixPassword)
}
var token;
var matrix_server;

function buzz_login_success(response, callback) {
    token = response.access_token;

    matrix_server = response.matrixUrl;
    if (!matrix_server.endsWith("/")) {
        matrix_server += "/";
    }
    var matrix_username = response.username;
    var matrix_password = response.authenticationPwd;
    matrix_login(matrix_username, matrix_password, callback);
}
private String token;
private String matrixServer;

private String loginSuccess(JsonNode response) {
    this.token = response.get("bearerToken").asText();
    this.matrixServer = response.get("matrixUrl").asText();
    if (!matrixServer.endsWith("/")) {
        matrixServer += "/";
    }
    String matrixUsername = response.get("username").asText();
    String matrixPassword = response.get("authenticationPwd").asText();
    return matrixLogin(matrixUsername, matrixPassword);
}
var matrixServer: String?
var token: String?

func loginSuccessful(response: [String: Any], callback: @escaping () -> Void) {
    token = (response["bearerToken"] as! String)
    //matrixServer = "https://buzz-im-test.dialogic.com/";

    matrixServer = (response["matrixUrl"] as! String)
    if !matrixServer!.hasSuffix("/") {
        matrixServer! += "/";
    }
    let matrixUsername = response["username"] as! String
    let matrixPassword = response["authenticationPwd"] as! String

    sendToken() //Register this device for push notifications
    matrixLogin(username: matrixUsername, password: matrixPassword, callback: callback)
}

Next, if you need to access the IM Service, you must also log in with the Matrix protocol. Write a function that will do that:

def matrix_login(user, pass):

    url = self.matrix_server + "/_matrix/client/r0/login"
        data = '''{
            "password": "%s",
            "type": "m.login.password",
            "user": "%s"
        }'''

        response = requests.post(url, (data % (pass, user)), auth=(user, pass))
        return json.loads(response)

matrix_response = matrix_login(matrix_username, matrix_password)
private fun matrixLogin(user: String, pass: String) {
    val base = "$user:$pass"
    val authHeader = "Basic ${Base64.getEncoder().encodeToString(base.toByteArray())}"

    val body = MatrixLoginBody(pass, "m.login.password", user)
    val callResponse = matrixApi.login(authHeader, body)
    val response = callResponse.execute()
    matrix_login_success(response)
}
function matrix_login(matrix_username, matrix_password, callback) {
    $.ajax({
        url: matrix_server + "_matrix/client/r0/login",
        method: "POST",
        data: JSON.stringify({
            "user": matrix_username,
            "password": matrix_password,
            "type": "m.login.password"
        }),
        success: function(result) {
            matrix_login_success(result, callback);
        },
        error: function(xhr, status, errorThrown) {
            console.log("Error logging into Matrix. " + xhr.status + " " + xhr.text + " " + errorThrown);
        }
    });
}
private String matrixLogin(String matrixUsername, String matrixPassword) {
    String plainCreds = matrixUsername + ":" + matrixPassword;
    byte[] plainCredsBytes = plainCreds.getBytes();
    byte[] base64CredsBytes = Base64.getEncoder().encode(plainCredsBytes);
    String base64Creds = new String(base64CredsBytes);

    HttpHeaders headers = new HttpHeaders();
    headers.add("Authorization", "Basic " + base64Creds);
    String loginBody = "{\n" +
            "  \"password\": \"" + matrixPassword + "\",\n" +
            "  \"type\": \"m.buzzLogin.password\",\n" +
            "  \"user\": \"" + matrixUsername + "\"\n" +
            "}";
    HttpEntity<String> request = new HttpEntity<String>(loginBody, headers);

    ResponseEntity<String> response = rest.exchange(matrixServer + "_matrix/client/r0/buzzLogin", HttpMethod.POST, request, String.class);
    try {
        if (response.getStatusCode().is2xxSuccessful()) {
            JsonNode loginResponse = mapper.readValue(response.getBody(), JsonNode.class);

            return matrixLoginSuccess(loginResponse); //Success
        }
        return "Error logging into IM server: " + response.toString();
    } catch (HttpClientErrorException e) {
        return "Error logging into IM server: " + e.getStatusCode().toString();
    } catch (Exception e2) {
        return "Problem logging into IM server: " + e2.toString();
    }
}
func matrixLogin(username: String, password: String, callback:@escaping () -> Void) {
    let loginBody = ["user": username, "password": password, "type": "m.login.password"]
    let url = URL(string: matrixServer! + "_matrix/client/r0/login")!
    let session = URLSession.shared
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    do {
        request.httpBody = try JSONSerialization.data(withJSONObject: loginBody, options: .prettyPrinted)
    } catch {
        print(error.localizedDescription)
        return
    }
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
        guard error == nil else {
            print(error)
            return
        }
        guard let data = data else {
            return
        }
        do {
            if let result = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
                self.matrixLoginSuccess(response: result, callback: callback)
            }
        } catch let error {
            print(error.localizedDescription)
        }
    })
    task.resume()
}

 

The matrix login response will return a bearer token that can be used for the IM Service authentication going forward.

matrix_token = matrix_response["access_token"].text
private fun matrixLoginSuccess(response) {
       matrixToken = response.body().access_token.toString()
}
var im_token;

function matrix_login_success(result, callback) {
    im_token = result.access_token;
    callback();
}
private String imToken;
private String matrixLoginSuccess(JsonNode response) {
    JsonNode accessToken = response.get("access_token");
    this.imToken = accessToken.asText();
    return null; //Success
}
var imToken: String?

func matrixLoginSuccess(response: [String: Any], callback: @escaping () -> Void) {
    imToken = (response["access_token"] as! String)
    callback()
}