blob: 629d6aa056ee7828fed44fdb2dfd7c5f1517996d [file] [log] [blame]
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you 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.apache.james.mailbox.store.quota;
import java.util.List;
import java.util.Optional;
import javax.inject.Inject;
import org.apache.james.core.Username;
import org.apache.james.mailbox.MailboxSession;
import org.apache.james.mailbox.SessionProvider;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.model.Mailbox;
import org.apache.james.mailbox.model.MailboxConstants;
import org.apache.james.mailbox.model.MailboxId;
import org.apache.james.mailbox.model.MailboxPath;
import org.apache.james.mailbox.model.QuotaRoot;
import org.apache.james.mailbox.model.search.MailboxQuery;
import org.apache.james.mailbox.quota.QuotaRootDeserializer;
import org.apache.james.mailbox.quota.UserQuotaRootResolver;
import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
import org.reactivestreams.Publisher;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
public class DefaultUserQuotaRootResolver implements UserQuotaRootResolver {
public static class DefaultQuotaRootDeserializer implements QuotaRootDeserializer {
@Override
public QuotaRoot fromString(String serializedQuotaRoot) throws MailboxException {
List<String> parts = toParts(serializedQuotaRoot);
Username username = Username.of(parts.get(1));
return QuotaRoot.quotaRoot(serializedQuotaRoot, username.getDomainPart());
}
private List<String> toParts(String serializedQuotaRoot) throws MailboxException {
List<String> parts = Splitter.on(SEPARATOR).splitToList(serializedQuotaRoot);
if (parts.size() != 2) {
throw new MailboxException(serializedQuotaRoot + " used as QuotaRoot should contain exactly one \"" + SEPARATOR + "\"");
}
return parts;
}
}
public static final String SEPARATOR = "&"; // Character illegal for mailbox naming in regard of RFC 3501 section 5.1
private static final DefaultQuotaRootDeserializer QUOTA_ROOT_DESERIALIZER = new DefaultQuotaRootDeserializer();
private final SessionProvider sessionProvider;
private final MailboxSessionMapperFactory factory;
@Inject
public DefaultUserQuotaRootResolver(SessionProvider sessionProvider, MailboxSessionMapperFactory factory) {
this.sessionProvider = sessionProvider;
this.factory = factory;
}
@Override
public QuotaRoot forUser(Username username) {
return QuotaRoot.quotaRoot(MailboxConstants.USER_NAMESPACE + SEPARATOR + username.asString(),
username.getDomainPart());
}
@Override
public QuotaRoot getQuotaRoot(MailboxPath mailboxPath) {
Preconditions.checkArgument(!mailboxPath.getNamespace().contains(SEPARATOR), "Namespace should not contain %s", SEPARATOR);
return Optional.ofNullable(mailboxPath.getUser())
.map(user -> {
Preconditions.checkArgument(!mailboxPath.getUser().asString().contains(SEPARATOR), "Username should not contain %s", SEPARATOR);
return mailboxPath.getUser();
})
.map(user -> QuotaRoot.quotaRoot(mailboxPath.getNamespace() + SEPARATOR + user.asString(), user.getDomainPart()))
.orElseGet(() -> QuotaRoot.quotaRoot(mailboxPath.getNamespace(), Optional.empty()));
}
@Override
public QuotaRoot getQuotaRoot(Mailbox mailbox) {
return getQuotaRoot(mailbox.generateAssociatedPath());
}
@Override
public QuotaRoot getQuotaRoot(MailboxId mailboxId) {
return getQuotaRootReactive(mailboxId).block();
}
@Override
public Mono<QuotaRoot> getQuotaRootReactive(MailboxId mailboxId) {
MailboxSession session = sessionProvider.createSystemSession(Username.of("DefaultUserQuotaRootResolver"));
return factory.getMailboxMapper(session)
.findMailboxById(mailboxId)
.map(Mailbox::generateAssociatedPath)
.map(MailboxPath::getUser)
.map(this::forUser);
}
@Override
public Publisher<QuotaRoot> getQuotaRootReactive(MailboxPath mailboxPath) {
return Mono.just(getQuotaRoot(mailboxPath));
}
@Override
public Publisher<QuotaRoot> getQuotaRootReactive(Mailbox mailbox) {
return Mono.just(getQuotaRoot(mailbox));
}
@Override
public QuotaRoot fromString(String serializedQuotaRoot) throws MailboxException {
return QUOTA_ROOT_DESERIALIZER.fromString(serializedQuotaRoot);
}
@Override
public Flux<Mailbox> retrieveAssociatedMailboxes(QuotaRoot quotaRoot, MailboxSession mailboxSession) {
try {
List<String> parts = QUOTA_ROOT_DESERIALIZER.toParts(quotaRoot.getValue());
String namespace = parts.get(0);
String user = parts.get(1);
return factory.getMailboxMapper(mailboxSession)
.findMailboxWithPathLike(MailboxQuery.builder()
.namespace(namespace)
.user(Username.of(user))
.matchesAllMailboxNames()
.build()
.asUserBound());
} catch (MailboxException e) {
return Flux.error(e);
}
}
}