1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.appender.rolling.action;
18
19 import java.io.IOException;
20 import java.nio.file.FileVisitResult;
21 import java.nio.file.FileVisitor;
22 import java.nio.file.Path;
23 import java.nio.file.SimpleFileVisitor;
24 import java.nio.file.attribute.BasicFileAttributes;
25 import java.nio.file.attribute.FileOwnerAttributeView;
26 import java.nio.file.attribute.PosixFileAttributeView;
27 import java.nio.file.attribute.PosixFilePermission;
28 import java.nio.file.attribute.PosixFilePermissions;
29 import java.util.List;
30 import java.util.Set;
31
32 import org.apache.logging.log4j.core.Core;
33 import org.apache.logging.log4j.core.config.Configuration;
34 import org.apache.logging.log4j.core.config.plugins.Plugin;
35 import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
36 import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
37 import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
38 import org.apache.logging.log4j.core.config.plugins.PluginElement;
39 import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
40 import org.apache.logging.log4j.core.lookup.StrSubstitutor;
41 import org.apache.logging.log4j.core.util.FileUtils;
42 import org.apache.logging.log4j.util.Strings;
43
44
45
46
47
48
49 @Plugin(name = "PosixViewAttribute", category = Core.CATEGORY_NAME, printObject = true)
50 public class PosixViewAttributeAction extends AbstractPathAction {
51
52
53
54
55 private final Set<PosixFilePermission> filePermissions;
56
57
58
59
60 private final String fileOwner;
61
62
63
64
65 private final String fileGroup;
66
67 private PosixViewAttributeAction(final String basePath, final boolean followSymbolicLinks,
68 final int maxDepth, final PathCondition[] pathConditions, final StrSubstitutor subst,
69 final Set<PosixFilePermission> filePermissions,
70 final String fileOwner, final String fileGroup) {
71 super(basePath, followSymbolicLinks, maxDepth, pathConditions, subst);
72 this.filePermissions = filePermissions;
73 this.fileOwner = fileOwner;
74 this.fileGroup = fileGroup;
75 }
76
77 @PluginBuilderFactory
78 public static Builder newBuilder() {
79 return new Builder();
80 }
81
82
83
84
85 public static class Builder implements org.apache.logging.log4j.core.util.Builder<PosixViewAttributeAction> {
86
87 @PluginConfiguration
88 private Configuration configuration;
89
90 private StrSubstitutor subst;
91
92 @PluginBuilderAttribute
93 @Required(message = "No base path provided")
94 private String basePath;
95
96 @PluginBuilderAttribute
97 private boolean followLinks = false;
98
99 @PluginBuilderAttribute
100 private int maxDepth = 1;
101
102 @PluginElement("PathConditions")
103 private PathCondition[] pathConditions;
104
105 @PluginBuilderAttribute(value = "filePermissions")
106 private String filePermissionsString;
107
108 private Set<PosixFilePermission> filePermissions;
109
110 @PluginBuilderAttribute
111 private String fileOwner;
112
113 @PluginBuilderAttribute
114 private String fileGroup;
115
116 @Override
117 public PosixViewAttributeAction build() {
118 if (Strings.isEmpty(basePath)) {
119 LOGGER.error("Posix file attribute view action not valid because base path is empty.");
120 return null;
121 }
122
123 if (filePermissions == null && Strings.isEmpty(filePermissionsString)
124 && Strings.isEmpty(fileOwner) && Strings.isEmpty(fileGroup)) {
125 LOGGER.error("Posix file attribute view not valid because nor permissions, user or group defined.");
126 return null;
127 }
128
129 if (!FileUtils.isFilePosixAttributeViewSupported()) {
130 LOGGER.warn("Posix file attribute view defined but it is not supported by this files system.");
131 return null;
132 }
133
134 return new PosixViewAttributeAction(basePath, followLinks, maxDepth, pathConditions,
135 subst != null ? subst : configuration.getStrSubstitutor(),
136 filePermissions != null ? filePermissions :
137 filePermissionsString != null ? PosixFilePermissions.fromString(filePermissionsString) : null,
138 fileOwner,
139 fileGroup);
140 }
141
142
143
144
145
146
147
148 public Builder withConfiguration(final Configuration configuration) {
149 this.configuration = configuration;
150 return this;
151 }
152
153
154
155
156
157
158
159 public Builder withSubst(final StrSubstitutor subst) {
160 this.subst = subst;
161 return this;
162 }
163
164
165
166
167
168
169 public Builder withBasePath(final String basePath) {
170 this.basePath = basePath;
171 return this;
172 }
173
174
175
176
177
178
179 public Builder withFollowLinks(final boolean followLinks) {
180 this.followLinks = followLinks;
181 return this;
182 }
183
184
185
186
187
188
189 public Builder withMaxDepth(final int maxDepth) {
190 this.maxDepth = maxDepth;
191 return this;
192 }
193
194
195
196
197
198
199
200 public Builder withPathConditions(final PathCondition[] pathConditions) {
201 this.pathConditions = pathConditions;
202 return this;
203 }
204
205
206
207
208
209
210
211
212
213
214 public Builder withFilePermissionsString(final String filePermissionsString) {
215 this.filePermissionsString = filePermissionsString;
216 return this;
217 }
218
219
220
221
222
223
224 public Builder withFilePermissions(final Set<PosixFilePermission> filePermissions) {
225 this.filePermissions = filePermissions;
226 return this;
227 }
228
229
230
231
232
233
234 public Builder withFileOwner(final String fileOwner) {
235 this.fileOwner = fileOwner;
236 return this;
237 }
238
239
240
241
242
243
244 public Builder withFileGroup(final String fileGroup) {
245 this.fileGroup = fileGroup;
246 return this;
247 }
248 }
249
250 @Override
251 protected FileVisitor<Path> createFileVisitor(final Path basePath,
252 final List<PathCondition> conditions) {
253 return new SimpleFileVisitor<Path>() {
254 @Override
255 public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException {
256 for (final PathCondition pathFilter : conditions) {
257 final Path relative = basePath.relativize(file);
258 if (!pathFilter.accept(basePath, relative, attrs)) {
259 LOGGER.trace("Not defining posix attribute base={}, relative={}", basePath, relative);
260 return FileVisitResult.CONTINUE;
261 }
262 }
263 FileUtils.defineFilePosixAttributeView(file, filePermissions, fileOwner, fileGroup);
264 return FileVisitResult.CONTINUE;
265 }
266 };
267 }
268
269
270
271
272
273
274
275 public Set<PosixFilePermission> getFilePermissions() {
276 return filePermissions;
277 }
278
279
280
281
282
283
284
285 public String getFileOwner() {
286 return fileOwner;
287 }
288
289
290
291
292
293
294
295 public String getFileGroup() {
296 return fileGroup;
297 }
298
299 @Override
300 public String toString() {
301 return "PosixViewAttributeAction [filePermissions=" + filePermissions + ", fileOwner="
302 + fileOwner + ", fileGroup=" + fileGroup + ", getBasePath()=" + getBasePath()
303 + ", getMaxDepth()=" + getMaxDepth() + ", getPathConditions()="
304 + getPathConditions() + "]";
305 }
306
307 }