Skip to content

Instantly share code, notes, and snippets.

@morteza-mori
Forked from mxamin/ibsng_api_intro.md
Created July 23, 2019 10:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save morteza-mori/506ad7f1cd3336f6a5ffd2f06d1340cc to your computer and use it in GitHub Desktop.
Save morteza-mori/506ad7f1cd3336f6a5ffd2f06d1340cc to your computer and use it in GitHub Desktop.

Introduction

The following document describes how we can communicate with IBSng API through JSONRPC.

Note that IBSng is capable of handling requests in XML format as well, which in this case the IBSng XMLRPC server is responsible of processing/answering the requests but it is not the purpose of this document

All the samples of this document are implemented with curl command to make it independent of any programming languages.

Each operation in IBSng can be done by calling its appropriate method. The methods are categorized in different sections called handler. All the handlers/methods are described in here. So if we want to refer to a specific method it has the following form: <handler_name>.<method_name>.

For example, if you decide to send the Recharge Users request, you must find its handler and of course its method. In this case, the method is rechargeUsers and its handler is user. So in your request, you must refer to it as method="user.rechargeUsers".

The default port of IBSng JSONRPC server is 1237. In following samples we already have an installed IBSng on a system with IP address 192.168.1.4 with port 1237, which JSONRPC server is listening on. Also, we have provided with a username: system, password: sys which has the required permission. We are sending our requests from IP address: 192.168.1.101.

Authentication

Before you decide to send any request to IBSng, first you must authenticate youself. This can be done by calling the login.login method of IBSng:

$ curl -H "Content-Type: application/json" \
       -H "Accept: application/json" \
       -H "Accept-Charset: utf-8" \
       -H "Cache-Control: no-cache" \
       -X POST \
       -d '{"params": {"auth_remoteaddr": "192.168.1.101", "auth_type": "ANONYMOUS", "auth_name": "ANONYMOUS", "auth_pass": "ANONYMOUS", "login_auth_name": "system", "login_auth_pass": "sys", "create_session": true, "login_auth_type": "ADMIN"}, "method": "login.login"}' \
       http://192.168.1.104:1237/

Output:

{"id": null, "result": "cm9vn23otwr5", "error": null}

As you can see in response, IBSng provided us with a session id: cm9vn23otwr5 (the value in result field) which you must include in from now on in every request you send, otherwise, your request will be rejected. In coming examples, we use cm9vn23otwr5 as session id.

All JSONRPC responses have only three fields: id, result and error.

If an error occurs in processing the request, IBSng will tell us what/where the error is by filling out the error field. null value means NO error.

If you're authenticating as a simple user you must change the login_auth_type to NORMAL_USER. For more information look at the handlers document.

Create and Configure New User

Suppose we have been provided with a username called sample-user and corresponded password pasw00rd and we want to register it if it hasn't been registered already and of course, activate it to be able to login and gets online.

Before we continue with our example we suppose that we have already created a group named sample-group with appropriate configurations (Group Credit, Recharge Credit, Charge, etc. For more info check here).

Create New User

As described above we want to create a new user with username sample-user and password passw00rd and assign it to an already created group named sample-group.

To do so first we must make sure that such user has't been already created. We can do that by calling user.getUserInfo method. The only parameter we have to provide is, of course, our username sample-user; if you're sure that such username doesn't exists, you can skip this step:

  • normal_username: username of the user which we want to get its info (here the normal username is: sample-user)
$ curl -H "Content-Type: application/json" \
       -H "Accept: application/json" \
       -H "Accept-Charset: utf-8" \
       -H "Cache-Control: no-cache" \
       -X POST \
       -d '{"params": {"auth_remoteaddr": "192.168.1.101", "auth_type": "ADMIN", "auth_name": "system", "auth_session": "cm9vn23otwr5", "normal_username": "sample-user"}, "method": "user.getUserInfo"}' \
       http://192.168.1.104:1237/

Output:

{"id": null, "result": null, "error": "NORMAL_USERNAME_DOESNT_EXISTS|User with Internet username sample-user does not exists"}

As you can see we have no such user registered already, so the next step is to create it.

If such user has already been registered you can fetch the User ID of the created user from the returned response and skip the rest of this section.

Now that we are sure we have no such user with username sample-user we have to create it. The method we have to call is user.addNewUsers with the following parameters:

  • count: how many users you want to create (we only need to create one user, so the value of this parameter is 1)
  • isp_name: name of ISP which new user(s) belong to (the concept of ISP has been described here, but for the sake of simplicity of this document we use default ISP name Main)
  • group_name: which group new user(s) belong to (according to our example parameters the value of this parameter is sample-group)
  • credit: initial credit of new user(s) (for now we assign 0 value to this parameter)
  • credit_comment: short description about the initial credit we assigned to the new user(s) (we keep it empty "")
