Android Open Source - bgBanking Dsk Client






From Project

Back to project page bgBanking.

License

The source code is released under:

Apache License

If you think the Android project bgBanking listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*******************************************************************************
 * Copyright (c) 2012 MASConsult Ltd/*from   www.j  av a2s .  co  m*/
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/

package eu.masconsult.bgbanking.banks.dskbank;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.auth.AuthenticationException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import android.net.UrlQuerySanitizer;
import android.util.Log;
import eu.masconsult.bgbanking.BankingApplication;
import eu.masconsult.bgbanking.banks.BankClient;
import eu.masconsult.bgbanking.banks.CaptchaException;
import eu.masconsult.bgbanking.banks.RawBankAccount;
import eu.masconsult.bgbanking.utils.Convert;

public class DskClient implements BankClient {

    /** The tag used to log to adb console. */
    private static final String TAG = BankingApplication.TAG + "DskClient";

    /** Timeout (in ms) we specify for each http request */
    private static final int HTTP_REQUEST_TIMEOUT_MS = 30 * 1000;

    /** Domain for DSK Direct website */
    private static final String DOMAIN = "www.dskdirect.bg";
    /** Base URL for DSK Direct website */
    private static final String BASE_URL = "https://" + DOMAIN + "/page/default.aspx";
    private static final String XML_ID_PREFIX = "/en-US/";
    /** URI for authentication service */
    private static final String AUTH_XML_ID = XML_ID_PREFIX + ".processlogin";
    /** URI for retrieving bank account */
    private static final String LIST_ACCOUNTS_XML_ID = XML_ID_PREFIX + "01Individuals/02Accounts/";
    /** URI for retrieving captcha */
    private static final String CAPTCHA_XML_ID = XML_ID_PREFIX + ".CaptchaImage";

    /** POST parameter name for the user's account name */
    private static final String PARAM_USERNAME = "userName";
    /** POST parameter name for the user's password */
    private static final String PARAM_PASSWORD = "pwd";

    private static final String XML_ID = "xml_id";

    private static final String ENCODING = "utf8";

    private static final String PARAM_USER_ID = "user_id";

    private static final String PARAM_SESSION_ID = "session_id";

    private static final Pattern PATTERN_MATCH_BANK_ACCOUNT_ID =
            Pattern.compile(".*document\\.forms\\[0\\]\\.BankAccountID\\.value='(\\d+)';.*",
                    Pattern.MULTILINE | Pattern.DOTALL);

    /**
     * Configures the httpClient to connect to the URL provided.
     * 
     * @param authToken
     */
    private static DefaultHttpClient getHttpClient() {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        final HttpParams params = httpClient.getParams();
        HttpConnectionParams.setConnectionTimeout(params, HTTP_REQUEST_TIMEOUT_MS);
        HttpConnectionParams.setSoTimeout(params, HTTP_REQUEST_TIMEOUT_MS);
        ConnManagerParams.setTimeout(params, HTTP_REQUEST_TIMEOUT_MS);
        return httpClient;
    }

