1 package com.atlassian.refapp.trustedapps.internal;
2
3 import com.atlassian.sal.api.pluginsettings.PluginSettings;
4 import com.atlassian.sal.api.pluginsettings.PluginSettingsFactory;
5 import com.atlassian.security.auth.trustedapps.Application;
6 import com.atlassian.security.auth.trustedapps.ApplicationRetriever.RetrievalException;
7 import com.atlassian.security.auth.trustedapps.CurrentApplication;
8 import com.atlassian.security.auth.trustedapps.DefaultCurrentApplication;
9 import com.atlassian.security.auth.trustedapps.DefaultTrustedApplication;
10 import com.atlassian.security.auth.trustedapps.EncryptionProvider;
11 import com.atlassian.security.auth.trustedapps.RequestConditions;
12 import com.atlassian.security.auth.trustedapps.TrustedApplication;
13 import com.atlassian.security.auth.trustedapps.TrustedApplicationsConfigurationManager;
14 import com.atlassian.security.auth.trustedapps.TrustedApplicationsManager;
15 import org.apache.commons.lang.ObjectUtils;
16 import org.apache.commons.lang.StringUtils;
17
18 import java.security.KeyPair;
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.List;
22 import java.util.Properties;
23
24 public class RefAppTrustedApplicationsManagerImpl implements TrustedApplicationsManager, TrustedApplicationsConfigurationManager {
25 private static final String TRUSTED_APPS_KEY = "trustedapps";
26 private static final String TRUSTED_APP_KEY_PREFIX = "trustedapp.";
27
28 private static final String PUBLIC_KEY_KEY = "public.key";
29 private static final String TIMEOUT_KEY = "timeout";
30 private static final String URLS_KEY = "urls";
31 private static final String IPS_KEY = "ips";
32
33 private final EncryptionProvider encryptionProvider;
34 private final CurrentApplication currentApplication;
35 private final PluginSettingsFactory pluginSettingsFactory;
36
37 public RefAppTrustedApplicationsManagerImpl(EncryptionProvider encryptionProvider, KeyFactory keyFactory,
38 PluginSettingsFactory pluginSettingsFactory) {
39 this.encryptionProvider = encryptionProvider;
40 this.pluginSettingsFactory = pluginSettingsFactory;
41
42 KeyPair keyPair = keyFactory.getKeyPair();
43
44 currentApplication = new DefaultCurrentApplication(encryptionProvider, keyPair.getPublic(),
45 keyPair.getPrivate(), keyFactory.getApplicationId());
46 }
47
48 public CurrentApplication getCurrentApplication() {
49 return currentApplication;
50 }
51
52 public synchronized TrustedApplication getTrustedApplication(final String id) {
53 return load(id);
54 }
55
56 public Application getApplicationCertificate(final String url) throws RetrievalException {
57 return encryptionProvider.getApplicationCertificate(url);
58 }
59
60 public TrustedApplication addTrustedApplication(final Application app, final RequestConditions conditions) {
61 final TrustedApplication trustedApp = new DefaultTrustedApplication(
62 encryptionProvider,
63 app.getPublicKey(),
64 app.getID(),
65 conditions);
66 store(app, conditions);
67 return trustedApp;
68 }
69
70 public Collection<TrustedApplication> getTrustedApplications() {
71 final PluginSettings pluginSettings = pluginSettingsFactory.createGlobalSettings();
72 final List<String> ids = (List<String>) pluginSettings.get(TRUSTED_APPS_KEY);
73 final Collection<TrustedApplication> trustedApplications = new ArrayList<TrustedApplication>();
74 if (ids != null) {
75 for (String id : ids) {
76 TrustedApplication app = load(id);
77 if (app != null) {
78 trustedApplications.add(app);
79 }
80 }
81 }
82 return trustedApplications;
83 }
84
85 public boolean deleteApplication(final String id) {
86 final PluginSettings pluginSettings = pluginSettingsFactory.createGlobalSettings();
87 final List<String> ids = (List<String>) pluginSettings.get(TRUSTED_APPS_KEY);
88 if (ids != null && ids.contains(id)) {
89 ids.remove(id);
90 if (ids.isEmpty()) {
91 pluginSettings.remove(TRUSTED_APPS_KEY);
92 } else {
93 pluginSettings.put(TRUSTED_APPS_KEY, ids);
94 }
95 }
96 return pluginSettings.remove(TRUSTED_APP_KEY_PREFIX + id) != null;
97 }
98
99 private void store(final Application application, final RequestConditions conditions) {
100 final PluginSettings pluginSettings = pluginSettingsFactory.createGlobalSettings();
101 final List<String> ids = (List<String>) ObjectUtils.defaultIfNull(
102 pluginSettings.get(TRUSTED_APPS_KEY), new ArrayList<String>());
103 if (!ids.contains(application.getID())) {
104 ids.add(application.getID());
105 }
106 pluginSettings.put(TRUSTED_APPS_KEY, ids);
107 Properties props = new Properties();
108 props.put(PUBLIC_KEY_KEY, KeyUtils.encode(application.getPublicKey()));
109 props.put(TIMEOUT_KEY, Long.toString(conditions.getCertificateTimeout()));
110 props.put(URLS_KEY, iterableToString(conditions.getURLPatterns()));
111 props.put(IPS_KEY, iterableToString(conditions.getIPPatterns()));
112 pluginSettings.put(TRUSTED_APP_KEY_PREFIX + application.getID(), props);
113 }
114
115 private TrustedApplication load(final String id) {
116 final PluginSettings pluginSettings = pluginSettingsFactory.createGlobalSettings();
117 final Properties props = (Properties) pluginSettings.get(TRUSTED_APP_KEY_PREFIX + id);
118 if (props == null) {
119 return null;
120 } else {
121 final String publicKey = props.getProperty(PUBLIC_KEY_KEY);
122 final long timeout = Long.parseLong(props.getProperty(TIMEOUT_KEY));
123 final String[] urls = decodeCommaSeparatedString(props.getProperty(URLS_KEY));
124 final String[] ips = decodeCommaSeparatedString(props.getProperty(IPS_KEY));
125 return new DefaultTrustedApplication(encryptionProvider, KeyUtils.decodePublicKey(encryptionProvider,
126 publicKey), id, RequestConditions
127 .builder()
128 .setCertificateTimeout(timeout)
129 .addURLPattern(urls)
130 .addIPPattern(ips)
131 .build());
132 }
133 }
134
135 private static String iterableToString(final Iterable<String> iterable) {
136 return StringUtils.join(iterable.iterator(), ',');
137 }
138
139 private static String[] decodeCommaSeparatedString(final String str) {
140 if (str == null || str.length() == 0) {
141 return new String[]{};
142 }
143 return str.split(",");
144 }
145
146 }