$ curl -H "Content-Type: application/json" \
       -H "Accept: application/json" \
       -H "Accept-Charset: utf-8" \
       -H "Cache-Control: no-cache" \
       -X POST \
       -d '{"params": {"auth_remoteaddr": "192.168.1.101", "auth_type": "ADMIN", "auth_name": "system", "auth_session": "cm9vn23otwr5", "count": 1, "isp_name": "Main", "group_name": "sample-group", "credit": 0, "credit_comment": ""}, "method": "user.addNewUsers"}' \
       http://192.168.1.104:1237/

Output:

{"id": null, "result": [12], "error": null}

As you can see in the response message, IBSng created only one user with the user ID of 12 (look at the value of result field).

You may have noticed that the created user has no username/password for authentication purposes if we decide to set this parameter we have to call another method named user.updateUserAttrs and assign new values to normal_username and normal_password attributes. To do so, we need the created user id which returned to us in the last request: 12. The parameters of this method are as follow:

  • user_id: the ID of the already created user (here the ID is: 12)
  • normal_username: user's username (here the username is: sample-user)
  • normal_password: user's password (here the password is: passw00rd)
$ curl -H "Content-Type: application/json" \
       -H "Accept: application/json" \
       -H "Accept-Charset: utf-8" \
       -H "Cache-Control: no-cache" \
       -X POST \
       -d '{"params": {"auth_remoteaddr": "192.168.1.101", "auth_type": "ADMIN", "auth_name": "system", "auth_session": "cm9vn23otwr5", "user_id": "12", "attrs": {"normal_user_spec": {"normal_username": "sample-user", "normal_password": "passw00rd"}}, "to_del_attrs": []}, "method": "user.updateUserAttrs"}' \
       http://192.168.1.104:1237/

Output:

{"id": null, "result": "", "error": null}

In response, you will receive nothing which is a good sign that your request executed successfully (of course you must check that the value of the error field is null).

Now if you call user.getUserInfo method again you will be represented with a different response, which now includes all the information of created user:

$ curl -H "Content-Type: application/json" \
       -H "Accept: application/json" \
       -H "Accept-Charset: utf-8" \
       -H "Cache-Control: no-cache" \
       -X POST \
       -d '{"params": {"auth_remoteaddr": "192.168.1.101", "auth_type": "ADMIN", "auth_name": "system", "auth_session": "cm9vn23otwr5", "normal_username": "sample-user"}, "method": "user.getUserInfo"}' \
       http://192.168.1.104:1237/

Output:

{
  "id": null,
  "result": {
    "12": {
      "online_status": false,
      "basic_info": {
        "status": "Package",
        "group_name": "sample-group",
        "isp_name": "Main",
        "creation_date": "2018-10-14 10:19:00",
        "recharge_deposit": 0,
        "user_id": 12,
        "nearest_exp_date": "",
        "credit": 0,
        "deposit": 0,
        "isp_id": 0,
        "group_id": 2
      },
      "user_repr": "sample-user",
      "attrs": {
        "normal_password": "passw00rd",
        "normal_username": "sample-user"
      },
      "voip_onlines": [],
      "internet_onlines": []
    }
  },
  "error": null
}

Change User's Credit

In order to change user's credit, we need to call user.changeCreditExtended method. Suppose we want to add 100 credit to user's current credit. To do so we need the following parameter to included them in our request:

  • user_id: the ID of existing user we want to change its credit (here the ID is: 12)
  • credit: the amount of credit we want to change (here the credit is: 100)
  • change_type: this method supports three type of change ADD, SET and MULTIPLY; for more information click here (here the change type is: ADD)
  • credit_comment: short description about the credit we are going to change for the user (we keep it empty "")

Note: the value of user_id must be a string, if we need to change the credit of multiple users in one request, we can do it by in including multiple user ids in user_id parameter separated by ,; i.e. user_id: 12,13,15.

$ curl -H "Content-Type: application/json" \
       -H "Accept: application/json" \
       -H "Accept-Charset: utf-8" \
       -H "Cache-Control: no-cache" \
       -X POST \
       -d '{"params": {"auth_remoteaddr": "192.168.1.101", "auth_type": "ADMIN", "auth_name": "system", "auth_session": "cm9vn23otwr5", "user_id": "12", "credit": 100, "change_type": "ADD", "credit_comment": ""}, "method": "user.changeCreditExtended"}' \
       http://192.168.1.104:1237/