    @Override
    public String authenticate(String username, String password) throws IOException,
            ParseException, CaptchaException {
        final HttpResponse resp;
        final ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair(PARAM_USERNAME, username));
        params.add(new BasicNameValuePair(PARAM_PASSWORD, password));
        final HttpEntity entity;
        try {
            entity = new UrlEncodedFormEntity(params);
        } catch (final UnsupportedEncodingException e) {
            // this should never happen.
            throw new IllegalStateException(e);
        }
        String uri = BASE_URL + "?"
                + URLEncodedUtils.format(
                        Arrays.asList(new BasicNameValuePair(XML_ID, AUTH_XML_ID)), ENCODING);
        Log.i(TAG, "Authenticating to: " + uri);
        final HttpPost post = new HttpPost(uri);
        post.addHeader(entity.getContentType());
        post.setHeader("Accept", "*/*");
        post.setEntity(entity);
        try {
            resp = getHttpClient().execute(post);

            if (resp.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                throw new ParseException("login: unhandled http status "
                        + resp.getStatusLine().getStatusCode() + " "
                        + resp.getStatusLine().getReasonPhrase());
            }

            String response = EntityUtils.toString(resp.getEntity());
            Log.v(TAG, "response = " + response);

            Document doc = Jsoup.parse(response, BASE_URL);
            Element mainForm = doc.getElementById("mainForm");
            if (mainForm == null) {
                throw new ParseException("login: missing mainForm");
            }

            String action = BASE_URL + mainForm.attr("action");
            Log.v(TAG, "action=" + action);
            UrlQuerySanitizer sanitizer = new UrlQuerySanitizer(action);
            String user_id = sanitizer.getValue(PARAM_USER_ID);
            String session_id = sanitizer.getValue(PARAM_SESSION_ID);

            if (user_id == null || "".equals(user_id) || session_id == null
                    || "".equals(session_id)) {
                if (doc.getElementsByClass("redtext").size() > 0) {
                    // bad authentication
                    return null;
                } else {
                    // TODO handle captcha
                    Elements captcha = doc.select("input[name=captcha_hkey]");
                    if (captcha != null && captcha.size() == 1) {
                        String captchaHash = captcha.first().attr("value");
                        String captchaUri = BASE_URL + "?" + URLEncodedUtils.format(Arrays.asList(
                                new BasicNameValuePair(XML_ID, CAPTCHA_XML_ID),
                                new BasicNameValuePair("captcha_key", captchaHash)
                                ),
                                ENCODING);
                        throw new CaptchaException(captchaUri);
                    }
                    throw new ParseException("no user_id or session_id: " + action);
                }
            }

            return URLEncodedUtils.format(Arrays.asList(
                    new BasicNameValuePair(PARAM_USER_ID, user_id),
                    new BasicNameValuePair(PARAM_SESSION_ID, session_id)),
                    ENCODING);
        } catch (ClientProtocolException e) {
            throw new IOException(e.getMessage());
        }
    }

    @Override
    public List<RawBankAccount> getBankAccounts(String authToken) throws IOException,
            ParseException, AuthenticationException {
        String uri = BASE_URL + "?" + URLEncodedUtils.format(
                Arrays.asList(new BasicNameValuePair(XML_ID, LIST_ACCOUNTS_XML_ID)), ENCODING)
                + "&" + authToken;

        // Get the accounts list
        Log.i(TAG, "Getting from: " + uri);
        final HttpGet get = new HttpGet(uri);
        get.setHeader("Accept", "*/*");

        DefaultHttpClient httpClient = getHttpClient();

        Log.v(TAG, "sending " + get.toString());
        final HttpResponse resp = httpClient.execute(get);

        if (resp.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
            throw new ParseException("getBankAccounts: unhandled http status "
                    + resp.getStatusLine().getStatusCode() + " "
                    + resp.getStatusLine().getReasonPhrase());
        }

        HttpEntity entity = resp.getEntity();
        Document doc = Jsoup.parse(entity.getContent(), "utf-8", BASE_URL);

        if (!checkLoggedIn(doc)) {
            throw new AuthenticationException("session expired!");
        }

        Element content = doc.getElementById("PageContent");
        if (content == null) {
            throw new ParseException("getBankAccounts: can't find PageContent");
        }

        Elements tables = content.getElementsByTag("table");
        if (tables == null || tables.size() == 0) {
            throw new ParseException("getBankAccounts: can't find table in PageContent");
        }

        Elements rows = tables.first().getElementsByTag("tr");
        if (rows == null || rows.size() == 0) {
            throw new ParseException("getBankAccounts: first table is empty in PageContent");
        }

        ArrayList<RawBankAccount> bankAccounts = new ArrayList<RawBankAccount>(rows.size());

        String lastCurrency = null;
        for (Element row : rows) {
            RawBankAccount bankAccount = obtainBankAccountFromHtmlTableRow(row);
            if (bankAccount != null) {
                if (bankAccount.getCurrency() == null) {
                    bankAccount.setCurrency(lastCurrency);
                } else {
                    lastCurrency = bankAccount.getCurrency();
                }
                bankAccounts.add(bankAccount);
            }
        }

        return bankAccounts;
    }

    private RawBankAccount obtainBankAccountFromHtmlTableRow(Element row) {
        // skip title rows
        if (row.children().size() != 4) {
            return null;
        }
        // skip header
        if (row.hasClass("td-header")) {
            return null;
        }

        String onclick = row.child(0).child(0).attr("onclick");
        Matcher matcher = PATTERN_MATCH_BANK_ACCOUNT_ID.matcher(onclick);
        if (!matcher.find()) {
            throw new ParseException("can't find bank account id in " + onclick);
        }

        return new RawBankAccount()
                .setServerId(matcher.group(1))
                .setName(row.child(0).text())
                .setIBAN(row.child(1).text())
                .setCurrency(row.child(2).text())
                .setBalance(Convert.strToFloat(row.child(3).text()))
                .setAvailableBalance(Convert.strToFloat(row.child(3).text()));
    }

    private boolean checkLoggedIn(Document doc) {
        Elements sup_links = doc.getElementsByClass("supplemental_links");
        if (sup_links == null || sup_links.size() == 0) {
            throw new ParseException("getBankAccounts: can't find .supplemental_links");
        }
        for (Element sup_link : sup_links) {
            Elements exits = sup_link.getElementsContainingText("Log Out");
            if (exits != null && exits.size() > 0) {
                return true;
            }
        }
        return false;
    }

}




