1 package com.atlassian.sal.core.features;
2
3 import com.atlassian.sal.api.features.DarkFeatureManager;
4 import com.atlassian.sal.api.features.EnabledDarkFeatures;
5 import com.atlassian.sal.api.features.EnabledDarkFeaturesBuilder;
6 import com.atlassian.sal.api.features.MissingPermissionException;
7 import com.atlassian.sal.api.features.SiteDarkFeaturesStorage;
8 import com.atlassian.sal.api.features.ValidFeatureKeyPredicate;
9 import com.atlassian.sal.api.user.UserKey;
10 import com.atlassian.sal.api.user.UserManager;
11
12 import javax.annotation.Nonnull;
13 import javax.annotation.Nullable;
14
15 import java.util.Optional;
16
17 import static com.atlassian.sal.api.features.ValidFeatureKeyPredicate.checkFeatureKey;
18
19
20
21
22
23 public class DefaultDarkFeatureManager implements DarkFeatureManager {
24 private final UserManager userManager;
25 private final SiteDarkFeaturesStorage siteDarkFeaturesStorage;
26 private final SystemDarkFeatureInitializer.SystemDarkFeatures systemDarkFeatures;
27
28 public DefaultDarkFeatureManager(final UserManager userManager, final SiteDarkFeaturesStorage siteDarkFeaturesStorage) {
29 this.userManager = userManager;
30 this.siteDarkFeaturesStorage = siteDarkFeaturesStorage;
31 this.systemDarkFeatures = SystemDarkFeatureInitializer.getSystemStartupDarkFeatures();
32 }
33
34 @Override
35 @Nonnull
36 public Optional<Boolean> isEnabledForAllUsers(@Nonnull String featureKey) {
37 if (!ValidFeatureKeyPredicate.isValidFeatureKey(featureKey)) {
38 return Optional.empty();
39 }
40 if (systemDarkFeatures.getEnabled().contains(featureKey)
41 || siteDarkFeaturesStorage.contains(featureKey)) {
42 return Optional.of(Boolean.TRUE);
43 }
44 if (systemDarkFeatures.getDisabled().contains(featureKey)) {
45 return Optional.of(Boolean.FALSE);
46 }
47 return Optional.empty();
48 }
49
50 @Override
51 @Nonnull
52 public Optional<Boolean> isEnabledForCurrentUser(@Nonnull String featureKey) {
53 return isEnabledForAllUsers(featureKey);
54 }
55
56 @Override
57 @Nonnull
58 public Optional<Boolean> isEnabledForUser(@Nullable UserKey userKey, @Nonnull String featureKey) {
59 if (isUserAnonymous(userKey) || isUserExisting(userKey)) {
60 return isEnabledForAllUsers(featureKey);
61 } else {
62 throw new IllegalArgumentException("The user does not exist");
63 }
64 }
65
66 @Override
67 @Deprecated
68 public boolean isFeatureEnabledForAllUsers(final String featureKey) {
69 return ValidFeatureKeyPredicate.isValidFeatureKey(featureKey) && getFeaturesEnabledForAllUsers().isFeatureEnabled(featureKey);
70 }
71
72 @Override
73 @Deprecated
74 public boolean isFeatureEnabledForCurrentUser(final String featureKey) {
75 return isFeatureEnabledForAllUsers(featureKey);
76 }
77
78 @Override
79 @Deprecated
80 public boolean isFeatureEnabledForUser(@Nullable final UserKey userKey, final String featureKey) {
81 if (isUserAnonymous(userKey) || isUserExisting(userKey)) {
82 return isFeatureEnabledForAllUsers(featureKey);
83 } else {
84 throw new IllegalArgumentException("The user does not exist");
85 }
86 }
87
88 @Override
89 public boolean canManageFeaturesForAllUsers() {
90 try {
91 final UserKey remoteUserKey = userManager.getRemoteUserKey();
92 return userManager.isSystemAdmin(remoteUserKey);
93 } catch (RuntimeException e) {
94
95
96
97
98
99 return false;
100 }
101 }
102
103 @Override
104 public void enableFeatureForAllUsers(final String featureKey) {
105 checkFeatureKey(featureKey);
106 checkCurrentUserCanManageFeaturesForAllUsers();
107 siteDarkFeaturesStorage.enable(featureKey);
108 }
109
110 @Override
111 public void disableFeatureForAllUsers(final String featureKey) {
112 checkFeatureKey(featureKey);
113 checkCurrentUserCanManageFeaturesForAllUsers();
114 siteDarkFeaturesStorage.disable(featureKey);
115 }
116
117 @Override
118 public void enableFeatureForCurrentUser(final String featureKey) {
119 throwUnsupportedPerUserOperationException();
120 }
121
122 @Override
123 public void enableFeatureForUser(final UserKey userKey, final String featureKey) {
124 throwUnsupportedPerUserOperationException();
125 }
126
127 @Override
128 public void disableFeatureForCurrentUser(final String featureKey) {
129 throwUnsupportedPerUserOperationException();
130 }
131
132 @Override
133 public void disableFeatureForUser(final UserKey userKey, final String featureKey) {
134 throwUnsupportedPerUserOperationException();
135 }
136
137 public EnabledDarkFeatures getFeaturesEnabledForAllUsers() {
138 if (systemDarkFeatures.isDisableAll()) {
139 return EnabledDarkFeatures.NONE;
140 } else {
141 return new EnabledDarkFeaturesBuilder()
142 .unmodifiableFeaturesEnabledForAllUsers(systemDarkFeatures.getEnabled())
143 .featuresEnabledForAllUsers(siteDarkFeaturesStorage.getEnabledDarkFeatures())
144 .build();
145 }
146 }
147
148 @Override
149 public EnabledDarkFeatures getFeaturesEnabledForCurrentUser() {
150 return getFeaturesEnabledForAllUsers();
151 }
152
153 @Override
154 public EnabledDarkFeatures getFeaturesEnabledForUser(@Nullable final UserKey userKey) {
155 if (isUserAnonymous(userKey) || isUserExisting(userKey)) {
156 return getFeaturesEnabledForAllUsers();
157 } else {
158 throw new IllegalArgumentException("The user does not exist");
159 }
160 }
161
162 private boolean isUserExisting(@Nullable final UserKey userKey) {
163 return (userKey != null) && userManager.getUserProfile(userKey) != null;
164 }
165
166 private boolean isUserAnonymous(@Nullable final UserKey userKey) {
167 return userKey == null;
168 }
169
170 private void checkCurrentUserCanManageFeaturesForAllUsers() {
171 if (!canManageFeaturesForAllUsers()) {
172 throw new MissingPermissionException("The current user is not allowed to change dark features affecting all users.");
173 }
174 }
175
176 private void throwUnsupportedPerUserOperationException() {
177 throw new UnsupportedOperationException("The default implementation doesn't support per-user dark features.");
178 }
179 }