Output:

{"id": null, "result": [87], "error": null}

The returned value of this request is a list of numbers which refers to corresponded change credit transaction record, it can be used later for reporting purposes.

Now if you can user.getUserInfo method again (as described above), you see that user's credit increased by 100 (last value of user's credit was 0):

{
  "id": null,
  "result": {
    "12": {
      "online_status": false,
      "basic_info": {
        "status": "Recharged",
        "group_name": "sample-group",
        "isp_name": "Main",
        "creation_date": "2018-10-14 10:19:00",
        "recharge_deposit": 0,
        "user_id": 12,
        "nearest_exp_date": "",
        "credit": 100,
        "deposit": 0,
        "isp_id": 0,
        "group_id": 2
      },
      "user_repr": "sample-user",
      "attrs": {
        "normal_password": "passw00rd",
        "normal_username": "sample-user"
      },
      "voip_onlines": [],
      "internet_onlines": []
    }
  },
  "error": null
}

Extend User's Current Service (Renew)

If the user intends to use its current service after it has been expired (extend the service which it has been using already), we only need to call user.renewUsers the method with the following parameters; you can read more about this feature here:

  • user_id: ID of user we want to extend its current service or as we call it, renew (here the ID is: 12)
  • comment: short description about the renew action we are going to execute (we keep it empty "")

Note: the value of user_id must be a string, if we need to renew multiple users in one request, we can do it by in including multiple user ids in user_id parameter separated by ,; i.e. user_id: 12,13,15.

$ curl -H "Content-Type: application/json" \
       -H "Accept: application/json" \
       -H "Accept-Charset: utf-8" \
       -H "Cache-Control: no-cache" \
       -X POST \
       -d '{"params": {"auth_remoteaddr": "192.168.1.101", "auth_type": "ADMIN", "auth_name": "system", "auth_session": "cm9vn23otwr5", "user_id": "12", "comment": ""}, "method": "user.renewUsers"}' \
       http://192.168.1.104:1237/

Output:

{"id": null, "result": true, "error": null}

Of course, the true value in the result is a good sign which means renew executed successfully.

Get User's Info

We have used this method before but it worth mention it again. User's info can be fetched by calling user.getUserInfo method. Suppose we want to fetch information of a user with username sample-user.

Let's call user.getUserInfo method and see what we got (the parameter of this function have been described in previous sections).

$ curl -H "Content-Type: application/json" \
       -H "Accept: application/json" \
       -H "Accept-Charset: utf-8" \
       -H "Cache-Control: no-cache" \
       -X POST \
       -d '{"params": {"auth_remoteaddr": "192.168.1.101", "auth_type": "ADMIN", "auth_name": "system", "auth_session": "cm9vn23otwr5", "normal_username": "sample-user"}, "method": "user.getUserInfo"}' \
       http://192.168.1.104:1237/

Output:

{
  "id": null,
  "result": {
    "12": {
      "online_status": true,
      "basic_info": {
        "status": "Package",
        "group_name": "sample-group",
        "isp_name": "Main",
        "creation_date": "2018-10-14 10:19:00",
        "recharge_deposit": 0,
        "user_id": 12,
        "nearest_exp_date": "",
        "credit": 999.991777420044,
        "deposit": 0,
        "isp_id": 0,
        "group_id": 2
      },
      "user_repr": "sample-user",
      "attrs": {
        "normal_password": "passw00rd",
        "real_first_login": "2018-10-14 11:19:22",
        "normal_username": "sample-user",
        "charge_rule_usage": [
          [
            6,
            "charge2",
            "0.00822257995605",
            "248",
            "10962"
          ]
        ],
        "first_login": "2018-10-14 11:29:32"
      },
      "voip_onlines": [],
      "internet_onlines": [
        [
          "172.17.109.146",
          "ras1",
          "15728641",
          "2018-10-14 11:19:26",
          "192.168.1.20",
          0,
          "0",
          "",
          "",
          "1468",
          "7154",
          "24",
          "119",
          "Master",
          "",
          "",
          "",
          "",
          true
        ]
      ]
    }
  },
  "error": null
}

Some useful information from the received response:

  • user_id: ID of the user
  • group_id: ID of the group which user belongs to
  • group_name: name of the group which user belongs to
  • creation_date: date and time of user's creation
  • nearest_exp_date: date and time of user's account expiration, after this date/time user's can not gets online.
  • credit: the amount of credit which is left for the user to spend.
  • real_first_login: date and time of user's very first login after its creation.
  • first_login: date and time of user's first login in its current service
  • charge_rule_usage: shows the usage (credit, time and traffic) of the user in each charge rule which is assigned to it.