Java Source Code List

eu.masconsult.bgbanking.BankAdapter.java
eu.masconsult.bgbanking.BankingApplication.java
eu.masconsult.bgbanking.Constants.java
eu.masconsult.bgbanking.accounts.AccountAuthenticator.java
eu.masconsult.bgbanking.accounts.AuthenticationService.java
eu.masconsult.bgbanking.accounts.LoginActivity.java
eu.masconsult.bgbanking.activity.HomeActivity.java
eu.masconsult.bgbanking.activity.fragment.AccountsListFragment.java
eu.masconsult.bgbanking.activity.fragment.ChooseAccountTypeFragment.java
eu.masconsult.bgbanking.banks.BankClient.java
eu.masconsult.bgbanking.banks.Bank.java
eu.masconsult.bgbanking.banks.CaptchaException.java
eu.masconsult.bgbanking.banks.RawBankAccount.java
eu.masconsult.bgbanking.banks.dskbank.AuthenticationService.java
eu.masconsult.bgbanking.banks.dskbank.DskClient.java
eu.masconsult.bgbanking.banks.dskbank.SyncService.java
eu.masconsult.bgbanking.banks.fibank.ebanking.AuthenticationService.java
eu.masconsult.bgbanking.banks.fibank.ebanking.EFIBankClient.java
eu.masconsult.bgbanking.banks.fibank.ebanking.SyncService.java
eu.masconsult.bgbanking.banks.fibank.my.AuthenticationService.java
eu.masconsult.bgbanking.banks.fibank.my.MyFIBankClient.java
eu.masconsult.bgbanking.banks.fibank.my.SyncService.java
eu.masconsult.bgbanking.banks.procreditbank.AuthenticationService.java
eu.masconsult.bgbanking.banks.procreditbank.ProcreditClient.java
eu.masconsult.bgbanking.banks.procreditbank.SyncService.java
eu.masconsult.bgbanking.banks.sgexpress.AuthenticationService.java
eu.masconsult.bgbanking.banks.sgexpress.SGExpressClient.java
eu.masconsult.bgbanking.banks.sgexpress.SyncService.java
eu.masconsult.bgbanking.platform.BankAccountManager.java
eu.masconsult.bgbanking.platform.BankAccountOperations.java
eu.masconsult.bgbanking.platform.BatchOperation.java
eu.masconsult.bgbanking.provider.BankingContract.java
eu.masconsult.bgbanking.provider.BankingProvider.java
eu.masconsult.bgbanking.sync.SyncAdapter.java
eu.masconsult.bgbanking.sync.SyncService.java
eu.masconsult.bgbanking.ui.LightProgressDialog.java
eu.masconsult.bgbanking.utils.Convert.java
eu.masconsult.bgbanking.utils.CookieQuotesFixerResponseInterceptor.java
eu.masconsult.bgbanking.utils.CookieRequestInterceptor.java
eu.masconsult.bgbanking.utils.DumpHeadersRequestInterceptor.java
eu.masconsult.bgbanking.utils.DumpHeadersResponseInterceptor.java
eu.masconsult.bgbanking.utils.SampleCursor.java