summaryrefslogtreecommitdiff
path: root/app/src/main/java/se/leap/bitmaskclient/ProviderManager.java
blob: abbdeb66a849739477b35f016a0b457b2374a567 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
package se.leap.bitmaskclient;

import android.content.res.*;

import com.pedrogomez.renderers.*;

import org.json.*;

import java.io.*;
import java.net.*;
import java.util.*;

/**
 * Created by parmegv on 4/12/14.
 */
public class ProviderManager implements AdapteeCollection<Provider> {

    private AssetManager assets_manager;
    private File external_files_dir;
    private Set<Provider> default_providers;
    private Set<Provider> custom_providers;

    private static ProviderManager instance;

    final protected static String URLS = "urls";

    public static ProviderManager getInstance(AssetManager assets_manager, File external_files_dir) {
        if (instance == null)
            instance = new ProviderManager(assets_manager, external_files_dir);

        return instance;
    }

    public ProviderManager(AssetManager assets_manager, File external_files_dir) {
        this.assets_manager = assets_manager;
        addDefaultProviders(assets_manager);
        addCustomProviders(external_files_dir);
    }

    private void addDefaultProviders(AssetManager assets_manager) {
        try {
            default_providers = providersFromAssets(URLS, assets_manager.list(URLS));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private Set<Provider> providersFromAssets(String directory, String[] relative_file_paths) {
        Set<Provider> providers = new HashSet<Provider>();
        try {
            for (String file : relative_file_paths) {
                InputStream provider_file = assets_manager.open(directory + "/" + file);
                String main_url = extractMainUrlFromInputStream(provider_file);
                String certificate_pin = extractCertificatePinFromInputStream(provider_file);
                if(certificate_pin.isEmpty())
                    providers.add(new Provider(new URL(main_url)));
                else
                    providers.add(new Provider(new URL(main_url), certificate_pin));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return providers;
    }


    private void addCustomProviders(File external_files_dir) {
        this.external_files_dir = external_files_dir;
        custom_providers = external_files_dir != null && external_files_dir.isDirectory() ?
                providersFromFiles(external_files_dir.list()) :
                new HashSet<Provider>();
    }

    private Set<Provider> providersFromFiles(String[] files) {
        Set<Provider> providers = new HashSet<Provider>();
        try {
            for (String file : files) {
                String main_url = extractMainUrlFromInputStream(new FileInputStream(external_files_dir.getAbsolutePath() + "/" + file));
                providers.add(new Provider(new URL(main_url)));
            }
        } catch (MalformedURLException | FileNotFoundException e) {
            e.printStackTrace();
        }

        return providers;
    }

    private String extractMainUrlFromInputStream(InputStream input_stream) {
        String main_url = "";

        JSONObject file_contents = inputStreamToJson(input_stream);
        if(file_contents != null)
            main_url = file_contents.optString(Provider.MAIN_URL);
        return main_url;
    }

    private String extractCertificatePinFromInputStream(InputStream input_stream) {
        String certificate_pin = "";

        JSONObject file_contents = inputStreamToJson(input_stream);
        if(file_contents != null)
            certificate_pin = file_contents.optString(Provider.CA_CERT_FINGERPRINT);

        return certificate_pin;
    }

    private JSONObject inputStreamToJson(InputStream input_stream) {
        JSONObject json = null;
        try {
            byte[] bytes = new byte[input_stream.available()];
            if (input_stream.read(bytes) > 0)
                json = new JSONObject(new String(bytes));
            input_stream.reset();
        } catch (IOException | JSONException e) {
            e.printStackTrace();
        }
        return json;
    }

    public Set<Provider> providers() {
        Set<Provider> all_providers = new HashSet<Provider>();
        all_providers.addAll(default_providers);
        if(custom_providers != null)
            all_providers.addAll(custom_providers);
        return all_providers;
    }

    @Override
    public int size() {
        return providers().size();
    }

    @Override
    public Provider get(int index) {
        Iterator<Provider> iterator = providers().iterator();
        while (iterator.hasNext() && index > 0) {
            iterator.next();
            index--;
        }
        return iterator.next();
    }

    @Override
    public boolean add(Provider element) {
        if (!default_providers.contains(element))
            return custom_providers.add(element);
        else return true;
    }

    @Override
    public boolean remove(Object element) {
        return custom_providers.remove(element);
    }

    @Override
    public boolean addAll(Collection<? extends Provider> elements) {
        return custom_providers.addAll(elements);
    }

    @Override
    public boolean removeAll(Collection<?> elements) {
        if(!elements.getClass().equals(Provider.class))
            return false;
        return default_providers.removeAll(elements) || custom_providers.removeAll(elements);
    }

    @Override
    public void clear() {
        default_providers.clear();
        custom_providers.clear();
    }

    protected void saveCustomProvidersToFile() {
        try {
            for (Provider provider : custom_providers) {
                File provider_file = new File(external_files_dir, provider.getName() + ".json");
                if (!provider_file.exists()) {
                    FileWriter writer = new FileWriter(provider_file);
                    writer.write(provider.toJson().toString());
                    writer.close();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}