/* * Copyright 2016 OpenMarket Ltd * * 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 org.matrix.androidsdk; import android.net.Uri; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.matrix.androidsdk.rest.model.login.Credentials; import org.matrix.androidsdk.ssl.Fingerprint; import java.util.ArrayList; /** * Represents how to connect to a specific Homeserver, may include credentials to use. */ public class HomeserverConnectionConfig { private Uri mHsUri; private Uri mIdentityServerUri; private ArrayList<Fingerprint> mAllowedFingerprints = new ArrayList<>(); private Credentials mCredentials; private boolean mPin; /** * @param hsUri The URI to use to connect to the homeserver */ public HomeserverConnectionConfig(Uri hsUri) { this(hsUri, null); } /** * @param hsUri The URI to use to connect to the homeserver * @param credentials The credentials to use, if needed. Can be null. */ public HomeserverConnectionConfig(Uri hsUri, Credentials credentials) { this(hsUri, null, credentials, new ArrayList<Fingerprint>(), false); } /** * @param hsUri The URI to use to connect to the homeserver * @param identityServerUri The URI to use to manage identity * @param credentials The credentials to use, if needed. Can be null. * @param allowedFingerprints If using SSL, allow server certs that match these fingerprints. * @param pin If true only allow certs matching given fingerprints, otherwise fallback to * standard X509 checks. */ public HomeserverConnectionConfig(Uri hsUri, Uri identityServerUri, Credentials credentials, ArrayList<Fingerprint> allowedFingerprints, boolean pin) { if (hsUri == null || (!"http".equals(hsUri.getScheme()) && !"https".equals(hsUri.getScheme())) ) { throw new RuntimeException("Invalid home server URI: "+hsUri); } if ((null != identityServerUri) && (!"http".equals(hsUri.getScheme()) && !"https".equals(hsUri.getScheme()))) { throw new RuntimeException("Invalid identity server URI: " + identityServerUri); } // remove trailing / if (hsUri.toString().endsWith("/")) { try { String url = hsUri.toString(); hsUri = Uri.parse(url.substring(0, url.length()-1)); } catch (Exception e) { throw new RuntimeException("Invalid home server URI: "+hsUri); } } // remove trailing / if ((null != identityServerUri) && identityServerUri.toString().endsWith("/")) { try { String url = identityServerUri.toString(); identityServerUri = Uri.parse(url.substring(0, url.length()-1)); } catch (Exception e) { throw new RuntimeException("Invalid identity server URI: " + identityServerUri); } } this.mHsUri = hsUri; this.mIdentityServerUri = identityServerUri; if (null != allowedFingerprints) { this.mAllowedFingerprints = allowedFingerprints; } this.mPin = pin; this.mCredentials = credentials; } public void setHomeserverUri(Uri uri) { mHsUri = uri; } public Uri getHomeserverUri() { return mHsUri; } public void setIdentityServerUri(Uri uri) { mIdentityServerUri = uri; } public Uri getIdentityServerUri() { return (null == mIdentityServerUri) ? mHsUri : mIdentityServerUri; } public ArrayList<Fingerprint> getAllowedFingerprints() { return mAllowedFingerprints; } public Credentials getCredentials() { return mCredentials; } public void setCredentials(Credentials credentials) { this.mCredentials = credentials; } /** * @return whether we should reject X509 certs that were issued by trusts CAs and only trust * certs with matching fingerprints. */ public boolean shouldPin() { return mPin; } @Override public String toString() { return "HomeserverConnectionConfig{" + "mHsUri=" + mHsUri + "mIdentityServerUri=" + mIdentityServerUri + ", mAllowedFingerprints size=" + mAllowedFingerprints.size() + ", mCredentials=" + mCredentials + ", mPin=" + mPin + '}'; } public JSONObject toJson() throws JSONException { JSONObject json = new JSONObject(); json.put("home_server_url", mHsUri.toString()); json.put("identity_server_url", getIdentityServerUri().toString()); json.put("pin", mPin); if (mCredentials != null) json.put("credentials", mCredentials.toJson()); if (mAllowedFingerprints != null) { ArrayList<JSONObject> fingerprints = new ArrayList<>(mAllowedFingerprints.size()); for (Fingerprint fingerprint : mAllowedFingerprints) { fingerprints.add(fingerprint.toJson()); } json.put("fingerprints", new JSONArray(fingerprints)); } return json; } public static HomeserverConnectionConfig fromJson(JSONObject obj) throws JSONException { JSONArray fingerprintArray = obj.optJSONArray("fingerprints"); ArrayList<Fingerprint> fingerprints = new ArrayList<>(); if (fingerprintArray != null) { for (int i = 0; i < fingerprintArray.length(); i++) { fingerprints.add(Fingerprint.fromJson(fingerprintArray.getJSONObject(i))); } } JSONObject credentialsObj = obj.optJSONObject("credentials"); Credentials creds = credentialsObj != null ? Credentials.fromJson(credentialsObj) : null; HomeserverConnectionConfig config = new HomeserverConnectionConfig( Uri.parse(obj.getString("home_server_url")), obj.has("identity_server_url") ? Uri.parse(obj.getString("identity_server_url")) : null, creds, fingerprints, obj.optBoolean("pin", false)); return config; } }