To fetch user's group info we need either group_id or group_name.

creation_date, nearest_exp_date, first_login parameters are in following format: <year>-<month>-<day> <hour>:<minute>. All the values are zero padded.

Difference of real_first_login and first_login: as you can see we have created this user on 2018-10-14 10:19:00 (value of creation_date), then the user login to our system on 2018-10-14 11:19:22 (value of real_first_login) but he started using current service on 2018-10-14 11:29:32 (value of first_login).

  • charge_rule_usage is a list of charge rules assinged to corresponded user where each record have following format: [<charge_rule_id>, <charge_rule_name, <credit_usage>, <time_usage>, <traffic_usage>]. The time is in seconds and traffic in bytes. You can calculate the remaining time and traffic of user if the corresponded charge rule has required attributes like: Maximum Rule Time Usage or Maximum Rule Traffic Usage, you just need to subtract the usages from their initial values. For example if we set Maximum Rule Time and Traffic Usage to 5 Minutes and 20 Megabytes respectively, the remaining time and traffic will be approximatly 52 Seconds and 19.99 Megabytes respectively. You can read more about charge rule attributes here.

User's Connection Logs (CDRs)

To get the user's connection logs you should call report.getConnections method with the following parameters:

  • username: username of the user you want to get its usages.
  • login_time_from: from when we want the usages, the value can be a number or a complete date and time in string format, depending on what you specify in login_time_from_unit parameter (here we use date and time: 2018-10-14 09:00:00).
  • login_time_from_unit: unit of login_time_from field which can be gregorian, jalali, years, months, days, hours or mintues (here the unit is: gregorian).
  • login_time_to: same as login_time_from, if not specified, current date and time will be used.
  • login_time_to_unit: same as login_time_to_unit.
  • from and to: these parameters are for pagination purposes and are the start and the end index of returned records respectively.
$ curl -H "Content-Type: application/json" \
       -H "Accept: application/json" \
       -H "Accept-Charset: utf-8" \
       -H "Cache-Control: no-cache" \
       -X POST \
       -d '{"params": {"auth_remoteaddr": "192.168.1.101", "auth_type": "ADMIN", "auth_name": "system", "auth_session": "cm9vn23otwr5", "conds": {"username": "sample-user", "login_time_from": "2018-10-14 09:00:00", "login_time_from_unit": "gregorian"}, "from": 0, "to": 5, "sort_by": "login_time", "desc": false}, "method": "report.getConnections"}' \
       http://192.168.1.104:1237/

Output:

{
  "id": null,
  "result": {
    "total_rows": 1,
    "total_in_bytes": -1,
    "total_duration": -1,
    "total_out_bytes": -1,
    "total_credit": -1,
    "report": [
      {
        "sub_service_name": "Master",
        "logout_time_formatted": "2018-10-14 11:23:34",
        "caller_id": "",
        "group_name": "sample-group",
        "remote_ip": "192.168.1.20",
        "user_id": 12,
        "bytes_in": "1882",
        "sub_service_charging": "",
        "login_time_formatted": "2018-10-14 11:19:23",
        "charge_rule_details": [
          [
            "charge2",
            "2018-10-14 11:19:26",
            "2018-10-14 11:23:34",
            "0",
            "1882",
            "0",
            "9080"
          ]
        ],
        "details": [
          [
            "terminate_cause",
            "NAS-Request"
          ],
          [
            "station_ip",
            "172.17.109.41"
          ],
          [
            "pppoe_service",
            "172.17.109.146"
          ],
          [
            "nas_port_type",
            "Virtual"
          ],
          [
            "ippool_assigned_ip",
            "192.168.1.20"
          ],
          [
            "nas_port",
            "15728641"
          ]
        ],
        "ras_description": "ras1",
        "service_type": "Internet",
        "username": "sample-user",
        "successful": "t",
        "bytes_out": "9080",
        "before_credit": 1000,
        "sub_service_qos": "",
        "connection_log_id": 126,
        "credit_used": 0.0097,
        "retry_count": 1,
        "duration_seconds": 251,
        "unique_id_value": "15728641",
        "group_id": 2,
        "unique_id": "nas_port"
      }
    ]
  },
  "error": null
}

If you want to see the next 5 records (if available) you should set the from and to parameters to 5 and 10 respectively (in the time of execution of this request, the user had only one record).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment