From 0c5ab90852d0076c6a3097e05d997f30350b890a Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Tue, 24 Nov 2020 22:07:24 +0100 Subject: [PATCH 01/35] work in progress --- .../main/java/sonia/scm/repository/Tag.java | 7 + .../sonia/scm/repository/TagCreatedEvent.java | 41 +++++ .../sonia/scm/repository/TagDeletedEvent.java | 40 +++++ .../scm/repository/api/TagCommandBuilder.java | 80 +++++++++ .../scm/repository/api/TagCreateRequest.java | 37 ++++ .../scm/repository/api/TagDeleteRequest.java | 36 ++++ .../sonia/scm/repository/spi/TagCommand.java | 39 ++++ .../java/sonia/scm/repository/GitUtil.java | 80 +++++++++ .../spi/GitRepositoryServiceProvider.java | 7 +- .../spi/GitRepositoryServiceResolver.java | 7 +- .../scm/repository/spi/GitTagCommand.java | 168 ++++++++++++++++++ .../scm/repository/spi/GitTagsCommand.java | 34 +++- .../repository/spi/GitBranchCommandTest.java | 1 - .../spi/GitRepositoryServiceProviderTest.java | 6 +- .../scm/repository/spi/GitTagCommandTest.java | 87 +++++++++ .../repository/spi/GitTagsCommandTest.java | 31 +++- .../repository/spi/scm-git-spi-test-tags.zip | Bin 44688 -> 46440 bytes 17 files changed, 688 insertions(+), 13 deletions(-) create mode 100644 scm-core/src/main/java/sonia/scm/repository/TagCreatedEvent.java create mode 100644 scm-core/src/main/java/sonia/scm/repository/TagDeletedEvent.java create mode 100644 scm-core/src/main/java/sonia/scm/repository/api/TagCommandBuilder.java create mode 100644 scm-core/src/main/java/sonia/scm/repository/api/TagCreateRequest.java create mode 100644 scm-core/src/main/java/sonia/scm/repository/api/TagDeleteRequest.java create mode 100644 scm-core/src/main/java/sonia/scm/repository/spi/TagCommand.java create mode 100644 scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java create mode 100644 scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagCommandTest.java diff --git a/scm-core/src/main/java/sonia/scm/repository/Tag.java b/scm-core/src/main/java/sonia/scm/repository/Tag.java index cdfac1c0e6..cd89b706b1 100644 --- a/scm-core/src/main/java/sonia/scm/repository/Tag.java +++ b/scm-core/src/main/java/sonia/scm/repository/Tag.java @@ -28,6 +28,8 @@ import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.ToString; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; /** @@ -44,6 +46,7 @@ public final class Tag { private final String name; private final String revision; private final Long date; + private final List signatures = new ArrayList<>(); /** * Constructs a new tag. @@ -89,4 +92,8 @@ public final class Tag { public Optional getDate() { return Optional.ofNullable(date); } + + public void addSignature(Signature signature) { + this.signatures.add(signature); + } } diff --git a/scm-core/src/main/java/sonia/scm/repository/TagCreatedEvent.java b/scm-core/src/main/java/sonia/scm/repository/TagCreatedEvent.java new file mode 100644 index 0000000000..d268394769 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/TagCreatedEvent.java @@ -0,0 +1,41 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package sonia.scm.repository; + +import lombok.Value; +import sonia.scm.event.Event; + +/** + * This event is fired when a new tag was created by the SCM-Manager. + * Warning: This event will not be fired if a new tag was pushed. + * @since 2.10.0 + */ +@Event +@Value +public class TagCreatedEvent { + Repository repository; + String revision; + String tagName; +} diff --git a/scm-core/src/main/java/sonia/scm/repository/TagDeletedEvent.java b/scm-core/src/main/java/sonia/scm/repository/TagDeletedEvent.java new file mode 100644 index 0000000000..13703c9223 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/TagDeletedEvent.java @@ -0,0 +1,40 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package sonia.scm.repository; + +import lombok.Value; +import sonia.scm.event.Event; + +/** + * This event is fired when a tag was deleted by the SCM-Manager. + * Warning: This event will not be fired if a tag was removed by a push of a git client. + * @since 2.10.0 + */ +@Event +@Value +public class TagDeletedEvent { + Repository repository; + String tagName; +} diff --git a/scm-core/src/main/java/sonia/scm/repository/api/TagCommandBuilder.java b/scm-core/src/main/java/sonia/scm/repository/api/TagCommandBuilder.java new file mode 100644 index 0000000000..ceb7f5ab79 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/api/TagCommandBuilder.java @@ -0,0 +1,80 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package sonia.scm.repository.api; + +import sonia.scm.event.ScmEventBus; +import sonia.scm.repository.Repository; +import sonia.scm.repository.Tag; +import sonia.scm.repository.TagCreatedEvent; +import sonia.scm.repository.TagDeletedEvent; +import sonia.scm.repository.spi.TagCommand; + +import java.io.IOException; + +public class TagCommandBuilder { + private final Repository repository; + private final TagCommand command; + private final ScmEventBus eventBus; + + public TagCommandBuilder(Repository repository, TagCommand command) { + this.repository = repository; + this.command = command; + this.eventBus = ScmEventBus.getInstance(); + } + + TagCreateCommandBuilder create() { + return new TagCreateCommandBuilder(); + } + + TagDeleteCommandBuilder delete() { + return new TagDeleteCommandBuilder(); + } + + private class TagCreateCommandBuilder { + private TagCreateRequest request = new TagCreateRequest(); + + void setRevision(String revision) { + request.setRevision(revision); + } + + void setName(String name) { + request.setName(name); + } + + Tag execute() throws IOException { + Tag tag = command.create(request); + eventBus.post(new TagCreatedEvent(repository, request.getRevision(), request.getName())); + return tag; + } + } + + private class TagDeleteCommandBuilder { + private TagDeleteRequest request = new TagDeleteRequest(); + void execute() throws IOException { + command.delete(request); + eventBus.post(new TagDeletedEvent(repository, request.getName())); + } + } +} diff --git a/scm-core/src/main/java/sonia/scm/repository/api/TagCreateRequest.java b/scm-core/src/main/java/sonia/scm/repository/api/TagCreateRequest.java new file mode 100644 index 0000000000..d74e0b642e --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/api/TagCreateRequest.java @@ -0,0 +1,37 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package sonia.scm.repository.api; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class TagCreateRequest { + private String revision; + private String name; +} diff --git a/scm-core/src/main/java/sonia/scm/repository/api/TagDeleteRequest.java b/scm-core/src/main/java/sonia/scm/repository/api/TagDeleteRequest.java new file mode 100644 index 0000000000..1e75aaf619 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/api/TagDeleteRequest.java @@ -0,0 +1,36 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package sonia.scm.repository.api; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class TagDeleteRequest { + private String name; +} diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/TagCommand.java b/scm-core/src/main/java/sonia/scm/repository/spi/TagCommand.java new file mode 100644 index 0000000000..66d6dd8386 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/spi/TagCommand.java @@ -0,0 +1,39 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package sonia.scm.repository.spi; + +import sonia.scm.repository.Tag; +import sonia.scm.repository.api.TagDeleteRequest; +import sonia.scm.repository.api.TagCreateRequest; + +import java.io.IOException; + +/** + * @since 2.11 + */ +public interface TagCommand { + Tag create(TagCreateRequest request) throws IOException; + void delete(TagDeleteRequest request) throws IOException; +} diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java index 6baa48111b..b1e0ec2b34 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java @@ -30,6 +30,7 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Strings; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; +import org.checkerframework.checker.nullness.Opt; import org.eclipse.jgit.api.FetchCommand; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; @@ -52,17 +53,23 @@ import org.eclipse.jgit.transport.RefSpec; import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.LfsFactory; +import org.eclipse.jgit.util.RawParseUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sonia.scm.ContextEntry; +import sonia.scm.security.GPG; +import sonia.scm.security.PublicKey; import sonia.scm.util.HttpUtil; import sonia.scm.util.Util; import sonia.scm.web.GitUserAgentProvider; import javax.servlet.http.HttpServletRequest; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.util.Arrays; +import java.util.Collections; import java.util.Map; import java.util.Optional; import java.util.concurrent.TimeUnit; @@ -451,6 +458,26 @@ public final class GitUtil return commit; } + public static RevTag getTag(org.eclipse.jgit.lib.Repository repository, + RevWalk revWalk, Ref ref) + throws IOException + { + RevTag tag = null; + ObjectId id = ref.getObjectId(); + + if (id != null) + { + if (revWalk == null) + { + revWalk = new RevWalk(repository); + } + + tag = revWalk.parseTag(id); + } + + return tag; + } + /** * Method description * @@ -683,6 +710,59 @@ public final class GitUtil return name; } + private static final byte[] GPG_HEADER = {'P', 'G', 'P'}; + + public static Optional getTagSignature(RevObject revObject, GPG gpg) { + if (revObject instanceof RevTag) { + RevTag tag = (RevTag) revObject; + byte[] raw = tag.getFullMessage().getBytes(); + + int start = RawParseUtils.headerStart(GPG_HEADER, raw, 0); + if (start < 0) { + return Optional.empty(); + } + + int end = RawParseUtils.headerEnd(raw, start); + byte[] signature = Arrays.copyOfRange(raw, start, end); + + String publicKeyId = gpg.findPublicKeyId(signature); + if (Strings.isNullOrEmpty(publicKeyId)) { + // key not found + return Optional.of(new Signature(publicKeyId, "gpg", SignatureStatus.NOT_FOUND, null, Collections.emptySet())); + } + + Optional publicKeyById = gpg.findPublicKey(publicKeyId); + if (!publicKeyById.isPresent()) { + // key not found + return Optional.of(new Signature(publicKeyId, "gpg", SignatureStatus.NOT_FOUND, null, Collections.emptySet())); + } + + PublicKey publicKey = publicKeyById.get(); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + byte[] headerPrefix = Arrays.copyOfRange(raw, 0, start - GPG_HEADER.length - 1); + baos.write(headerPrefix); + + byte[] headerSuffix = Arrays.copyOfRange(raw, end + 1, raw.length); + baos.write(headerSuffix); + } catch (IOException ex) { + // this will never happen, because we are writing into memory + throw new IllegalStateException("failed to write into memory", ex); + } + + boolean verified = publicKey.verify(baos.toByteArray(), signature); + return Optional.of(new Signature( + publicKeyId, + "gpg", + verified ? SignatureStatus.VERIFIED : SignatureStatus.INVALID, + publicKey.getOwner().orElse(null), + publicKey.getContacts() + )); + } + return Optional.empty(); + } + /** * Returns true if the request comes from a git client. * diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceProvider.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceProvider.java index fae69a47cf..d54320575d 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceProvider.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceProvider.java @@ -29,6 +29,7 @@ import com.google.inject.AbstractModule; import com.google.inject.Injector; import sonia.scm.repository.Feature; import sonia.scm.repository.api.Command; +import sonia.scm.security.GPG; import java.util.EnumSet; import java.util.Set; @@ -61,12 +62,14 @@ public class GitRepositoryServiceProvider extends RepositoryServiceProvider protected static final Set FEATURES = EnumSet.of(Feature.INCOMING_REVISION); private final GitContext context; + private final GPG gpg; private final Injector commandInjector; //~--- constructors --------------------------------------------------------- - GitRepositoryServiceProvider(Injector injector, GitContext context) { + GitRepositoryServiceProvider(Injector injector, GitContext context, GPG gpg) { this.context = context; + this.gpg = gpg; commandInjector = injector.createChildInjector(new AbstractModule() { @Override protected void configure() { @@ -142,7 +145,7 @@ public class GitRepositoryServiceProvider extends RepositoryServiceProvider @Override public TagsCommand getTagsCommand() { - return new GitTagsCommand(context); + return new GitTagsCommand(context, gpg); } @Override diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceResolver.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceResolver.java index 7ff06dd140..1eb9b55e9b 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceResolver.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceResolver.java @@ -31,6 +31,7 @@ import com.google.inject.Injector; import sonia.scm.plugin.Extension; import sonia.scm.repository.GitRepositoryHandler; import sonia.scm.repository.Repository; +import sonia.scm.security.GPG; /** * @@ -41,17 +42,19 @@ public class GitRepositoryServiceResolver implements RepositoryServiceResolver { private final Injector injector; private final GitContextFactory contextFactory; + private final GPG gpg; @Inject - public GitRepositoryServiceResolver(Injector injector, GitContextFactory contextFactory) { + public GitRepositoryServiceResolver(Injector injector, GitContextFactory contextFactory, GPG gpg) { this.injector = injector; this.contextFactory = contextFactory; + this.gpg = gpg; } @Override public GitRepositoryServiceProvider resolve(Repository repository) { if (GitRepositoryHandler.TYPE_NAME.equalsIgnoreCase(repository.getType())) { - return new GitRepositoryServiceProvider(injector, contextFactory.create(repository)); + return new GitRepositoryServiceProvider(injector, contextFactory.create(repository), gpg); } return null; } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java new file mode 100644 index 0000000000..31fb9d6249 --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java @@ -0,0 +1,168 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package sonia.scm.repository.spi; + +import com.google.common.base.Strings; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.PersonIdent; +import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.revwalk.RevObject; +import org.eclipse.jgit.revwalk.RevTag; +import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.util.RawParseUtils; +import sonia.scm.repository.GitUtil; +import sonia.scm.repository.InternalRepositoryException; +import sonia.scm.repository.Signature; +import sonia.scm.repository.SignatureStatus; +import sonia.scm.repository.Tag; +import sonia.scm.repository.api.TagDeleteRequest; +import sonia.scm.repository.api.TagCreateRequest; +import sonia.scm.security.GPG; +import sonia.scm.security.PublicKey; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.Optional; + +public class GitTagCommand extends AbstractGitCommand implements TagCommand { + private final GPG gpg; + + GitTagCommand(GitContext context, GPG gpg) { + super(context); + this.gpg = gpg; + } + + @Override + public Tag create(TagCreateRequest request) { + try (Git git = new Git(context.open())) { + Tag tag; + String revision = request.getRevision(); + + RevObject revObject = null; + Long tagTime = null; + + if (!Strings.isNullOrEmpty(revision)) { + ObjectId id = git.getRepository().resolve(revision); + + try (RevWalk walk = new RevWalk(git.getRepository())) { + revObject = walk.parseAny(id); + tagTime = GitUtil.getTagTime(walk, id); + } + } + + Ref ref; + + if (revObject != null) { + ref = + git.tag() + .setObjectId(revObject) + .setTagger(new PersonIdent("SCM-Manager", "noreply@scm-manager.org")) + .setName(request.getName()) + .call(); + } else { + throw new InternalRepositoryException(repository, "could not create tag because revision does not exist"); + } + + ObjectId objectId; + if (ref.isPeeled()) { + objectId = ref.getPeeledObjectId(); + } else { + objectId = ref.getObjectId(); + } + tag = new Tag(request.getName(), objectId.toString(), tagTime); + + try (RevWalk walk = new RevWalk(git.getRepository())) { + revObject = walk.parseTag(objectId); + tag.addSignature(getTagSignature((RevTag) revObject)); + } + + return tag; + } catch (IOException | GitAPIException ex) { + throw new InternalRepositoryException(repository, "could not create tag " + request.getName(), ex); + } + } + + @Override + public void delete(TagDeleteRequest request) { + try (Git git = new Git(context.open())) { + git.tagDelete().setTags(request.getName()).call(); + } catch (GitAPIException | IOException e) { + throw new InternalRepositoryException(repository, "could not delete tag", e); + } + } + + private static final byte[] GPG_HEADER = {'g', 'p', 'g', 's', 'i', 'g'}; + + private Signature getTagSignature(RevTag tag) { + byte[] raw = tag.getFullMessage().getBytes(); + + int start = RawParseUtils.headerStart(GPG_HEADER, raw, 0); + if (start < 0) { + return null; + } + + int end = RawParseUtils.headerEnd(raw, start); + byte[] signature = Arrays.copyOfRange(raw, start, end); + + String publicKeyId = gpg.findPublicKeyId(signature); + if (Strings.isNullOrEmpty(publicKeyId)) { + // key not found + return new Signature(publicKeyId, "gpg", SignatureStatus.NOT_FOUND, null, Collections.emptySet()); + } + + Optional publicKeyById = gpg.findPublicKey(publicKeyId); + if (!publicKeyById.isPresent()) { + // key not found + return new Signature(publicKeyId, "gpg", SignatureStatus.NOT_FOUND, null, Collections.emptySet()); + } + + PublicKey publicKey = publicKeyById.get(); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + byte[] headerPrefix = Arrays.copyOfRange(raw, 0, start - GPG_HEADER.length - 1); + baos.write(headerPrefix); + + byte[] headerSuffix = Arrays.copyOfRange(raw, end + 1, raw.length); + baos.write(headerSuffix); + } catch (IOException ex) { + // this will never happen, because we are writing into memory + throw new IllegalStateException("failed to write into memory", ex); + } + + boolean verified = publicKey.verify(baos.toByteArray(), signature); + return new Signature( + publicKeyId, + "gpg", + verified ? SignatureStatus.VERIFIED : SignatureStatus.INVALID, + publicKey.getOwner().orElse(null), + publicKey.getContacts() + ); + } +} diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagsCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagsCommand.java index 60b1105547..06e500ce4c 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagsCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagsCommand.java @@ -30,17 +30,22 @@ import com.google.common.base.Function; import com.google.common.collect.Lists; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.revwalk.RevObject; +import org.eclipse.jgit.revwalk.RevTag; import org.eclipse.jgit.revwalk.RevWalk; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sonia.scm.repository.GitUtil; import sonia.scm.repository.InternalRepositoryException; +import sonia.scm.repository.Signature; import sonia.scm.repository.Tag; +import sonia.scm.security.GPG; import java.io.IOException; import java.util.List; +import java.util.Optional; //~--- JDK imports ------------------------------------------------------------ @@ -49,20 +54,23 @@ import java.util.List; */ public class GitTagsCommand extends AbstractGitCommand implements TagsCommand { + private final GPG gpg; + /** * Constructs ... * * @param context */ - public GitTagsCommand(GitContext context) { + public GitTagsCommand(GitContext context, GPG gpp) { super(context); + this.gpg = gpp; } //~--- get methods ---------------------------------------------------------- @Override public List getTags() throws IOException { - List tags = null; + List tags; RevWalk revWalk = null; @@ -74,7 +82,7 @@ public class GitTagsCommand extends AbstractGitCommand implements TagsCommand { List tagList = git.tagList().call(); tags = Lists.transform(tagList, - new TransformFuntion(git.getRepository(), revWalk)); + new TransformFuntion(git.getRepository(), revWalk, gpg, git)); } catch (GitAPIException ex) { throw new InternalRepositoryException(repository, "could not read tags from repository", ex); } finally { @@ -109,9 +117,13 @@ public class GitTagsCommand extends AbstractGitCommand implements TagsCommand { * @param revWalk */ public TransformFuntion(org.eclipse.jgit.lib.Repository repository, - RevWalk revWalk) { + RevWalk revWalk, + GPG gpg, + Git git) { this.repository = repository; this.revWalk = revWalk; + this.gpg = gpg; + this.git = git; } //~--- methods ------------------------------------------------------------ @@ -133,6 +145,18 @@ public class GitTagsCommand extends AbstractGitCommand implements TagsCommand { String name = GitUtil.getTagName(ref); tag = new Tag(name, revObject.getId().name(), GitUtil.getTagTime(revWalk, ref.getObjectId())); + + try { + RevTag revTag = GitUtil.getTag(repository, revWalk, ref); + + final Optional tagSignature = GitUtil.getTagSignature(revTag, gpg); + if (tagSignature.isPresent()) { + tag.addSignature(tagSignature.get()); + } + } catch (IncorrectObjectTypeException e) { + // Ignore, this must be a lightweight tag + } + } } catch (IOException ex) { @@ -153,5 +177,7 @@ public class GitTagsCommand extends AbstractGitCommand implements TagsCommand { * Field description */ private RevWalk revWalk; + private final GPG gpg; + private final Git git; } } diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBranchCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBranchCommandTest.java index 0df9332cfe..1fba957da5 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBranchCommandTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBranchCommandTest.java @@ -32,7 +32,6 @@ import org.mockito.invocation.InvocationOnMock; import org.mockito.junit.MockitoJUnitRunner; import sonia.scm.event.ScmEventBus; import sonia.scm.repository.Branch; -import sonia.scm.repository.BranchCreatedEvent; import sonia.scm.repository.PostReceiveRepositoryHookEvent; import sonia.scm.repository.PreReceiveRepositoryHookEvent; import sonia.scm.repository.api.BranchRequest; diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitRepositoryServiceProviderTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitRepositoryServiceProviderTest.java index aac6eaef49..4878a8f4b8 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitRepositoryServiceProviderTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitRepositoryServiceProviderTest.java @@ -32,6 +32,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import sonia.scm.repository.GitRepositoryHandler; +import sonia.scm.security.GPG; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.verify; @@ -45,6 +46,9 @@ class GitRepositoryServiceProviderTest { @Mock private GitContext context; + @Mock + private GPG gpg; + @Test void shouldCreatePushCommand() { GitRepositoryServiceProvider provider = createProvider(); @@ -59,7 +63,7 @@ class GitRepositoryServiceProviderTest { } private GitRepositoryServiceProvider createProvider() { - return new GitRepositoryServiceProvider(createParentInjector(), context); + return new GitRepositoryServiceProvider(createParentInjector(), context, gpg); } private Injector createParentInjector() { diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagCommandTest.java new file mode 100644 index 0000000000..7c883cc087 --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagCommandTest.java @@ -0,0 +1,87 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package sonia.scm.repository.spi; + +import org.eclipse.jgit.lib.GpgSigner; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import sonia.scm.repository.GitTestHelper; +import sonia.scm.repository.Tag; +import sonia.scm.repository.api.TagDeleteRequest; +import sonia.scm.repository.api.TagCreateRequest; +import sonia.scm.security.GPG; + +import java.io.IOException; +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(MockitoJUnitRunner.class) +public class GitTagCommandTest extends AbstractGitCommandTestBase { + + @Mock + private GPG gpg; + + @Before + public void setSigner() { + GpgSigner.setDefault(new GitTestHelper.SimpleGpgSigner()); + } + + @Test + public void shouldCreateATag() throws IOException { + createCommand().create(new TagCreateRequest("592d797cd36432e591416e8b2b98154f4f163411", "newtag")); + Optional tag = findTag(createContext(), "newtag"); + assertThat(tag).isNotEmpty(); + } + + @Test + public void shouldDeleteATag() throws IOException { + final GitContext context = createContext(); + Optional tag = findTag(context, "test-tag"); + assertThat(tag).isNotEmpty(); + + createCommand().delete(new TagDeleteRequest("test-tag")); + + tag = findTag(context, "test-tag"); + assertThat(tag).isEmpty(); + } + + private GitTagCommand createCommand() { + return new GitTagCommand(createContext(), gpg); + } + + private List readTags(GitContext context) throws IOException { + return new GitTagsCommand(context, gpg).getTags(); + } + + private Optional findTag(GitContext context, String name) throws IOException { + List branches = readTags(context); + return branches.stream().filter(b -> name.equals(b.getName())).findFirst(); + } +} diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagsCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagsCommandTest.java index 9112aa3133..27711d8b55 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagsCommandTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagsCommandTest.java @@ -29,14 +29,22 @@ import com.github.sdorra.shiro.SubjectAware; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.mockito.ArgumentMatchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; import sonia.scm.repository.Tag; +import sonia.scm.security.GPG; import java.io.IOException; import java.util.List; +import static org.assertj.core.api.Assertions.anyOf; import static org.assertj.core.api.Assertions.assertThat; @SubjectAware(configuration = "classpath:sonia/scm/configuration/shiro.ini", username = "admin", password = "secret") +@RunWith(MockitoJUnitRunner.class) public class GitTagsCommandTest extends AbstractGitCommandTestBase { @Rule @@ -48,24 +56,41 @@ public class GitTagsCommandTest extends AbstractGitCommandTestBase { @Rule public ShiroRule shiro = new ShiroRule(); + @Mock + GPG gpg; + @Test public void shouldGetDatesCorrectly() throws IOException { final GitContext gitContext = createContext(); - final GitTagsCommand tagsCommand = new GitTagsCommand(gitContext); + final GitTagsCommand tagsCommand = new GitTagsCommand(gitContext, gpg); final List tags = tagsCommand.getTags(); - assertThat(tags).hasSize(2); + assertThat(tags).hasSize(3); Tag annotatedTag = tags.get(0); assertThat(annotatedTag.getName()).isEqualTo("1.0.0"); assertThat(annotatedTag.getDate()).contains(1598348105000L); // Annotated - Take tag date assertThat(annotatedTag.getRevision()).isEqualTo("fcd0ef1831e4002ac43ea539f4094334c79ea9ec"); - Tag lightweightTag = tags.get(1); + Tag lightweightTag = tags.get(2); assertThat(lightweightTag.getName()).isEqualTo("test-tag"); assertThat(lightweightTag.getDate()).contains(1339416344000L); // Lightweight - Take commit date assertThat(lightweightTag.getRevision()).isEqualTo("86a6645eceefe8b9a247db5eb16e3d89a7e6e6d1"); } + @Test + public void shouldGetSignatures() throws IOException { + Mockito.when(gpg.findPublicKeyId(ArgumentMatchers.any())).thenReturn("2BA27721F113C005CC16F06BAE63EFBC49F140CF"); + + final GitContext gitContext = createContext(); + final GitTagsCommand tagsCommand = new GitTagsCommand(gitContext, gpg); + final List tags = tagsCommand.getTags(); + + assertThat(tags).hasSize(3); + + Tag signedTag = tags.get(1); + assertThat(signedTag.getSignatures()).isNotEmpty(); + } + @Override protected String getZippedRepositoryResource() { return "sonia/scm/repository/spi/scm-git-spi-test-tags.zip"; diff --git a/scm-plugins/scm-git-plugin/src/test/resources/sonia/scm/repository/spi/scm-git-spi-test-tags.zip b/scm-plugins/scm-git-plugin/src/test/resources/sonia/scm/repository/spi/scm-git-spi-test-tags.zip index 05b2f0f7cab59ed00cab488ed71e36611e5f6983..20f8169dededa874b4f141ab0a9f5687c4927f73 100644 GIT binary patch delta 6967 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 delta 5402 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 E2T Date: Wed, 25 Nov 2020 11:29:06 +0100 Subject: [PATCH 02/35] implement hg tag command and add rest endpoints --- .../sonia/scm/repository/api/Command.java | 7 +- .../scm/repository/api/RepositoryService.java | 12 ++ .../scm/repository/api/TagCommandBuilder.java | 24 ++-- .../spi/RepositoryServiceProvider.java | 11 ++ .../main/java/sonia/scm/web/VndMediaType.java | 1 + .../spi/GitRepositoryServiceProvider.java | 5 + .../spi/HgRepositoryServiceProvider.java | 5 + .../scm/repository/spi/HgTagCommand.java | 61 ++++++++++ .../scm/repository/spi/HgTagCommandTest.java | 53 +++++++++ .../sonia/scm/api/v2/resources/TagDto.java | 3 + .../scm/api/v2/resources/TagRequestDto.java | 45 ++++++++ .../scm/api/v2/resources/TagRootResource.java | 105 +++++++++++++++++- .../api/v2/resources/TagToTagDtoMapper.java | 1 + .../v2/resources/TagToTagDtoMapperTest.java | 17 +++ 14 files changed, 339 insertions(+), 11 deletions(-) create mode 100644 scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgTagCommand.java create mode 100644 scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgTagCommandTest.java create mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRequestDto.java diff --git a/scm-core/src/main/java/sonia/scm/repository/api/Command.java b/scm-core/src/main/java/sonia/scm/repository/api/Command.java index 4a2d3e77ae..e96233a5f3 100644 --- a/scm-core/src/main/java/sonia/scm/repository/api/Command.java +++ b/scm-core/src/main/java/sonia/scm/repository/api/Command.java @@ -62,5 +62,10 @@ public enum Command /** * @since 2.10.0 */ - LOOKUP; + LOOKUP, + + /** + * @since 2.11.0 + */ + TAG; } diff --git a/scm-core/src/main/java/sonia/scm/repository/api/RepositoryService.java b/scm-core/src/main/java/sonia/scm/repository/api/RepositoryService.java index 15c2f3f523..c1b1321419 100644 --- a/scm-core/src/main/java/sonia/scm/repository/api/RepositoryService.java +++ b/scm-core/src/main/java/sonia/scm/repository/api/RepositoryService.java @@ -377,6 +377,18 @@ public final class RepositoryService implements Closeable { repository); } + /** + * The tag command allows the management of repository tags. + * + * @return instance of {@link TagCommandBuilder} + * + * @throws CommandNotSupportedException if the command is not supported + * by the implementation of the repository service provider. + */ + public TagCommandBuilder getTagCommand() { + return new TagCommandBuilder(repository, provider.getTagCommand()); + } + /** * The unbundle command restores a repository from the given bundle. * diff --git a/scm-core/src/main/java/sonia/scm/repository/api/TagCommandBuilder.java b/scm-core/src/main/java/sonia/scm/repository/api/TagCommandBuilder.java index ceb7f5ab79..ca2a0f176f 100644 --- a/scm-core/src/main/java/sonia/scm/repository/api/TagCommandBuilder.java +++ b/scm-core/src/main/java/sonia/scm/repository/api/TagCommandBuilder.java @@ -44,35 +44,43 @@ public class TagCommandBuilder { this.eventBus = ScmEventBus.getInstance(); } - TagCreateCommandBuilder create() { + public TagCreateCommandBuilder create() { return new TagCreateCommandBuilder(); } - TagDeleteCommandBuilder delete() { + public TagDeleteCommandBuilder delete() { return new TagDeleteCommandBuilder(); } - private class TagCreateCommandBuilder { + public class TagCreateCommandBuilder { private TagCreateRequest request = new TagCreateRequest(); - void setRevision(String revision) { + public TagCreateCommandBuilder setRevision(String revision) { request.setRevision(revision); + return this; } - void setName(String name) { + public TagCreateCommandBuilder setName(String name) { request.setName(name); + return this; } - Tag execute() throws IOException { + public Tag execute() throws IOException { Tag tag = command.create(request); eventBus.post(new TagCreatedEvent(repository, request.getRevision(), request.getName())); return tag; } } - private class TagDeleteCommandBuilder { + public class TagDeleteCommandBuilder { private TagDeleteRequest request = new TagDeleteRequest(); - void execute() throws IOException { + + public TagDeleteCommandBuilder setName(String name) { + request.setName(name); + return this; + } + + public void execute() throws IOException { command.delete(request); eventBus.post(new TagDeletedEvent(repository, request.getName())); } diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceProvider.java b/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceProvider.java index 091c9b46b3..62548280e7 100644 --- a/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceProvider.java +++ b/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceProvider.java @@ -246,6 +246,17 @@ public abstract class RepositoryServiceProvider implements Closeable throw new CommandNotSupportedException(Command.TAGS); } + /** + * Method description + * + * + * @return + */ + public TagCommand getTagCommand() + { + throw new CommandNotSupportedException(Command.TAGS); + } + /** * Method description * diff --git a/scm-core/src/main/java/sonia/scm/web/VndMediaType.java b/scm-core/src/main/java/sonia/scm/web/VndMediaType.java index b3dbcb5b6e..dc5dd4702b 100644 --- a/scm-core/src/main/java/sonia/scm/web/VndMediaType.java +++ b/scm-core/src/main/java/sonia/scm/web/VndMediaType.java @@ -51,6 +51,7 @@ public class VndMediaType { public static final String MODIFICATIONS = PREFIX + "modifications" + SUFFIX; public static final String TAG = PREFIX + "tag" + SUFFIX; public static final String TAG_COLLECTION = PREFIX + "tagCollection" + SUFFIX; + public static final String TAG_REQUEST = PREFIX + "tagRequest" + SUFFIX; public static final String BRANCH = PREFIX + "branch" + SUFFIX; public static final String BRANCH_REQUEST = PREFIX + "branchRequest" + SUFFIX; public static final String DIFF = PLAIN_TEXT_PREFIX + "diff" + PLAIN_TEXT_SUFFIX; diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceProvider.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceProvider.java index d54320575d..a6f2145611 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceProvider.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceProvider.java @@ -148,6 +148,11 @@ public class GitRepositoryServiceProvider extends RepositoryServiceProvider return new GitTagsCommand(context, gpg); } + @Override + public TagCommand getTagCommand() { + return new GitTagCommand(context, gpg); + } + @Override public MergeCommand getMergeCommand() { return commandInjector.getInstance(GitMergeCommand.class); diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceProvider.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceProvider.java index ce64b06982..b37918d4c1 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceProvider.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceProvider.java @@ -271,6 +271,11 @@ public class HgRepositoryServiceProvider extends RepositoryServiceProvider return new HgTagsCommand(context); } + @Override + public TagCommand getTagCommand() { + return new HgTagCommand(context); + } + //~--- fields --------------------------------------------------------------- /** Field description */ diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgTagCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgTagCommand.java new file mode 100644 index 0000000000..6d738de6b8 --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgTagCommand.java @@ -0,0 +1,61 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package sonia.scm.repository.spi; + +import com.aragost.javahg.Repository; +import com.google.common.base.Strings; +import sonia.scm.repository.Tag; +import sonia.scm.repository.api.TagCreateRequest; +import sonia.scm.repository.api.TagDeleteRequest; + +public class HgTagCommand extends AbstractCommand implements TagCommand { + + public HgTagCommand(HgCommandContext context) { + super(context); + } + + @Override + public Tag create(TagCreateRequest request) { + Repository repository = getContext().open(); + String rev = request.getRevision(); + if (Strings.isNullOrEmpty(rev)) { + rev = repository.tip().getNode(); + } + com.aragost.javahg.commands.TagCommand.on(repository) + .rev(rev) + .user("SCM-Manager") + .execute(request.getName()); + return new Tag(request.getName(), rev); + } + + @Override + public void delete(TagDeleteRequest request) { + Repository repository = getContext().open(); + com.aragost.javahg.commands.TagCommand.on(repository) + .user("SCM-Manager") + .remove() + .execute(request.getName()); + } +} diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgTagCommandTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgTagCommandTest.java new file mode 100644 index 0000000000..e1b7eff2f2 --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgTagCommandTest.java @@ -0,0 +1,53 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package sonia.scm.repository.spi; + +import org.junit.Test; +import sonia.scm.repository.Tag; +import sonia.scm.repository.api.TagCreateRequest; +import sonia.scm.repository.api.TagDeleteRequest; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class HgTagCommandTest extends AbstractHgCommandTestBase { + + @Test + public void shouldCreateAndDeleteTagCorrectly() { + // Create + new HgTagCommand(cmdContext).create(new TagCreateRequest("79b6baf49711", "newtag")); + List tags = new HgTagsCommand(cmdContext).getTags(); + assertThat(tags).hasSize(2); + final Tag newTag = tags.get(1); + assertThat(newTag.getName()).isEqualTo("newtag"); + + // Delete + new HgTagCommand(cmdContext).delete(new TagDeleteRequest("newtag")); + tags = new HgTagsCommand(cmdContext).getTags(); + assertThat(tags).hasSize(1); + } + +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagDto.java index 7d4fd6dada..9100090b36 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagDto.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagDto.java @@ -33,6 +33,7 @@ import lombok.NoArgsConstructor; import lombok.Setter; import java.time.Instant; +import java.util.List; @Getter @Setter @@ -46,6 +47,8 @@ public class TagDto extends HalRepresentation { @JsonInclude(JsonInclude.Include.NON_NULL) private Instant date; + private List signatures; + TagDto(Links links, Embedded embedded) { super(links, embedded); } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRequestDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRequestDto.java new file mode 100644 index 0000000000..5d43914552 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRequestDto.java @@ -0,0 +1,45 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package sonia.scm.api.v2.resources; + +import lombok.Getter; +import lombok.Setter; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotEmpty; + +@Getter +@Setter +public class TagRequestDto { + // TODO: Validate revision via regex + @NotEmpty + @Length(min = 1, max = 100) + private String revision; + + // TODO: Validate name via regex + @NotEmpty + @Length(min = 1, max = 100) + private String name; +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRootResource.java index a0f9fe0e7c..b46656a02d 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRootResource.java @@ -21,14 +21,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + package sonia.scm.api.v2.resources; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.headers.Header; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import sonia.scm.NotFoundException; +import sonia.scm.repository.Branch; import sonia.scm.repository.NamespaceAndName; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryPermissions; @@ -36,16 +38,22 @@ import sonia.scm.repository.Tag; import sonia.scm.repository.Tags; import sonia.scm.repository.api.RepositoryService; import sonia.scm.repository.api.RepositoryServiceFactory; +import sonia.scm.repository.api.TagCommandBuilder; import sonia.scm.web.VndMediaType; import javax.inject.Inject; +import javax.validation.Valid; +import javax.ws.rs.DELETE; import javax.ws.rs.GET; +import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Response; import java.io.IOException; +import java.net.URI; +import static sonia.scm.AlreadyExistsException.alreadyExists; import static sonia.scm.ContextEntry.ContextBuilder.entity; import static sonia.scm.NotFoundException.notFound; @@ -54,14 +62,17 @@ public class TagRootResource { private final RepositoryServiceFactory serviceFactory; private final TagCollectionToDtoMapper tagCollectionToDtoMapper; private final TagToTagDtoMapper tagToTagDtoMapper; + private final ResourceLinks resourceLinks; @Inject public TagRootResource(RepositoryServiceFactory serviceFactory, TagCollectionToDtoMapper tagCollectionToDtoMapper, - TagToTagDtoMapper tagToTagDtoMapper) { + TagToTagDtoMapper tagToTagDtoMapper, + ResourceLinks resourceLinks) { this.serviceFactory = serviceFactory; this.tagCollectionToDtoMapper = tagCollectionToDtoMapper; this.tagToTagDtoMapper = tagToTagDtoMapper; + this.resourceLinks = resourceLinks; } @GET @@ -98,6 +109,53 @@ public class TagRootResource { } } + @POST + @Path("") + @Produces(VndMediaType.TAG_REQUEST) + @Operation(summary = "Create tag", description = "Creates a new tag and returns it", tags = "Repository") + @ApiResponse( + responseCode = "201", + description = "create success", + headers = @Header( + name = "Location", + description = "uri to the created tag", + schema = @Schema(type = "string") + ) + ) + @ApiResponse(responseCode = "401", description = "not authenticated / invalid credentials") + @ApiResponse(responseCode = "403", description = "not authorized, the current user has no privileges to read the tags") + @ApiResponse( + responseCode = "404", + description = "not found, no tag with the specified name available in the repository", + content = @Content( + mediaType = VndMediaType.ERROR_TYPE, + schema = @Schema(implementation = ErrorDto.class) + )) + @ApiResponse( + responseCode = "500", + description = "internal server error", + content = @Content( + mediaType = VndMediaType.ERROR_TYPE, + schema = @Schema(implementation = ErrorDto.class) + )) + public Response create(@PathParam("namespace") String namespace, @PathParam("name") String name, @Valid TagRequestDto tagRequest) throws IOException { + NamespaceAndName namespaceAndName = new NamespaceAndName(namespace, name); + String revision = tagRequest.getRevision(); + String tagName = tagRequest.getName(); + try (RepositoryService repositoryService = serviceFactory.create(namespaceAndName)) { + if (tagExists(tagName, repositoryService)) { + throw alreadyExists(entity(Tag.class, tagName).in(Repository.class, namespace + "/" + name)); + } + Repository repository = repositoryService.getRepository(); + RepositoryPermissions.push(repository).check(); + TagCommandBuilder tagCommandBuilder = repositoryService.getTagCommand(); + final Tag newTag = tagCommandBuilder.create() + .setRevision(revision) + .setName(tagName) + .execute(); + return Response.created(URI.create(resourceLinks.tag().self(namespace, name, newTag.getName()))).build(); + } + } @GET @Path("{tagName}") @@ -145,6 +203,45 @@ public class TagRootResource { } } + @DELETE + @Path("{tagName}") + @Produces(VndMediaType.TAG) + @Operation(summary = "Delete tag", description = "Deletes the tag provided in the path", tags = "Repository") + @ApiResponse( + responseCode = "200", + description = "success" + ) + @ApiResponse(responseCode = "401", description = "not authenticated / invalid credentials") + @ApiResponse(responseCode = "403", description = "not authorized, the current user has no privileges to read the tags") + @ApiResponse( + responseCode = "404", + description = "not found, no tag with the specified name available in the repository", + content = @Content( + mediaType = VndMediaType.ERROR_TYPE, + schema = @Schema(implementation = ErrorDto.class) + )) + @ApiResponse( + responseCode = "500", + description = "internal server error", + content = @Content( + mediaType = VndMediaType.ERROR_TYPE, + schema = @Schema(implementation = ErrorDto.class) + )) + public Response delete(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("tagName") String tagName) { + NamespaceAndName namespaceAndName = new NamespaceAndName(namespace, name); + try (RepositoryService repositoryService = serviceFactory.create(namespaceAndName)) { + RepositoryPermissions.modify(repositoryService.getRepository()).check(); + + if (tagExists(tagName, repositoryService)) { + repositoryService.getTagCommand().delete() + .setName(tagName) + .execute(); + } + + return Response.noContent().build(); + } + } + private NotFoundException createNotFoundException(String namespace, String name, String tagName) { return notFound(entity("Tag", tagName).in("Repository", namespace + "/" + name)); } @@ -155,5 +252,9 @@ public class TagRootResource { return repositoryService.getTagsCommand().getTags(); } + private boolean tagExists(String tagName, RepositoryService repositoryService) throws IOException { + return getTags(repositoryService) + .getTagByName(tagName) != null; + } } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java index 940b33dd05..78350ab114 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java @@ -52,6 +52,7 @@ public abstract class TagToTagDtoMapper extends HalAppenderMapper { @Mapping(target = "date", source = "date", qualifiedByName = "mapDate") @Mapping(target = "attributes", ignore = true) // We do not map HAL attributes + @Mapping(target = "signatures") public abstract TagDto map(Tag tag, @Context NamespaceAndName namespaceAndName); @ObjectFactory diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/TagToTagDtoMapperTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/TagToTagDtoMapperTest.java index ebf71f6b85..efb5dcee4e 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/TagToTagDtoMapperTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/TagToTagDtoMapperTest.java @@ -29,10 +29,13 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.junit.jupiter.MockitoExtension; import sonia.scm.repository.NamespaceAndName; +import sonia.scm.repository.Signature; +import sonia.scm.repository.SignatureStatus; import sonia.scm.repository.Tag; import java.net.URI; import java.time.Instant; +import java.util.Collections; import static org.assertj.core.api.Assertions.assertThat; @@ -66,4 +69,18 @@ class TagToTagDtoMapperTest { assertThat(dto.getDate()).isEqualTo(Instant.ofEpochMilli(now)); } + @Test + void shouldContainSignatureArray() { + TagDto dto = mapper.map(new Tag("1.0.0", "42"), new NamespaceAndName("hitchhiker", "hog")); + assertThat(dto.getSignatures()).isNotNull(); + } + + @Test + void shouldMapSignatures() { + final Tag tag = new Tag("1.0.0", "42"); + tag.addSignature(new Signature("29v391239v", "gpg", SignatureStatus.VERIFIED, "me", Collections.emptySet())); + TagDto dto = mapper.map(tag, new NamespaceAndName("hitchhiker", "hog")); + assertThat(dto.getSignatures()).isNotEmpty(); + } + } From 84ea15974166da136e4528ffa386bc2dbda8f660 Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Wed, 25 Nov 2020 12:08:51 +0100 Subject: [PATCH 03/35] add unit test for rest endpoints --- .../scm/api/v2/resources/TagRootResource.java | 2 + .../api/v2/resources/TagRootResourceTest.java | 135 +++++++++++++++++- 2 files changed, 134 insertions(+), 3 deletions(-) diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRootResource.java index b46656a02d..0f5cb2c450 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRootResource.java @@ -239,6 +239,8 @@ public class TagRootResource { } return Response.noContent().build(); + } catch (IOException e) { + return Response.serverError().build(); } } diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/TagRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/TagRootResourceTest.java index 726cbc89e4..7655dd7c9b 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/TagRootResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/TagRootResourceTest.java @@ -24,8 +24,8 @@ package sonia.scm.api.v2.resources; -import com.google.inject.util.Providers; import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.authz.AuthorizationException; import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.support.SubjectThreadState; import org.apache.shiro.util.ThreadContext; @@ -46,17 +46,24 @@ import sonia.scm.repository.Tag; import sonia.scm.repository.Tags; import sonia.scm.repository.api.RepositoryService; import sonia.scm.repository.api.RepositoryServiceFactory; +import sonia.scm.repository.api.TagCommandBuilder; import sonia.scm.repository.api.TagsCommandBuilder; import sonia.scm.web.RestDispatcher; import sonia.scm.web.VndMediaType; +import java.io.IOException; import java.net.URI; +import java.net.URISyntaxException; +import java.util.Collections; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @Slf4j @@ -79,6 +86,12 @@ public class TagRootResourceTest extends RepositoryTestBase { @Mock private TagsCommandBuilder tagsCommandBuilder; + @Mock + private TagCommandBuilder tagCommandBuilder; + @Mock + private TagCommandBuilder.TagCreateCommandBuilder tagCreateCommandBuilder; + @Mock + private TagCommandBuilder.TagDeleteCommandBuilder tagDeleteCommandBuilder; private TagCollectionToDtoMapper tagCollectionToDtoMapper; @InjectMocks @@ -89,17 +102,21 @@ public class TagRootResourceTest extends RepositoryTestBase { @Before - public void prepareEnvironment() throws Exception { + public void prepareEnvironment() { tagCollectionToDtoMapper = new TagCollectionToDtoMapper(resourceLinks, tagToTagDtoMapper); - tagRootResource = new TagRootResource(serviceFactory, tagCollectionToDtoMapper, tagToTagDtoMapper); + tagRootResource = new TagRootResource(serviceFactory, tagCollectionToDtoMapper, tagToTagDtoMapper, resourceLinks); dispatcher.addSingletonResource(getRepositoryRootResource()); when(serviceFactory.create(new NamespaceAndName("space", "repo"))).thenReturn(repositoryService); when(serviceFactory.create(any(Repository.class))).thenReturn(repositoryService); when(repositoryService.getRepository()).thenReturn(new Repository("repoId", "git", "space", "repo")); when(repositoryService.getTagsCommand()).thenReturn(tagsCommandBuilder); + when(repositoryService.getTagCommand()).thenReturn(tagCommandBuilder); subjectThreadState.bind(); ThreadContext.bind(subject); when(subject.isPermitted(any(String.class))).thenReturn(true); + when(tagCreateCommandBuilder.setName(any())).thenReturn(tagCreateCommandBuilder); + when(tagCreateCommandBuilder.setRevision(any())).thenReturn(tagCreateCommandBuilder); + when(tagDeleteCommandBuilder.setName(any())).thenReturn(tagDeleteCommandBuilder); } @After @@ -211,4 +228,116 @@ public class TagRootResourceTest extends RepositoryTestBase { assertTrue(response.getContentAsString().contains(String.format("\"name\":\"%s\"", tag2))); assertTrue(response.getContentAsString().contains(String.format("\"revision\":\"%s\"", revision2))); } + + @Test + public void shouldCreateTag() throws URISyntaxException, IOException { + Tags tags = new Tags(); + tags.setTags(Lists.emptyList()); + when(tagsCommandBuilder.getTags()).thenReturn(tags); + when(tagCommandBuilder.create()).thenReturn(tagCreateCommandBuilder); + when(tagCreateCommandBuilder.execute()).thenReturn(new Tag("newtag", "592d797cd36432e591416e8b2b98154f4f163411")); + MockHttpRequest request = MockHttpRequest + .post(TAG_URL) + .content("{\"name\": \"newtag\",\"revision\":\"592d797cd36432e591416e8b2b98154f4f163411\"}".getBytes()) + .contentType(VndMediaType.TAG_REQUEST); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(201, response.getStatus()); + assertEquals( + URI.create("/v2/repositories/space/repo/tags/newtag"), + response.getOutputHeaders().getFirst("Location")); + } + + @Test + public void shouldNotCreateTagIfNotPermitted() throws IOException, URISyntaxException { + doThrow(AuthorizationException.class).when(subject).checkPermission("repository:push:repoId"); + Tags tags = new Tags(); + tags.setTags(Lists.emptyList()); + when(tagsCommandBuilder.getTags()).thenReturn(tags); + when(tagCommandBuilder.create()).thenReturn(tagCreateCommandBuilder); + when(tagCreateCommandBuilder.execute()).thenReturn(new Tag("newtag", "592d797cd36432e591416e8b2b98154f4f163411")); + MockHttpRequest request = MockHttpRequest + .post(TAG_URL) + .content("{\"name\": \"newtag\",\"revision\":\"592d797cd36432e591416e8b2b98154f4f163411\"}".getBytes()) + .contentType(VndMediaType.TAG_REQUEST); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(403, response.getStatus()); + verify(tagCommandBuilder, never()).create(); + } + + @Test + public void shouldThrowExceptionIfTagAlreadyExists() throws URISyntaxException, IOException { + Tags tags = new Tags(); + tags.setTags(Collections.singletonList(new Tag("newtag", "592d797cd36432e591416e8b2b98154f4f163411"))); + when(tagsCommandBuilder.getTags()).thenReturn(tags); + when(tagCommandBuilder.create()).thenReturn(tagCreateCommandBuilder); + when(tagCreateCommandBuilder.execute()).thenReturn(new Tag("newtag", "592d797cd36432e591416e8b2b98154f4f163411")); + MockHttpRequest request = MockHttpRequest + .post(TAG_URL) + .content("{\"name\": \"newtag\",\"revision\":\"592d797cd36432e591416e8b2b98154f4f163411\"}".getBytes()) + .contentType(VndMediaType.TAG_REQUEST); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(409, response.getStatus()); + verify(tagCommandBuilder, never()).create(); + } + + @Test + public void shouldDeleteTag() throws IOException, URISyntaxException { + Tags tags = new Tags(); + tags.setTags(Collections.singletonList(new Tag("newtag", "592d797cd36432e591416e8b2b98154f4f163411"))); + when(tagsCommandBuilder.getTags()).thenReturn(tags); + when(tagCommandBuilder.delete()).thenReturn(tagDeleteCommandBuilder); + + MockHttpRequest request = MockHttpRequest + .delete(TAG_URL + "newtag"); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(204, response.getStatus()); + verify(tagCommandBuilder).delete(); + } + + @Test + public void shouldReturn204EvenIfTagDoesntExist() throws IOException, URISyntaxException { + Tags tags = new Tags(); + tags.setTags(Collections.emptyList()); + when(tagsCommandBuilder.getTags()).thenReturn(tags); + when(tagCommandBuilder.delete()).thenReturn(tagDeleteCommandBuilder); + + MockHttpRequest request = MockHttpRequest + .delete(TAG_URL + "newtag"); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(204, response.getStatus()); + verify(tagCommandBuilder, never()).delete(); + } + + @Test + public void shouldNotDeleteTagIfNotPermitted() throws IOException, URISyntaxException { + doThrow(AuthorizationException.class).when(subject).checkPermission("repository:modify:repoId"); + Tags tags = new Tags(); + tags.setTags(Collections.singletonList(new Tag("newtag", "592d797cd36432e591416e8b2b98154f4f163411"))); + when(tagsCommandBuilder.getTags()).thenReturn(tags); + when(tagCommandBuilder.delete()).thenReturn(tagDeleteCommandBuilder); + + MockHttpRequest request = MockHttpRequest + .delete(TAG_URL + "newtag"); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(403, response.getStatus()); + verify(tagCommandBuilder, never()).delete(); + } } From e3170543cba4a29691aa2850e619edcbe205dee8 Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Wed, 25 Nov 2020 15:51:44 +0100 Subject: [PATCH 04/35] add frontend for deleting tags --- scm-ui/ui-webapp/public/locales/de/repos.json | 13 ++++- scm-ui/ui-webapp/public/locales/en/repos.json | 13 ++++- .../src/repos/tags/components/TagRow.tsx | 25 ++++++--- .../src/repos/tags/components/TagTable.tsx | 54 +++++++++++++++++-- .../src/repos/tags/container/TagsOverview.tsx | 8 ++- .../scm/api/v2/resources/ResourceLinks.java | 4 ++ .../api/v2/resources/TagToTagDtoMapper.java | 3 +- 7 files changed, 104 insertions(+), 16 deletions(-) diff --git a/scm-ui/ui-webapp/public/locales/de/repos.json b/scm-ui/ui-webapp/public/locales/de/repos.json index d95ef44970..a0b6ef015b 100644 --- a/scm-ui/ui-webapp/public/locales/de/repos.json +++ b/scm-ui/ui-webapp/public/locales/de/repos.json @@ -95,7 +95,18 @@ "tag": { "name": "Name", "commit": "Commit", - "sources": "Sources" + "sources": "Sources", + "delete": { + "button": "Tag löschen", + "subtitle": "Tag löschen", + "description": "Gelöschte Tags können nicht wiederhergestellt werden.", + "confirmAlert": { + "title": "Tag löschen", + "message": "Möchten Sie den Tag \"{{tag}}\" wirklich löschen?", + "cancel": "Nein", + "submit": "Ja" + } + } }, "code": { "sources": "Sources", diff --git a/scm-ui/ui-webapp/public/locales/en/repos.json b/scm-ui/ui-webapp/public/locales/en/repos.json index 59981282df..f2f6f31cea 100644 --- a/scm-ui/ui-webapp/public/locales/en/repos.json +++ b/scm-ui/ui-webapp/public/locales/en/repos.json @@ -95,7 +95,18 @@ "tag": { "name": "Name", "commit": "Commit", - "sources": "Sources" + "sources": "Sources", + "delete": { + "button": "Delete tag", + "subtitle": "Delete tag", + "description": "Deleted tag can not be restored.", + "confirmAlert": { + "title": "Delete tag", + "message": "Do you really want to delete the tag \"{{tag}}\"?", + "cancel": "No", + "submit": "Yes" + } + } }, "code": { "sources": "Sources", diff --git a/scm-ui/ui-webapp/src/repos/tags/components/TagRow.tsx b/scm-ui/ui-webapp/src/repos/tags/components/TagRow.tsx index 00b18da623..9b45816231 100644 --- a/scm-ui/ui-webapp/src/repos/tags/components/TagRow.tsx +++ b/scm-ui/ui-webapp/src/repos/tags/components/TagRow.tsx @@ -24,14 +24,15 @@ import React, { FC } from "react"; import { useTranslation } from "react-i18next"; -import { Link } from "react-router-dom"; -import { Tag } from "@scm-manager/ui-types"; +import { Link as RouterLink } from "react-router-dom"; +import { Tag, Link } from "@scm-manager/ui-types"; import styled from "styled-components"; -import { DateFromNow } from "@scm-manager/ui-components"; +import { DateFromNow, Icon } from "@scm-manager/ui-components"; type Props = { tag: Tag; baseUrl: string; + onDelete: (tag: Tag) => void; }; const Created = styled.span` @@ -39,20 +40,32 @@ const Created = styled.span` font-size: 0.8rem; `; -const TagRow: FC = ({ tag, baseUrl }) => { +const TagRow: FC = ({ tag, baseUrl, onDelete }) => { const [t] = useTranslation("repos"); + let deleteButton; + if ((tag?._links?.delete as Link)?.href) { + deleteButton = ( + onDelete(tag)}> + + + + + ); + } + const to = `${baseUrl}/${encodeURIComponent(tag.name)}/info`; return ( - + {tag.name} {t("tags.overview.created")} - + + {deleteButton} ); }; diff --git a/scm-ui/ui-webapp/src/repos/tags/components/TagTable.tsx b/scm-ui/ui-webapp/src/repos/tags/components/TagTable.tsx index 4cd694766f..5778b346a9 100644 --- a/scm-ui/ui-webapp/src/repos/tags/components/TagTable.tsx +++ b/scm-ui/ui-webapp/src/repos/tags/components/TagTable.tsx @@ -22,30 +22,74 @@ * SOFTWARE. */ -import React, { FC } from "react"; -import { Tag } from "@scm-manager/ui-types"; +import React, {FC, useState} from "react"; +import {Link, Tag} from "@scm-manager/ui-types"; import { useTranslation } from "react-i18next"; import TagRow from "./TagRow"; +import {apiClient, ConfirmAlert, ErrorNotification} from "@scm-manager/ui-components"; type Props = { baseUrl: string; tags: Tag[]; + fetchTags: () => void; }; -const TagTable: FC = ({ baseUrl, tags }) => { +const TagTable: FC = ({ baseUrl, tags, fetchTags }) => { const [t] = useTranslation("repos"); + const [showConfirmAlert, setShowConfirmAlert] = useState(false); + const [error, setError] = useState(); + const [tagToBeDeleted, setTagToBeDeleted] = useState(); + + const onDelete = (tag: Tag) => { + setTagToBeDeleted(tag); + setShowConfirmAlert(true); + }; + + const abortDelete = () => { + setTagToBeDeleted(undefined); + setShowConfirmAlert(false); + }; + + const deleteTag = () => { + apiClient + .delete((tagToBeDeleted?._links.delete as Link).href) + .then(() => fetchTags()) + .catch(setError); + }; const renderRow = () => { let rowContent = null; if (tags) { rowContent = tags.map((tag, index) => { - return ; + return ; }); } return rowContent; }; + const confirmAlert = ( + deleteTag() + }, + { + label: t("tag.delete.confirmAlert.cancel"), + onClick: () => abortDelete() + } + ]} + close={() => abortDelete()} + /> + ); + return ( + <> + {showConfirmAlert && confirmAlert} + {error && } @@ -54,7 +98,7 @@ const TagTable: FC = ({ baseUrl, tags }) => { {renderRow()}
- ); + ); }; export default TagTable; diff --git a/scm-ui/ui-webapp/src/repos/tags/container/TagsOverview.tsx b/scm-ui/ui-webapp/src/repos/tags/container/TagsOverview.tsx index 42de372b60..e449358c3b 100644 --- a/scm-ui/ui-webapp/src/repos/tags/container/TagsOverview.tsx +++ b/scm-ui/ui-webapp/src/repos/tags/container/TagsOverview.tsx @@ -40,7 +40,7 @@ const TagsOverview: FC = ({ repository, baseUrl }) => { const [error, setError] = useState(undefined); const [tags, setTags] = useState([]); - useEffect(() => { + const fetchTags = () => { const link = (repository._links?.tags as Link)?.href; if (link) { setLoading(true); @@ -51,12 +51,16 @@ const TagsOverview: FC = ({ repository, baseUrl }) => { .then(() => setLoading(false)) .catch(setError); } + }; + + useEffect(() => { + fetchTags(); }, [repository]); const renderTagsTable = () => { if (!loading && tags?.length > 0) { orderTags(tags); - return ; + return fetchTags()} />; } return {t("tags.overview.noTags")}; }; diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ResourceLinks.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ResourceLinks.java index 7bd6c353f5..f24490eef1 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ResourceLinks.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ResourceLinks.java @@ -445,6 +445,10 @@ class ResourceLinks { return tagLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("tags").parameters().method("get").parameters(tagName).href(); } + String delete(String namespace, String name, String tagName) { + return tagLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("tags").parameters().method("delete").parameters(tagName).href(); + } + String all(String namespace, String name) { return tagLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("tags").parameters().method("getAll").parameters().href(); } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java index 78350ab114..cfa0c2db8c 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java @@ -60,7 +60,8 @@ public abstract class TagToTagDtoMapper extends HalAppenderMapper { Links.Builder linksBuilder = linkingTo() .self(resourceLinks.tag().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), tag.getName())) .single(link("sources", resourceLinks.source().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), tag.getRevision()))) - .single(link("changeset", resourceLinks.changeset().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), tag.getRevision()))); + .single(link("changeset", resourceLinks.changeset().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), tag.getRevision()))) + .single(link("delete", resourceLinks.tag().delete(namespaceAndName.getNamespace(), namespaceAndName.getName(), tag.getName()))); Embedded.Builder embeddedBuilder = embeddedBuilder(); applyEnrichers(new EdisonHalAppender(linksBuilder, embeddedBuilder), tag, namespaceAndName); From b64d34afa481ad610790d85cf74ac89633bb3961 Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Thu, 26 Nov 2020 11:15:26 +0100 Subject: [PATCH 05/35] add hook events to tag command and update unit tests --- .../spi/GitRepositoryServiceProvider.java | 10 +- .../spi/GitRepositoryServiceResolver.java | 10 +- .../scm/repository/spi/GitTagCommand.java | 183 +++++++++++------- .../spi/GitRepositoryServiceProviderTest.java | 10 +- .../scm/repository/spi/GitTagCommandTest.java | 61 +++++- 5 files changed, 193 insertions(+), 81 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceProvider.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceProvider.java index a6f2145611..5b936ba23a 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceProvider.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceProvider.java @@ -27,8 +27,10 @@ package sonia.scm.repository.spi; import com.google.common.collect.ImmutableSet; import com.google.inject.AbstractModule; import com.google.inject.Injector; +import sonia.scm.event.ScmEventBus; import sonia.scm.repository.Feature; import sonia.scm.repository.api.Command; +import sonia.scm.repository.api.HookContextFactory; import sonia.scm.security.GPG; import java.util.EnumSet; @@ -63,13 +65,17 @@ public class GitRepositoryServiceProvider extends RepositoryServiceProvider private final GitContext context; private final GPG gpg; + private final HookContextFactory hookContextFactory; + private final ScmEventBus eventBus; private final Injector commandInjector; //~--- constructors --------------------------------------------------------- - GitRepositoryServiceProvider(Injector injector, GitContext context, GPG gpg) { + GitRepositoryServiceProvider(Injector injector, GitContext context, GPG gpg, HookContextFactory hookContextFactory, ScmEventBus eventBus) { this.context = context; this.gpg = gpg; + this.hookContextFactory = hookContextFactory; + this.eventBus = eventBus; commandInjector = injector.createChildInjector(new AbstractModule() { @Override protected void configure() { @@ -150,7 +156,7 @@ public class GitRepositoryServiceProvider extends RepositoryServiceProvider @Override public TagCommand getTagCommand() { - return new GitTagCommand(context, gpg); + return new GitTagCommand(context, gpg, hookContextFactory, eventBus); } @Override diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceResolver.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceResolver.java index 1eb9b55e9b..8e65258ada 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceResolver.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceResolver.java @@ -28,9 +28,11 @@ package sonia.scm.repository.spi; import com.google.inject.Inject; import com.google.inject.Injector; +import sonia.scm.event.ScmEventBus; import sonia.scm.plugin.Extension; import sonia.scm.repository.GitRepositoryHandler; import sonia.scm.repository.Repository; +import sonia.scm.repository.api.HookContextFactory; import sonia.scm.security.GPG; /** @@ -43,18 +45,22 @@ public class GitRepositoryServiceResolver implements RepositoryServiceResolver { private final Injector injector; private final GitContextFactory contextFactory; private final GPG gpg; + private final HookContextFactory hookContextFactory; + private final ScmEventBus scmEventBus; @Inject - public GitRepositoryServiceResolver(Injector injector, GitContextFactory contextFactory, GPG gpg) { + public GitRepositoryServiceResolver(Injector injector, GitContextFactory contextFactory, GPG gpg, HookContextFactory hookContextFactory) { this.injector = injector; this.contextFactory = contextFactory; this.gpg = gpg; + this.hookContextFactory = hookContextFactory; + this.scmEventBus = ScmEventBus.getInstance(); } @Override public GitRepositoryServiceProvider resolve(Repository repository) { if (GitRepositoryHandler.TYPE_NAME.equalsIgnoreCase(repository.getType())) { - return new GitRepositoryServiceProvider(injector, contextFactory.create(repository), gpg); + return new GitRepositoryServiceProvider(injector, contextFactory.create(repository), gpg, hookContextFactory, scmEventBus); } return null; } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java index 31fb9d6249..4d9814f5c4 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java @@ -30,78 +30,93 @@ import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevObject; -import org.eclipse.jgit.revwalk.RevTag; import org.eclipse.jgit.revwalk.RevWalk; -import org.eclipse.jgit.util.RawParseUtils; +import sonia.scm.event.ScmEventBus; import sonia.scm.repository.GitUtil; import sonia.scm.repository.InternalRepositoryException; +import sonia.scm.repository.PostReceiveRepositoryHookEvent; +import sonia.scm.repository.PreReceiveRepositoryHookEvent; +import sonia.scm.repository.RepositoryHookEvent; +import sonia.scm.repository.RepositoryHookType; import sonia.scm.repository.Signature; -import sonia.scm.repository.SignatureStatus; import sonia.scm.repository.Tag; -import sonia.scm.repository.api.TagDeleteRequest; +import sonia.scm.repository.api.HookContext; +import sonia.scm.repository.api.HookContextFactory; +import sonia.scm.repository.api.HookFeature; +import sonia.scm.repository.api.HookTagProvider; import sonia.scm.repository.api.TagCreateRequest; +import sonia.scm.repository.api.TagDeleteRequest; import sonia.scm.security.GPG; -import sonia.scm.security.PublicKey; -import java.io.ByteArrayOutputStream; +import javax.inject.Inject; import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; +import java.util.List; import java.util.Optional; +import java.util.Set; + +import static java.util.Collections.emptyList; +import static java.util.Collections.singleton; +import static java.util.Collections.singletonList; public class GitTagCommand extends AbstractGitCommand implements TagCommand { private final GPG gpg; + private final HookContextFactory hookContextFactory; + private final ScmEventBus eventBus; - GitTagCommand(GitContext context, GPG gpg) { + @Inject + GitTagCommand(GitContext context, GPG gpg, HookContextFactory hookContextFactory, ScmEventBus eventBus) { super(context); this.gpg = gpg; + this.hookContextFactory = hookContextFactory; + this.eventBus = eventBus; } @Override public Tag create(TagCreateRequest request) { try (Git git = new Git(context.open())) { - Tag tag; String revision = request.getRevision(); - RevObject revObject = null; - Long tagTime = null; + RevObject revObject; + Long tagTime; - if (!Strings.isNullOrEmpty(revision)) { - ObjectId id = git.getRepository().resolve(revision); - - try (RevWalk walk = new RevWalk(git.getRepository())) { - revObject = walk.parseAny(id); - tagTime = GitUtil.getTagTime(walk, id); - } + if (Strings.isNullOrEmpty(revision)) { + throw new IllegalArgumentException("Revision is required"); } - Ref ref; + ObjectId taggedCommitObjectId = git.getRepository().resolve(revision); - if (revObject != null) { - ref = - git.tag() - .setObjectId(revObject) - .setTagger(new PersonIdent("SCM-Manager", "noreply@scm-manager.org")) - .setName(request.getName()) - .call(); - } else { + try (RevWalk walk = new RevWalk(git.getRepository())) { + revObject = walk.parseAny(taggedCommitObjectId); + tagTime = GitUtil.getTagTime(walk, taggedCommitObjectId); + } + + Tag tag = new Tag(request.getName(), revision, tagTime); + + if (revObject == null) { throw new InternalRepositoryException(repository, "could not create tag because revision does not exist"); } - ObjectId objectId; - if (ref.isPeeled()) { - objectId = ref.getPeeledObjectId(); - } else { - objectId = ref.getObjectId(); - } - tag = new Tag(request.getName(), objectId.toString(), tagTime); + RepositoryHookEvent hookEvent = createTagHookEvent(TagHookContextProvider.createHookEvent(tag)); + eventBus.post(new PreReceiveRepositoryHookEvent(hookEvent)); + + Ref ref = + git.tag() + .setObjectId(revObject) + .setTagger(new PersonIdent("SCM-Manager", "noreply@scm-manager.org")) + .setName(request.getName()) + .call(); try (RevWalk walk = new RevWalk(git.getRepository())) { - revObject = walk.parseTag(objectId); - tag.addSignature(getTagSignature((RevTag) revObject)); + revObject = walk.parseTag(ref.getObjectId()); + final Optional tagSignature = GitUtil.getTagSignature(revObject, gpg); + tagSignature.ifPresent(tag::addSignature); } + eventBus.post(new PostReceiveRepositoryHookEvent(hookEvent)); + return tag; } catch (IOException | GitAPIException ex) { throw new InternalRepositoryException(repository, "could not create tag " + request.getName(), ex); @@ -111,58 +126,76 @@ public class GitTagCommand extends AbstractGitCommand implements TagCommand { @Override public void delete(TagDeleteRequest request) { try (Git git = new Git(context.open())) { - git.tagDelete().setTags(request.getName()).call(); + String name = request.getName(); + final Repository repository = git.getRepository(); + Ref tagRef = findTagRef(git, name); + Tag tag; + + try (RevWalk walk = new RevWalk(repository)) { + final RevCommit commit = GitUtil.getCommit(repository, walk, tagRef); + Long tagTime = GitUtil.getTagTime(walk, commit.toObjectId()); + tag = new Tag(name, commit.name(), tagTime); + } + + RepositoryHookEvent hookEvent = createTagHookEvent(TagHookContextProvider.deleteHookEvent(tag)); + eventBus.post(new PreReceiveRepositoryHookEvent(hookEvent)); + git.tagDelete().setTags(name).call(); + eventBus.post(new PostReceiveRepositoryHookEvent(hookEvent)); } catch (GitAPIException | IOException e) { throw new InternalRepositoryException(repository, "could not delete tag", e); } } - private static final byte[] GPG_HEADER = {'g', 'p', 'g', 's', 'i', 'g'}; + private Ref findTagRef(Git git, String name) throws GitAPIException { + final String tagRef = "refs/tags/" + name; + return git.tagList().call().stream().filter(it -> it.getName().equals(tagRef)).findAny().get(); + } - private Signature getTagSignature(RevTag tag) { - byte[] raw = tag.getFullMessage().getBytes(); + private RepositoryHookEvent createTagHookEvent(TagHookContextProvider hookEvent) { + HookContext context = hookContextFactory.createContext(hookEvent, this.context.getRepository()); + return new RepositoryHookEvent(context, this.context.getRepository(), RepositoryHookType.PRE_RECEIVE); + } - int start = RawParseUtils.headerStart(GPG_HEADER, raw, 0); - if (start < 0) { - return null; + private static class TagHookContextProvider extends HookContextProvider { + private final List newTags; + private final List deletedTags; + + private TagHookContextProvider(List newTags, List deletedTags) { + this.newTags = newTags; + this.deletedTags = deletedTags; } - int end = RawParseUtils.headerEnd(raw, start); - byte[] signature = Arrays.copyOfRange(raw, start, end); - - String publicKeyId = gpg.findPublicKeyId(signature); - if (Strings.isNullOrEmpty(publicKeyId)) { - // key not found - return new Signature(publicKeyId, "gpg", SignatureStatus.NOT_FOUND, null, Collections.emptySet()); + static TagHookContextProvider createHookEvent(Tag newTag) { + return new TagHookContextProvider(singletonList(newTag), emptyList()); } - Optional publicKeyById = gpg.findPublicKey(publicKeyId); - if (!publicKeyById.isPresent()) { - // key not found - return new Signature(publicKeyId, "gpg", SignatureStatus.NOT_FOUND, null, Collections.emptySet()); + static TagHookContextProvider deleteHookEvent(Tag deletedTag) { + return new TagHookContextProvider(emptyList(), singletonList(deletedTag)); } - PublicKey publicKey = publicKeyById.get(); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try { - byte[] headerPrefix = Arrays.copyOfRange(raw, 0, start - GPG_HEADER.length - 1); - baos.write(headerPrefix); - - byte[] headerSuffix = Arrays.copyOfRange(raw, end + 1, raw.length); - baos.write(headerSuffix); - } catch (IOException ex) { - // this will never happen, because we are writing into memory - throw new IllegalStateException("failed to write into memory", ex); + @Override + public Set getSupportedFeatures() { + return singleton(HookFeature.BRANCH_PROVIDER); } - boolean verified = publicKey.verify(baos.toByteArray(), signature); - return new Signature( - publicKeyId, - "gpg", - verified ? SignatureStatus.VERIFIED : SignatureStatus.INVALID, - publicKey.getOwner().orElse(null), - publicKey.getContacts() - ); + @Override + public HookTagProvider getTagProvider() { + return new HookTagProvider() { + @Override + public List getCreatedTags() { + return newTags; + } + + @Override + public List getDeletedTags() { + return deletedTags; + } + }; + } + + @Override + public HookChangesetProvider getChangesetProvider() { + return r -> new HookChangesetResponse(emptyList()); + } } } diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitRepositoryServiceProviderTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitRepositoryServiceProviderTest.java index 4878a8f4b8..894965ccda 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitRepositoryServiceProviderTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitRepositoryServiceProviderTest.java @@ -31,7 +31,9 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import sonia.scm.event.ScmEventBus; import sonia.scm.repository.GitRepositoryHandler; +import sonia.scm.repository.api.HookContextFactory; import sonia.scm.security.GPG; import static org.assertj.core.api.Assertions.assertThat; @@ -49,6 +51,12 @@ class GitRepositoryServiceProviderTest { @Mock private GPG gpg; + @Mock + private HookContextFactory hookContextFactory; + + @Mock + private ScmEventBus eventBus; + @Test void shouldCreatePushCommand() { GitRepositoryServiceProvider provider = createProvider(); @@ -63,7 +71,7 @@ class GitRepositoryServiceProviderTest { } private GitRepositoryServiceProvider createProvider() { - return new GitRepositoryServiceProvider(createParentInjector(), context, gpg); + return new GitRepositoryServiceProvider(createParentInjector(), context, gpg, hookContextFactory, eventBus); } private Injector createParentInjector() { diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagCommandTest.java index 7c883cc087..12b02e3473 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagCommandTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagCommandTest.java @@ -28,10 +28,17 @@ import org.eclipse.jgit.lib.GpgSigner; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; +import org.mockito.invocation.InvocationOnMock; import org.mockito.junit.MockitoJUnitRunner; +import sonia.scm.event.ScmEventBus; import sonia.scm.repository.GitTestHelper; +import sonia.scm.repository.PostReceiveRepositoryHookEvent; +import sonia.scm.repository.PreReceiveRepositoryHookEvent; import sonia.scm.repository.Tag; +import sonia.scm.repository.api.HookContext; +import sonia.scm.repository.api.HookContextFactory; import sonia.scm.repository.api.TagDeleteRequest; import sonia.scm.repository.api.TagCreateRequest; import sonia.scm.security.GPG; @@ -41,6 +48,10 @@ import java.util.List; import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class GitTagCommandTest extends AbstractGitCommandTestBase { @@ -48,6 +59,12 @@ public class GitTagCommandTest extends AbstractGitCommandTestBase { @Mock private GPG gpg; + @Mock + private HookContextFactory hookContextFactory; + + @Mock + private ScmEventBus eventBus; + @Before public void setSigner() { GpgSigner.setDefault(new GitTestHelper.SimpleGpgSigner()); @@ -60,6 +77,23 @@ public class GitTagCommandTest extends AbstractGitCommandTestBase { assertThat(tag).isNotEmpty(); } + @Test + public void shouldPostCreateEvent() { + ArgumentCaptor captor = ArgumentCaptor.forClass(Object.class); + doNothing().when(eventBus).post(captor.capture()); + when(hookContextFactory.createContext(any(), any())).thenAnswer(this::createMockedContext); + + createCommand().create(new TagCreateRequest("592d797cd36432e591416e8b2b98154f4f163411", "newtag")); + + List events = captor.getAllValues(); + assertThat(events.get(0)).isInstanceOf(PreReceiveRepositoryHookEvent.class); + assertThat(events.get(1)).isInstanceOf(PostReceiveRepositoryHookEvent.class); + + PreReceiveRepositoryHookEvent event = (PreReceiveRepositoryHookEvent) events.get(0); + assertThat(event.getContext().getTagProvider().getCreatedTags().get(0).getName()).isEqualTo("newtag"); + assertThat(event.getContext().getTagProvider().getDeletedTags()).isEmpty(); + } + @Test public void shouldDeleteATag() throws IOException { final GitContext context = createContext(); @@ -72,8 +106,27 @@ public class GitTagCommandTest extends AbstractGitCommandTestBase { assertThat(tag).isEmpty(); } + @Test + public void shouldPostDeleteEvent() { + ArgumentCaptor captor = ArgumentCaptor.forClass(Object.class); + doNothing().when(eventBus).post(captor.capture()); + when(hookContextFactory.createContext(any(), any())).thenAnswer(this::createMockedContext); + + createCommand().delete(new TagDeleteRequest("test-tag")); + + List events = captor.getAllValues(); + assertThat(events.get(0)).isInstanceOf(PreReceiveRepositoryHookEvent.class); + assertThat(events.get(1)).isInstanceOf(PostReceiveRepositoryHookEvent.class); + + PreReceiveRepositoryHookEvent event = (PreReceiveRepositoryHookEvent) events.get(0); + assertThat(event.getContext().getTagProvider().getCreatedTags()).isEmpty(); + final Tag deletedTag = event.getContext().getTagProvider().getDeletedTags().get(0); + assertThat(deletedTag.getName()).isEqualTo("test-tag"); + assertThat(deletedTag.getRevision()).isEqualTo("86a6645eceefe8b9a247db5eb16e3d89a7e6e6d1"); + } + private GitTagCommand createCommand() { - return new GitTagCommand(createContext(), gpg); + return new GitTagCommand(createContext(), gpg, hookContextFactory, eventBus); } private List readTags(GitContext context) throws IOException { @@ -84,4 +137,10 @@ public class GitTagCommandTest extends AbstractGitCommandTestBase { List branches = readTags(context); return branches.stream().filter(b -> name.equals(b.getName())).findFirst(); } + + private HookContext createMockedContext(InvocationOnMock invocation) { + HookContext mock = mock(HookContext.class); + when(mock.getTagProvider()).thenReturn(((HookContextProvider) invocation.getArgument(0)).getTagProvider()); + return mock; + } } From 280f3e005e27e7059c87d7b62373e37d7e7b5d0c Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Thu, 26 Nov 2020 13:08:10 +0100 Subject: [PATCH 06/35] work on getting signatures running --- .../java/sonia/scm/repository/GitUtil.java | 44 +++++-------------- .../scm/repository/spi/GitTagCommand.java | 2 +- .../scm/repository/spi/GitTagsCommand.java | 18 ++++---- .../repository/spi/GitTagsCommandTest.java | 39 +++++++++------- 4 files changed, 45 insertions(+), 58 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java index b1e0ec2b34..f41628f8e0 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java @@ -422,16 +422,8 @@ public final class GitUtil } /** - * Method description - * - * - * @param repository - * @param revWalk - * @param ref - * - * @return - * - * @throws IOException + * Returns the commit for the given ref. + * If the given ref is for a tag, the commit that this tag belongs to is returned instead. */ public static RevCommit getCommit(org.eclipse.jgit.lib.Repository repository, RevWalk revWalk, Ref ref) @@ -710,22 +702,20 @@ public final class GitUtil return name; } - private static final byte[] GPG_HEADER = {'P', 'G', 'P'}; + private static final String GPG_HEADER = "-----BEGIN PGP SIGNATURE-----"; - public static Optional getTagSignature(RevObject revObject, GPG gpg) { + public static Optional getTagSignature(RevObject revObject, GPG gpg, RevWalk revWalk) throws IOException { if (revObject instanceof RevTag) { - RevTag tag = (RevTag) revObject; - byte[] raw = tag.getFullMessage().getBytes(); - - int start = RawParseUtils.headerStart(GPG_HEADER, raw, 0); - if (start < 0) { + final byte[] bytes = revWalk.getObjectReader().open(revObject.getId()).getBytes(); + final String message = new String(bytes); + final int signatureStartIndex = message.indexOf(GPG_HEADER); + if (signatureStartIndex < 0) { return Optional.empty(); } - int end = RawParseUtils.headerEnd(raw, start); - byte[] signature = Arrays.copyOfRange(raw, start, end); + final String signature = message.substring(signatureStartIndex); - String publicKeyId = gpg.findPublicKeyId(signature); + String publicKeyId = gpg.findPublicKeyId(signature.getBytes()); if (Strings.isNullOrEmpty(publicKeyId)) { // key not found return Optional.of(new Signature(publicKeyId, "gpg", SignatureStatus.NOT_FOUND, null, Collections.emptySet())); @@ -739,19 +729,7 @@ public final class GitUtil PublicKey publicKey = publicKeyById.get(); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try { - byte[] headerPrefix = Arrays.copyOfRange(raw, 0, start - GPG_HEADER.length - 1); - baos.write(headerPrefix); - - byte[] headerSuffix = Arrays.copyOfRange(raw, end + 1, raw.length); - baos.write(headerSuffix); - } catch (IOException ex) { - // this will never happen, because we are writing into memory - throw new IllegalStateException("failed to write into memory", ex); - } - - boolean verified = publicKey.verify(baos.toByteArray(), signature); + boolean verified = publicKey.verify(message.substring(0, signatureStartIndex - 1).getBytes(), signature.getBytes()); return Optional.of(new Signature( publicKeyId, "gpg", diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java index 4d9814f5c4..ca3bd78c6e 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java @@ -111,7 +111,7 @@ public class GitTagCommand extends AbstractGitCommand implements TagCommand { try (RevWalk walk = new RevWalk(git.getRepository())) { revObject = walk.parseTag(ref.getObjectId()); - final Optional tagSignature = GitUtil.getTagSignature(revObject, gpg); + final Optional tagSignature = GitUtil.getTagSignature(revObject, gpg, walk); tagSignature.ifPresent(tag::addSignature); } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagsCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagsCommand.java index 06e500ce4c..64a038b3ce 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagsCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagsCommand.java @@ -82,7 +82,7 @@ public class GitTagsCommand extends AbstractGitCommand implements TagsCommand { List tagList = git.tagList().call(); tags = Lists.transform(tagList, - new TransformFuntion(git.getRepository(), revWalk, gpg, git)); + new TransformFunction(git.getRepository(), revWalk, gpg, git)); } catch (GitAPIException ex) { throw new InternalRepositoryException(repository, "could not read tags from repository", ex); } finally { @@ -100,13 +100,13 @@ public class GitTagsCommand extends AbstractGitCommand implements TagsCommand { * @author Enter your name here... * @version Enter version here..., 12/07/06 */ - private static class TransformFuntion implements Function { + private static class TransformFunction implements Function { /** * the logger for TransformFuntion */ private static final Logger logger = - LoggerFactory.getLogger(TransformFuntion.class); + LoggerFactory.getLogger(TransformFunction.class); //~--- constructors ------------------------------------------------------- @@ -116,10 +116,10 @@ public class GitTagsCommand extends AbstractGitCommand implements TagsCommand { * @param repository * @param revWalk */ - public TransformFuntion(org.eclipse.jgit.lib.Repository repository, - RevWalk revWalk, - GPG gpg, - Git git) { + public TransformFunction(org.eclipse.jgit.lib.Repository repository, + RevWalk revWalk, + GPG gpg, + Git git) { this.repository = repository; this.revWalk = revWalk; this.gpg = gpg; @@ -149,12 +149,12 @@ public class GitTagsCommand extends AbstractGitCommand implements TagsCommand { try { RevTag revTag = GitUtil.getTag(repository, revWalk, ref); - final Optional tagSignature = GitUtil.getTagSignature(revTag, gpg); + final Optional tagSignature = GitUtil.getTagSignature(revTag, gpg, revWalk); if (tagSignature.isPresent()) { tag.addSignature(tagSignature.get()); } } catch (IncorrectObjectTypeException e) { - // Ignore, this must be a lightweight tag + // Ignore because it is a lightweight tag which cannot have signatures } } diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagsCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagsCommandTest.java index 27711d8b55..456096d736 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagsCommandTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagsCommandTest.java @@ -24,41 +24,33 @@ package sonia.scm.repository.spi; -import com.github.sdorra.shiro.ShiroRule; import com.github.sdorra.shiro.SubjectAware; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.mockito.ArgumentMatchers; import org.mockito.Mock; -import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; import sonia.scm.repository.Tag; import sonia.scm.security.GPG; +import sonia.scm.security.PublicKey; import java.io.IOException; import java.util.List; +import java.util.Optional; -import static org.assertj.core.api.Assertions.anyOf; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; @SubjectAware(configuration = "classpath:sonia/scm/configuration/shiro.ini", username = "admin", password = "secret") @RunWith(MockitoJUnitRunner.class) public class GitTagsCommandTest extends AbstractGitCommandTestBase { - @Rule - public TemporaryFolder temporaryFolder = new TemporaryFolder(); - - @Rule - public BindTransportProtocolRule transportProtocolRule = new BindTransportProtocolRule(); - - @Rule - public ShiroRule shiro = new ShiroRule(); - @Mock GPG gpg; + @Mock + PublicKey publicKey; + @Test public void shouldGetDatesCorrectly() throws IOException { final GitContext gitContext = createContext(); @@ -79,7 +71,24 @@ public class GitTagsCommandTest extends AbstractGitCommandTestBase { @Test public void shouldGetSignatures() throws IOException { - Mockito.when(gpg.findPublicKeyId(ArgumentMatchers.any())).thenReturn("2BA27721F113C005CC16F06BAE63EFBC49F140CF"); + when(gpg.findPublicKeyId(ArgumentMatchers.any())).thenReturn("2BA27721F113C005CC16F06BAE63EFBC49F140CF"); + when(gpg.findPublicKey("2BA27721F113C005CC16F06BAE63EFBC49F140CF")).thenReturn(Optional.of(publicKey)); + String signature = "-----BEGIN PGP SIGNATURE-----\n" + + "\n" + + "iQEzBAABCgAdFiEEK6J3IfETwAXMFvBrrmPvvEnxQM8FAl+9acoACgkQrmPvvEnx\n" + + "QM9abwgAnGP+Y/Ijli+PAsimfOmZQWYepjptoOv9m7i3bnHv8V+Qg6cm51I3E0YV\n" + + "R2QaxxzW9PgS4hcES+L1qs8Lwo18RurF469eZEmNb8DcUFJ3sEWeHlIl5wZNNo/v\n" + + "jJm0d9LNcSmtAIiQ8eDMoGdFXJzHewGickLOSsQGmfZgZus4Qlsh7r3BZTI1Zwd/\n" + + "6jaBFctX13FuepCTxq2SjEfRaQHIYkyFQq2o6mjL5S2qfYJ/S//gcCCzxllQrisF\n" + + "5fRW3LzLI4eXFH0vua7+UzNS2Rwpifg2OENJA/Kn+3R36LWEGxFK9pNqjVPRAcQj\n" + + "1vSkcjK26RqhAqCjNLSagM8ATZrh+g==\n" + + "=kUKm\n" + + "-----END PGP SIGNATURE-----\n"; + String signedContent = "Tagger: Arthur Dent \n" + + "Date: Tue Nov 24 21:37:46 2020 +0100\n" + + "\n" + + "this tag is signed"; + when(publicKey.verify(signedContent.getBytes(), signature.getBytes())).thenReturn(true); final GitContext gitContext = createContext(); final GitTagsCommand tagsCommand = new GitTagsCommand(gitContext, gpg); From 7895da0a2a122bfa15ef13f8d5044517dd55a10b Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Fri, 27 Nov 2020 08:49:10 +0100 Subject: [PATCH 07/35] implement frontend for creating tags --- scm-ui/ui-components/src/buttons/Button.tsx | 8 +- scm-ui/ui-webapp/public/locales/de/repos.json | 16 ++ scm-ui/ui-webapp/public/locales/en/repos.json | 16 ++ .../changesets/ChangesetDetails.tsx | 258 +++++++++++------- .../src/repos/containers/ChangesetView.tsx | 8 +- .../DefaultChangesetToChangesetDtoMapper.java | 1 + .../scm/api/v2/resources/ResourceLinks.java | 4 + 7 files changed, 203 insertions(+), 108 deletions(-) diff --git a/scm-ui/ui-components/src/buttons/Button.tsx b/scm-ui/ui-components/src/buttons/Button.tsx index e8c6494437..fc0bf7ff6b 100644 --- a/scm-ui/ui-components/src/buttons/Button.tsx +++ b/scm-ui/ui-components/src/buttons/Button.tsx @@ -94,9 +94,11 @@ class Button extends React.Component { - - {label} {children} - + {(label || children) && ( + + {label} {children} + + )} ); } diff --git a/scm-ui/ui-webapp/public/locales/de/repos.json b/scm-ui/ui-webapp/public/locales/de/repos.json index a0b6ef015b..b8510069c0 100644 --- a/scm-ui/ui-webapp/public/locales/de/repos.json +++ b/scm-ui/ui-webapp/public/locales/de/repos.json @@ -90,6 +90,19 @@ }, "table": { "tags": "Tags" + }, + "create": { + "form": { + "field": { + "name": { + "label": "Name" + } + } + }, + "title": "Neuen Tag anlegen", + "hint": "Der Tag wird automatisch mit ihrem Standardschlüssel vom SCM-Manager signiert.", + "confirm": "Tag erstellen", + "cancel": "Abbrechen" } }, "tag": { @@ -156,6 +169,9 @@ "buttons": { "details": "Details", "sources": "Sources" + }, + "tag": { + "create": "Tag erstellen" } }, "commit": { diff --git a/scm-ui/ui-webapp/public/locales/en/repos.json b/scm-ui/ui-webapp/public/locales/en/repos.json index f2f6f31cea..6cf48d8503 100644 --- a/scm-ui/ui-webapp/public/locales/en/repos.json +++ b/scm-ui/ui-webapp/public/locales/en/repos.json @@ -90,6 +90,19 @@ }, "table": { "tags": "Tags" + }, + "create": { + "form": { + "field": { + "name": { + "label": "Name" + } + } + }, + "title": "Create a new tag", + "hint": "The tag will be automatically signed with your default key by the SCM-Manager.", + "confirm": "Create Tag", + "cancel": "Cancel" } }, "tag": { @@ -156,6 +169,9 @@ "more": "{{count}} more", "count": "{{count}} Contributor", "count_plural": "{{count}} Contributors" + }, + "tag": { + "create": "Create Tag" } }, "commit": { diff --git a/scm-ui/ui-webapp/src/repos/components/changesets/ChangesetDetails.tsx b/scm-ui/ui-webapp/src/repos/components/changesets/ChangesetDetails.tsx index be9a70dfc8..2b5284235d 100644 --- a/scm-ui/ui-webapp/src/repos/components/changesets/ChangesetDetails.tsx +++ b/scm-ui/ui-webapp/src/repos/components/changesets/ChangesetDetails.tsx @@ -26,7 +26,7 @@ import { Trans, useTranslation, WithTranslation, withTranslation } from "react-i import classNames from "classnames"; import styled from "styled-components"; import { ExtensionPoint } from "@scm-manager/ui-extensions"; -import { Changeset, ParentChangeset, Repository } from "@scm-manager/ui-types"; +import { Changeset, Link, ParentChangeset, Repository } from "@scm-manager/ui-types"; import { AvatarImage, AvatarWrapper, @@ -41,7 +41,10 @@ import { FileControlFactory, Icon, Level, - SignatureIcon + SignatureIcon, + Modal, + InputField, + apiClient } from "@scm-manager/ui-components"; import ContributorTable from "./ContributorTable"; import { Link as ReactLink } from "react-router-dom"; @@ -50,6 +53,7 @@ type Props = WithTranslation & { changeset: Changeset; repository: Repository; fileControlFactory?: FileControlFactory; + refetchChangeset?: (re) => void; }; type State = { @@ -82,11 +86,12 @@ const ContributorLine = styled.div` `; const ContributorColumn = styled.p` - flex-grow: 1; + flex-grow: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; + margin-right: 16px; `; const CountColumn = styled.p` @@ -159,109 +164,154 @@ const Contributors: FC<{ changeset: Changeset }> = ({ changeset }) => { ); }; -class ChangesetDetails extends React.Component { - constructor(props: Props) { - super(props); - this.state = { - collapsed: false - }; - } +const ChangesetDetails: FC = ({ changeset, repository, fileControlFactory, t , refetchChangeset}) => { + const [collapsed, setCollapsed] = useState(false); + const [isTagCreationModalVisible, setTagCreationModalVisible] = useState(false); + const [newTagName, setNewTagName] = useState(""); - render() { - const { changeset, repository, fileControlFactory, t } = this.props; - const { collapsed } = this.state; + const description = changesets.parseDescription(changeset.description); + const id = ; + const date = ; + const parents = changeset._embedded.parents.map((parent: ParentChangeset, index: number) => ( + + {parent.id.substring(0, 7)} + + )); + const showCreateButton = "tag" in changeset._links; - const description = changesets.parseDescription(changeset.description); - const id = ; - const date = ; - const parents = changeset._embedded.parents.map((parent: ParentChangeset, index: number) => ( - - {parent.id.substring(0, 7)} - - )); - - return ( - <> -
-

- - - -

-
- - - - - -
- - -

- -

- {parents?.length > 0 && ( - - {t("changeset.parents.label", { count: parents?.length }) + ": "} - {parents} - - )} -
-
-
- -
-
-

- {description.message.split("\n").map((item, key) => { - return ( - - - - -
-
- ); - })} -

-
-
- - } - /> - -
- - ); - } - - collapseDiffs = () => { - this.setState(state => ({ - collapsed: !state.collapsed - })); + const collapseDiffs = () => { + setCollapsed(!collapsed); }; -} + + const createTag = () => { + apiClient + .post((changeset._links["tag"] as Link).href, { + revision: changeset.id, + name: newTagName + }) + .then(() => { + refetchChangeset?.(); + closeTagCreationModal(); + }); + }; + + const closeTagCreationModal = () => { + setNewTagName(""); + setTagCreationModalVisible(false); + }; + + return ( + <> +
+

+ + + +

+
+ + + + + +
+ + +

+ +

+ {parents?.length > 0 && ( + + {t("changeset.parents.label", { count: parents?.length }) + ": "} + {parents} + + )} +
+
+
+ +
+
+ {showCreateButton && ( + + + + } + closeFunction={() => closeTagCreationModal()} + /> + )} +
+
+

+ {description.message.split("\n").map((item, key) => { + return ( + + + + +
+
+ ); + })} +

+
+
+ + } + /> + +
+ + ); +}; export default withTranslation("repos")(ChangesetDetails); diff --git a/scm-ui/ui-webapp/src/repos/containers/ChangesetView.tsx b/scm-ui/ui-webapp/src/repos/containers/ChangesetView.tsx index fd9c55d32b..20791822aa 100644 --- a/scm-ui/ui-webapp/src/repos/containers/ChangesetView.tsx +++ b/scm-ui/ui-webapp/src/repos/containers/ChangesetView.tsx @@ -29,6 +29,7 @@ import { WithTranslation, withTranslation } from "react-i18next"; import { Changeset, Repository } from "@scm-manager/ui-types"; import { ErrorPage, Loading } from "@scm-manager/ui-components"; import { + fetchChangeset, fetchChangesetIfNeeded, getChangeset, getFetchChangesetFailure, @@ -45,6 +46,7 @@ type Props = WithTranslation & { loading: boolean; error: Error; fetchChangesetIfNeeded: (repository: Repository, id: string) => void; + refetchChangeset: (repository: Repository, id: string) => void; match: any; }; @@ -62,7 +64,7 @@ class ChangesetView extends React.Component { } render() { - const { changeset, loading, error, t, repository, fileControlFactoryFactory } = this.props; + const { changeset, loading, error, t, repository, fileControlFactoryFactory, refetchChangeset } = this.props; if (error) { return ; @@ -75,6 +77,7 @@ class ChangesetView extends React.Component { changeset={changeset} repository={repository} fileControlFactory={fileControlFactoryFactory && fileControlFactoryFactory(changeset)} + refetchChangeset={() => refetchChangeset(repository, changeset.id)} /> ); } @@ -98,6 +101,9 @@ const mapDispatchToProps = (dispatch: any) => { return { fetchChangesetIfNeeded: (repository: Repository, id: string) => { dispatch(fetchChangesetIfNeeded(repository, id)); + }, + refetchChangeset: (repository: Repository, id: string) => { + dispatch(fetchChangeset(repository, id)); } }; }; diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/DefaultChangesetToChangesetDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/DefaultChangesetToChangesetDtoMapper.java index 53e6d52c0a..69977065e7 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/DefaultChangesetToChangesetDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/DefaultChangesetToChangesetDtoMapper.java @@ -130,6 +130,7 @@ public abstract class DefaultChangesetToChangesetDtoMapper extends HalAppenderMa embeddedBuilder.with("tags", tagCollectionToDtoMapper.getTagDtoList(namespace, name, getListOfObjects(source.getTags(), tags::getTagByName))); } + linksBuilder.single(link("tag", resourceLinks.tag().create(namespace, name))); } if (repositoryService.isSupported(Command.BRANCHES)) { embeddedBuilder.with("branches", branchCollectionToDtoMapper.getBranchDtoList(repository, diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ResourceLinks.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ResourceLinks.java index f24490eef1..79cfc3ace0 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ResourceLinks.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ResourceLinks.java @@ -449,6 +449,10 @@ class ResourceLinks { return tagLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("tags").parameters().method("delete").parameters(tagName).href(); } + String create(String namespace, String name) { + return tagLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("tags").parameters().method("create").parameters().href(); + } + String all(String namespace, String name) { return tagLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("tags").parameters().method("getAll").parameters().href(); } From dc4607935b7c86bf065cdd1176f342c1b0eec3e9 Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Fri, 27 Nov 2020 10:48:56 +0100 Subject: [PATCH 08/35] improve ux --- scm-ui/ui-webapp/public/locales/de/repos.json | 3 +- scm-ui/ui-webapp/public/locales/en/repos.json | 3 +- .../changesets/ChangesetDetails.tsx | 105 +++++++----------- .../components/changesets/CreateTagModal.tsx | 88 +++++++++++++++ 4 files changed, 130 insertions(+), 69 deletions(-) create mode 100644 scm-ui/ui-webapp/src/repos/components/changesets/CreateTagModal.tsx diff --git a/scm-ui/ui-webapp/public/locales/de/repos.json b/scm-ui/ui-webapp/public/locales/de/repos.json index b8510069c0..7647a67d60 100644 --- a/scm-ui/ui-webapp/public/locales/de/repos.json +++ b/scm-ui/ui-webapp/public/locales/de/repos.json @@ -95,7 +95,8 @@ "form": { "field": { "name": { - "label": "Name" + "label": "Name", + "error": "Dieser Tag existiert bereits." } } }, diff --git a/scm-ui/ui-webapp/public/locales/en/repos.json b/scm-ui/ui-webapp/public/locales/en/repos.json index 6cf48d8503..fde688516e 100644 --- a/scm-ui/ui-webapp/public/locales/en/repos.json +++ b/scm-ui/ui-webapp/public/locales/en/repos.json @@ -95,7 +95,8 @@ "form": { "field": { "name": { - "label": "Name" + "label": "Name", + "error": "This tag already exists." } } }, diff --git a/scm-ui/ui-webapp/src/repos/components/changesets/ChangesetDetails.tsx b/scm-ui/ui-webapp/src/repos/components/changesets/ChangesetDetails.tsx index 2b5284235d..b730b74101 100644 --- a/scm-ui/ui-webapp/src/repos/components/changesets/ChangesetDetails.tsx +++ b/scm-ui/ui-webapp/src/repos/components/changesets/ChangesetDetails.tsx @@ -26,7 +26,7 @@ import { Trans, useTranslation, WithTranslation, withTranslation } from "react-i import classNames from "classnames"; import styled from "styled-components"; import { ExtensionPoint } from "@scm-manager/ui-extensions"; -import { Changeset, Link, ParentChangeset, Repository } from "@scm-manager/ui-types"; +import {Changeset, Link, ParentChangeset, Repository, Tag} from "@scm-manager/ui-types"; import { AvatarImage, AvatarWrapper, @@ -42,22 +42,18 @@ import { Icon, Level, SignatureIcon, - Modal, - InputField, - apiClient + Tooltip, + ErrorNotification } from "@scm-manager/ui-components"; import ContributorTable from "./ContributorTable"; import { Link as ReactLink } from "react-router-dom"; +import CreateTagModal from "./CreateTagModal"; type Props = WithTranslation & { changeset: Changeset; repository: Repository; fileControlFactory?: FileControlFactory; - refetchChangeset?: (re) => void; -}; - -type State = { - collapsed: boolean; + refetchChangeset?: () => void; }; const RightMarginP = styled.p` @@ -91,7 +87,6 @@ const ContributorColumn = styled.p` text-overflow: ellipsis; white-space: nowrap; min-width: 0; - margin-right: 16px; `; const CountColumn = styled.p` @@ -113,7 +108,6 @@ const ContributorToggleLine = styled.p` const ChangesetSummary = styled.div` display: flex; - justify-content: space-between; `; const SeparatedParents = styled.div` @@ -152,7 +146,7 @@ const Contributors: FC<{ changeset: Changeset }> = ({ changeset }) => { {signatureIcon} - + ( {t("changeset.contributors.count", { count: countContributors(changeset) })} @@ -164,10 +158,10 @@ const Contributors: FC<{ changeset: Changeset }> = ({ changeset }) => { ); }; -const ChangesetDetails: FC = ({ changeset, repository, fileControlFactory, t , refetchChangeset}) => { +const ChangesetDetails: FC = ({ changeset, repository, fileControlFactory, t, refetchChangeset }) => { const [collapsed, setCollapsed] = useState(false); const [isTagCreationModalVisible, setTagCreationModalVisible] = useState(false); - const [newTagName, setNewTagName] = useState(""); + const [error, setError] = useState(); const description = changesets.parseDescription(changeset.description); const id = ; @@ -183,22 +177,9 @@ const ChangesetDetails: FC = ({ changeset, repository, fileControlFactory setCollapsed(!collapsed); }; - const createTag = () => { - apiClient - .post((changeset._links["tag"] as Link).href, { - revision: changeset.id, - name: newTagName - }) - .then(() => { - refetchChangeset?.(); - closeTagCreationModal(); - }); - }; - - const closeTagCreationModal = () => { - setNewTagName(""); - setTagCreationModalVisible(false); - }; + if (error) { + return ; + } return ( <> @@ -238,43 +219,33 @@ const ChangesetDetails: FC = ({ changeset, repository, fileControlFactory
-
- {showCreateButton && ( - - - - } - closeFunction={() => closeTagCreationModal()} - /> - )} -
+ + {showCreateButton && ( +
+ +
+ )} + {isTagCreationModalVisible && ( + tag.name)} + onClose={() => setTagCreationModalVisible(false)} + onCreated={() => { + refetchChangeset?.(); + setTagCreationModalVisible(false); + }} + onError={setError} + tagCreationLink={(changeset._links["tag"] as Link).href} + /> + )}

{description.message.split("\n").map((item, key) => { diff --git a/scm-ui/ui-webapp/src/repos/components/changesets/CreateTagModal.tsx b/scm-ui/ui-webapp/src/repos/components/changesets/CreateTagModal.tsx new file mode 100644 index 0000000000..1e83d784a0 --- /dev/null +++ b/scm-ui/ui-webapp/src/repos/components/changesets/CreateTagModal.tsx @@ -0,0 +1,88 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React, {FC, useEffect, useState} from "react"; +import { Modal, InputField, Button, apiClient } from "@scm-manager/ui-components"; +import { WithTranslation, withTranslation } from "react-i18next"; + +type Props = WithTranslation & { + tagCreationLink: string; + tagNames: string[]; + onClose: () => void; + onCreated: () => void; + onError: (error: Error) => void; + revision: string; +}; + +const CreateTagModal: FC = ({ t, onClose, tagCreationLink, onCreated, onError, revision, tagNames }) => { + const [newTagName, setNewTagName] = useState(""); + const [loading, setLoading] = useState(false); + + const createTag = () => { + setLoading(true); + apiClient + .post(tagCreationLink, { + revision, + name: newTagName + }) + .then(onCreated) + .catch(onError) + .finally(() => setLoading(false)); + }; + + const isInvalid = () => { + return tagNames.includes(newTagName); + }; + + return ( + + setNewTagName(val)} + value={newTagName} + validationError={isInvalid()} + errorMessage={t("tags.create.form.field.name.error")} + /> +

{t("tags.create.hint")}
+ + } + footer={ + <> + + + + } + closeFunction={onClose} + /> + ); +}; + +export default withTranslation("repos")(CreateTagModal); From 6dbbe7c8170102ede0039d5688948c99008e88e4 Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Fri, 27 Nov 2020 11:03:11 +0100 Subject: [PATCH 09/35] display tag signature --- scm-ui/ui-types/src/Changesets.ts | 12 +----- scm-ui/ui-types/src/Signature.ts | 37 +++++++++++++++++++ scm-ui/ui-types/src/Tags.ts | 2 + .../src/repos/tags/components/TagDetail.tsx | 9 +++-- 4 files changed, 46 insertions(+), 14 deletions(-) create mode 100644 scm-ui/ui-types/src/Signature.ts diff --git a/scm-ui/ui-types/src/Changesets.ts b/scm-ui/ui-types/src/Changesets.ts index 81acd09c92..561a8c5045 100644 --- a/scm-ui/ui-types/src/Changesets.ts +++ b/scm-ui/ui-types/src/Changesets.ts @@ -26,6 +26,7 @@ import {Collection, Link, Links} from "./hal"; import { Tag } from "./Tags"; import { Branch } from "./Branches"; import { Person } from "./Person"; +import {Signature} from "./Signature"; export type Changeset = Collection & { id: string; @@ -42,16 +43,7 @@ export type Changeset = Collection & { }; }; -export type Signature = { - keyId: string; - type: string; - status: "VERIFIED" | "NOT_FOUND" | "INVALID"; - owner?: string; - contacts?: Person[]; - _links?: { - rawKey?: Link; - }; -} + export type Contributor = { person: Person; diff --git a/scm-ui/ui-types/src/Signature.ts b/scm-ui/ui-types/src/Signature.ts new file mode 100644 index 0000000000..ee9cb72b16 --- /dev/null +++ b/scm-ui/ui-types/src/Signature.ts @@ -0,0 +1,37 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { Person } from "./Person"; +import { Link } from "./hal"; + +export type Signature = { + keyId: string; + type: string; + status: "VERIFIED" | "NOT_FOUND" | "INVALID"; + owner?: string; + contacts?: Person[]; + _links?: { + rawKey?: Link; + }; +}; diff --git a/scm-ui/ui-types/src/Tags.ts b/scm-ui/ui-types/src/Tags.ts index 67fcf734dd..41e9bb0c6c 100644 --- a/scm-ui/ui-types/src/Tags.ts +++ b/scm-ui/ui-types/src/Tags.ts @@ -23,10 +23,12 @@ */ import { Links } from "./hal"; +import {Signature} from "./Signature"; export type Tag = { name: string; revision: string; date?: Date; + signatures: Signature[]; _links: Links; }; diff --git a/scm-ui/ui-webapp/src/repos/tags/components/TagDetail.tsx b/scm-ui/ui-webapp/src/repos/tags/components/TagDetail.tsx index 0bbcdb56dc..5db1fe962f 100644 --- a/scm-ui/ui-webapp/src/repos/tags/components/TagDetail.tsx +++ b/scm-ui/ui-webapp/src/repos/tags/components/TagDetail.tsx @@ -25,7 +25,7 @@ import React, { FC } from "react"; import { useTranslation } from "react-i18next"; import { Repository, Tag } from "@scm-manager/ui-types"; -import { DateFromNow } from "@scm-manager/ui-components"; +import { DateFromNow, SignatureIcon } from "@scm-manager/ui-components"; import styled from "styled-components"; import TagButtonGroup from "./TagButtonGroup"; @@ -58,9 +58,10 @@ const TagDetail: FC = ({ tag, repository }) => { return (
- - {tag.name} - + + {tag.name} + + {t("tags.overview.created")} From 6652a039dd373c17a62495ce80fac72b34495534 Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Fri, 27 Nov 2020 12:40:02 +0100 Subject: [PATCH 10/35] fix unit tests --- .../java/sonia/scm/repository/GitUtil.java | 347 ++++++------------ .../repository/spi/GitTagsCommandTest.java | 19 +- scm-ui/ui-types/src/Changesets.ts | 6 +- scm-ui/ui-types/src/index.ts | 13 +- 4 files changed, 145 insertions(+), 240 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java index f41628f8e0..5650f59938 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java @@ -30,7 +30,6 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Strings; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; -import org.checkerframework.checker.nullness.Opt; import org.eclipse.jgit.api.FetchCommand; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; @@ -53,7 +52,6 @@ import org.eclipse.jgit.transport.RefSpec; import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.LfsFactory; -import org.eclipse.jgit.util.RawParseUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sonia.scm.ContextEntry; @@ -64,11 +62,9 @@ import sonia.scm.util.Util; import sonia.scm.web.GitUserAgentProvider; import javax.servlet.http.HttpServletRequest; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.util.Arrays; import java.util.Collections; import java.util.Map; import java.util.Optional; @@ -80,73 +76,89 @@ import static java.util.Optional.of; //~--- JDK imports ------------------------------------------------------------ /** - * * @author Sebastian Sdorra */ -public final class GitUtil -{ +public final class GitUtil { private static final GitUserAgentProvider GIT_USER_AGENT_PROVIDER = new GitUserAgentProvider(); - /** Field description */ + /** + * Field description + */ public static final String REF_HEAD = "HEAD"; - /** Field description */ + /** + * Field description + */ public static final String REF_HEAD_PREFIX = "refs/heads/"; - /** Field description */ + /** + * Field description + */ public static final String REF_MASTER = "master"; - /** Field description */ + /** + * Field description + */ private static final String DIRECTORY_DOTGIT = ".git"; - /** Field description */ + /** + * Field description + */ private static final String DIRECTORY_OBJETCS = "objects"; - /** Field description */ + /** + * Field description + */ private static final String DIRECTORY_REFS = "refs"; - /** Field description */ + /** + * Field description + */ private static final String PREFIX_HEADS = "refs/heads/"; - /** Field description */ + /** + * Field description + */ private static final String PREFIX_TAG = "refs/tags/"; - /** Field description */ + /** + * Field description + */ private static final String REFSPEC = "+refs/heads/*:refs/remote/scm/%s/*"; - /** Field description */ + /** + * Field description + */ private static final String REMOTE_REF = "refs/remote/scm/%s/%s"; - /** Field description */ + /** + * Field description + */ private static final int TIMEOUT = 5; - /** Field description */ - private static final String USERAGENT_GIT = "git/"; - - /** the logger for GitUtil */ + /** + * the logger for GitUtil + */ private static final Logger logger = LoggerFactory.getLogger(GitUtil.class); //~--- constructors --------------------------------------------------------- /** * Constructs ... - * */ - private GitUtil() {} + private GitUtil() { + } //~--- methods -------------------------------------------------------------- /** * Method description * - * * @param repo */ - public static void close(org.eclipse.jgit.lib.Repository repo) - { - if (repo != null) - { + public static void close(org.eclipse.jgit.lib.Repository repo) { + if (repo != null) { repo.close(); } } @@ -154,42 +166,30 @@ public final class GitUtil /** * TODO cache * - * * @param repository * @param revWalk - * - * * @return */ public static Multimap createTagMap(org.eclipse.jgit.lib.Repository repository, - RevWalk revWalk) - { + RevWalk revWalk) { Multimap tags = ArrayListMultimap.create(); Map tagMap = repository.getTags(); - if (tagMap != null) - { - for (Map.Entry e : tagMap.entrySet()) - { - try - { + if (tagMap != null) { + for (Map.Entry e : tagMap.entrySet()) { + try { RevCommit c = getCommit(repository, revWalk, e.getValue()); - if (c != null) - { + if (c != null) { tags.put(c.getId(), e.getKey()); - } - else if (logger.isWarnEnabled()) - { + } else if (logger.isWarnEnabled()) { logger.warn("could not find commit for tag {}", e.getKey()); } - } - catch (IOException ex) - { + } catch (IOException ex) { logger.error("could not read commit for ref", ex); } @@ -200,8 +200,7 @@ public final class GitUtil } public static FetchResult fetch(Git git, File directory, Repository remoteRepository) { - try - { + try { FetchCommand fetch = git.fetch(); fetch.setRemote(directory.getAbsolutePath()); @@ -209,9 +208,7 @@ public final class GitUtil fetch.setTimeout((int) TimeUnit.MINUTES.toSeconds(TIMEOUT)); return fetch.call(); - } - catch (GitAPIException ex) - { + } catch (GitAPIException ex) { throw new InternalRepositoryException(ContextEntry.ContextBuilder.entity("Remote", directory.toString()).in(remoteRepository), "could not fetch", ex); } } @@ -219,29 +216,22 @@ public final class GitUtil /** * Method description * - * * @param directory - * * @return - * * @throws IOException */ public static org.eclipse.jgit.lib.Repository open(File directory) - throws IOException - { + throws IOException { FS fs = FS.DETECTED; FileRepositoryBuilder builder = new FileRepositoryBuilder(); builder.setFS(fs); - if (isGitDirectory(fs, directory)) - { + if (isGitDirectory(fs, directory)) { // bare repository builder.setGitDir(directory).setBare(); - } - else - { + } else { builder.setWorkTree(directory); } @@ -251,13 +241,10 @@ public final class GitUtil /** * Method description * - * * @param formatter */ - public static void release(DiffFormatter formatter) - { - if (formatter != null) - { + public static void release(DiffFormatter formatter) { + if (formatter != null) { formatter.close(); } } @@ -265,13 +252,10 @@ public final class GitUtil /** * Method description * - * * @param walk */ - public static void release(TreeWalk walk) - { - if (walk != null) - { + public static void release(TreeWalk walk) { + if (walk != null) { walk.close(); } } @@ -279,13 +263,10 @@ public final class GitUtil /** * Method description * - * * @param walk */ - public static void release(RevWalk walk) - { - if (walk != null) - { + public static void release(RevWalk walk) { + if (walk != null) { walk.close(); } } @@ -295,17 +276,13 @@ public final class GitUtil /** * Method description * - * * @param ref - * * @return */ - public static String getBranch(Ref ref) - { + public static String getBranch(Ref ref) { String branch = null; - if (ref != null) - { + if (ref != null) { branch = getBranch(ref.getName()); } @@ -315,17 +292,13 @@ public final class GitUtil /** * Method description * - * * @param name - * * @return */ - public static String getBranch(String name) - { + public static String getBranch(String name) { String branch = null; - if (Util.isNotEmpty(name) && name.startsWith(PREFIX_HEADS)) - { + if (Util.isNotEmpty(name) && name.startsWith(PREFIX_HEADS)) { branch = name.substring(PREFIX_HEADS.length()); } @@ -336,18 +309,15 @@ public final class GitUtil * Returns {@code true} if the provided reference name is a branch name. * * @param refName reference name - * * @return {@code true} if the name is a branch name - * * @since 1.50 */ - public static boolean isBranch(String refName) - { + public static boolean isBranch(String refName) { return Strings.nullToEmpty(refName).startsWith(PREFIX_HEADS); } public static Ref getBranchIdOrCurrentHead(org.eclipse.jgit.lib.Repository gitRepository, String requestedBranch) throws IOException { - if ( Strings.isNullOrEmpty(requestedBranch) ) { + if (Strings.isNullOrEmpty(requestedBranch)) { logger.trace("no default branch configured, use repository head as default"); Optional repositoryHeadRef = GitUtil.getRepositoryHeadRef(gitRepository); return repositoryHeadRef.orElse(null); @@ -359,37 +329,28 @@ public final class GitUtil /** * Method description * - * * @param repo * @param branchName - * * @return - * * @throws IOException */ public static Ref getBranchId(org.eclipse.jgit.lib.Repository repo, - String branchName) - throws IOException - { + String branchName) + throws IOException { Ref ref = null; - if (!branchName.startsWith(REF_HEAD)) - { + if (!branchName.startsWith(REF_HEAD)) { branchName = PREFIX_HEADS.concat(branchName); } checkBranchName(repo, branchName); - try - { + try { ref = repo.findRef(branchName); - if (ref == null) - { + if (ref == null) { logger.warn("could not find branch for {}", branchName); } - } - catch (IOException ex) - { + } catch (IOException ex) { logger.warn("error occured during resolve of branch id", ex); } @@ -426,21 +387,17 @@ public final class GitUtil * If the given ref is for a tag, the commit that this tag belongs to is returned instead. */ public static RevCommit getCommit(org.eclipse.jgit.lib.Repository repository, - RevWalk revWalk, Ref ref) - throws IOException - { + RevWalk revWalk, Ref ref) + throws IOException { RevCommit commit = null; ObjectId id = ref.getPeeledObjectId(); - if (id == null) - { + if (id == null) { id = ref.getObjectId(); } - if (id != null) - { - if (revWalk == null) - { + if (id != null) { + if (revWalk == null) { revWalk = new RevWalk(repository); } @@ -451,16 +408,13 @@ public final class GitUtil } public static RevTag getTag(org.eclipse.jgit.lib.Repository repository, - RevWalk revWalk, Ref ref) - throws IOException - { + RevWalk revWalk, Ref ref) + throws IOException { RevTag tag = null; ObjectId id = ref.getObjectId(); - if (id != null) - { - if (revWalk == null) - { + if (id != null) { + if (revWalk == null) { revWalk = new RevWalk(repository); } @@ -473,13 +427,10 @@ public final class GitUtil /** * Method description * - * * @param commit - * * @return */ - public static long getCommitTime(RevCommit commit) - { + public static long getCommitTime(RevCommit commit) { long date = commit.getCommitTime(); date = date * 1000; @@ -490,17 +441,13 @@ public final class GitUtil /** * Method description * - * * @param objectId - * * @return */ - public static String getId(AnyObjectId objectId) - { + public static String getId(AnyObjectId objectId) { String id = Util.EMPTY_STRING; - if (objectId != null) - { + if (objectId != null) { id = objectId.name(); } @@ -510,44 +457,27 @@ public final class GitUtil /** * Method description * - * * @param repository * @param id - * * @return - * * @throws IOException */ public static Ref getRefForCommit(org.eclipse.jgit.lib.Repository repository, - ObjectId id) - throws IOException - { + ObjectId id) + throws IOException { Ref ref = null; - RevWalk walk = null; - - try - { - walk = new RevWalk(repository); + try (RevWalk walk = new RevWalk(repository)) { RevCommit commit = walk.parseCommit(id); - for (Map.Entry e : repository.getAllRefs().entrySet()) - { - if (e.getKey().startsWith(Constants.R_HEADS)) - { - if (walk.isMergedInto(commit, - walk.parseCommit(e.getValue().getObjectId()))) - { - ref = e.getValue(); - } + for (Map.Entry e : repository.getAllRefs().entrySet()) { + if (e.getKey().startsWith(Constants.R_HEADS) && walk.isMergedInto(commit, + walk.parseCommit(e.getValue().getObjectId()))) { + ref = e.getValue(); } } } - finally - { - release(walk); - } return ref; } @@ -599,26 +529,19 @@ public final class GitUtil /** * Method description * - * * @param repo * @param revision - * * @return - * * @throws IOException */ public static ObjectId getRevisionId(org.eclipse.jgit.lib.Repository repo, - String revision) - throws IOException - { + String revision) + throws IOException { ObjectId revId; - if (Util.isNotEmpty(revision)) - { + if (Util.isNotEmpty(revision)) { revId = repo.resolve(revision); - } - else - { + } else { revId = getRepositoryHead(repo); } @@ -628,34 +551,27 @@ public final class GitUtil /** * Method description * - * * @param repository * @param localBranch - * * @return */ public static String getScmRemoteRefName(Repository repository, - Ref localBranch) - { + Ref localBranch) { return getScmRemoteRefName(repository, localBranch.getName()); } /** * Method description * - * * @param repository * @param localBranch - * * @return */ public static String getScmRemoteRefName(Repository repository, - String localBranch) - { + String localBranch) { String branch = localBranch; - if (localBranch.startsWith(REF_HEAD_PREFIX)) - { + if (localBranch.startsWith(REF_HEAD_PREFIX)) { branch = localBranch.substring(REF_HEAD_PREFIX.length()); } @@ -666,16 +582,12 @@ public final class GitUtil * Returns the name of the tag or {@code null} if the the ref is not a tag. * * @param refName ref name - * * @return name of tag or {@link null} - * * @since 1.50 */ - public static String getTagName(String refName) - { + public static String getTagName(String refName) { String tagName = null; - if (refName.startsWith(PREFIX_TAG)) - { + if (refName.startsWith(PREFIX_TAG)) { tagName = refName.substring(PREFIX_TAG.length()); } @@ -685,17 +597,13 @@ public final class GitUtil /** * Method description * - * * @param ref - * * @return */ - public static String getTagName(Ref ref) - { + public static String getTagName(Ref ref) { String name = ref.getName(); - if (name.startsWith(PREFIX_TAG)) - { + if (name.startsWith(PREFIX_TAG)) { name = name.substring(PREFIX_TAG.length()); } @@ -706,8 +614,8 @@ public final class GitUtil public static Optional getTagSignature(RevObject revObject, GPG gpg, RevWalk revWalk) throws IOException { if (revObject instanceof RevTag) { - final byte[] bytes = revWalk.getObjectReader().open(revObject.getId()).getBytes(); - final String message = new String(bytes); + final byte[] messageBytes = revWalk.getObjectReader().open(revObject.getId()).getBytes(); + final String message = new String(messageBytes); final int signatureStartIndex = message.indexOf(GPG_HEADER); if (signatureStartIndex < 0) { return Optional.empty(); @@ -729,7 +637,7 @@ public final class GitUtil PublicKey publicKey = publicKeyById.get(); - boolean verified = publicKey.verify(message.substring(0, signatureStartIndex - 1).getBytes(), signature.getBytes()); + boolean verified = publicKey.verify(messageBytes, signature.getBytes()); return Optional.of(new Signature( publicKeyId, "gpg", @@ -744,71 +652,56 @@ public final class GitUtil /** * Returns true if the request comes from a git client. * - * * @param request servlet request - * * @return true if the client is git */ - public static boolean isGitClient(HttpServletRequest request) - { + public static boolean isGitClient(HttpServletRequest request) { return GIT_USER_AGENT_PROVIDER.parseUserAgent(request.getHeader(HttpUtil.HEADER_USERAGENT)) != null; } /** * Method description * - * * @param dir - * * @return */ - public static boolean isGitDirectory(File dir) - { + public static boolean isGitDirectory(File dir) { return isGitDirectory(FS.DETECTED, dir); } /** * Method description * - * * @param fs * @param dir - * * @return */ - public static boolean isGitDirectory(FS fs, File dir) - { + public static boolean isGitDirectory(FS fs, File dir) { //J- return fs.resolve(dir, DIRECTORY_OBJETCS).exists() && fs.resolve(dir, DIRECTORY_REFS).exists() - &&!fs.resolve(dir, DIRECTORY_DOTGIT).exists(); + && !fs.resolve(dir, DIRECTORY_DOTGIT).exists(); //J+ } /** * Method description * - * * @param ref - * * @return */ - public static boolean isHead(String ref) - { + public static boolean isHead(String ref) { return ref.startsWith(REF_HEAD_PREFIX); } /** * Method description * - * * @param id - * * @return */ - public static boolean isValidObjectId(ObjectId id) - { - return (id != null) &&!id.equals(ObjectId.zeroId()); + public static boolean isValidObjectId(ObjectId id) { + return (id != null) && !id.equals(ObjectId.zeroId()); } /** @@ -850,25 +743,20 @@ public final class GitUtil /** * Method description * - * * @param repo * @param branchName - * * @throws IOException */ @VisibleForTesting static void checkBranchName(org.eclipse.jgit.lib.Repository repo, - String branchName) - throws IOException - { - if (branchName.contains("..")) - { + String branchName) + throws IOException { + if (branchName.contains("..")) { File repoDirectory = repo.getDirectory(); File branchFile = new File(repoDirectory, branchName); if (!branchFile.getCanonicalPath().startsWith( - repoDirectory.getCanonicalPath())) - { + repoDirectory.getCanonicalPath())) { logger.error( "branch \"{}\" is outside of the repository. It looks like path traversal attack", branchName); @@ -882,13 +770,10 @@ public final class GitUtil /** * Method description * - * * @param repository - * * @return */ - private static RefSpec createRefSpec(Repository repository) - { + private static RefSpec createRefSpec(Repository repository) { return new RefSpec(String.format(REFSPEC, repository.getId())); } } diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagsCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagsCommandTest.java index 456096d736..f93fd801c1 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagsCommandTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagsCommandTest.java @@ -84,10 +84,23 @@ public class GitTagsCommandTest extends AbstractGitCommandTestBase { "1vSkcjK26RqhAqCjNLSagM8ATZrh+g==\n" + "=kUKm\n" + "-----END PGP SIGNATURE-----\n"; - String signedContent = "Tagger: Arthur Dent \n" + - "Date: Tue Nov 24 21:37:46 2020 +0100\n" + + String signedContent = "object 592d797cd36432e591416e8b2b98154f4f163411\n" + + "type commit\n" + + "tag signedtag\n" + + "tagger Arthur Dent 1606248906 +0100\n" + "\n" + - "this tag is signed"; + "this tag is signed\n" + + "-----BEGIN PGP SIGNATURE-----\n" + + "\n" + + "iQEzBAABCgAdFiEEK6J3IfETwAXMFvBrrmPvvEnxQM8FAl+9acoACgkQrmPvvEnx\n" + + "QM9abwgAnGP+Y/Ijli+PAsimfOmZQWYepjptoOv9m7i3bnHv8V+Qg6cm51I3E0YV\n" + + "R2QaxxzW9PgS4hcES+L1qs8Lwo18RurF469eZEmNb8DcUFJ3sEWeHlIl5wZNNo/v\n" + + "jJm0d9LNcSmtAIiQ8eDMoGdFXJzHewGickLOSsQGmfZgZus4Qlsh7r3BZTI1Zwd/\n" + + "6jaBFctX13FuepCTxq2SjEfRaQHIYkyFQq2o6mjL5S2qfYJ/S//gcCCzxllQrisF\n" + + "5fRW3LzLI4eXFH0vua7+UzNS2Rwpifg2OENJA/Kn+3R36LWEGxFK9pNqjVPRAcQj\n" + + "1vSkcjK26RqhAqCjNLSagM8ATZrh+g==\n" + + "=kUKm\n" + + "-----END PGP SIGNATURE-----\n"; when(publicKey.verify(signedContent.getBytes(), signature.getBytes())).thenReturn(true); final GitContext gitContext = createContext(); diff --git a/scm-ui/ui-types/src/Changesets.ts b/scm-ui/ui-types/src/Changesets.ts index 561a8c5045..ab7fa54e61 100644 --- a/scm-ui/ui-types/src/Changesets.ts +++ b/scm-ui/ui-types/src/Changesets.ts @@ -22,11 +22,11 @@ * SOFTWARE. */ -import {Collection, Link, Links} from "./hal"; +import { Collection, Links } from "./hal"; import { Tag } from "./Tags"; import { Branch } from "./Branches"; import { Person } from "./Person"; -import {Signature} from "./Signature"; +import { Signature } from "./Signature"; export type Changeset = Collection & { id: string; @@ -43,8 +43,6 @@ export type Changeset = Collection & { }; }; - - export type Contributor = { person: Person; type: string; diff --git a/scm-ui/ui-types/src/index.ts b/scm-ui/ui-types/src/index.ts index 35adda77bb..da97204e1a 100644 --- a/scm-ui/ui-types/src/index.ts +++ b/scm-ui/ui-types/src/index.ts @@ -29,14 +29,23 @@ export { Me } from "./Me"; export { DisplayedUser, User } from "./User"; export { Group, Member } from "./Group"; -export { Repository, RepositoryCollection, RepositoryGroup, RepositoryCreation, Namespace, NamespaceCollection } from "./Repositories"; +export { + Repository, + RepositoryCollection, + RepositoryGroup, + RepositoryCreation, + Namespace, + NamespaceCollection +} from "./Repositories"; export { RepositoryType, RepositoryTypeCollection } from "./RepositoryTypes"; export { Branch, BranchRequest } from "./Branches"; export { Person } from "./Person"; -export { Changeset, Contributor, ParentChangeset, Signature } from "./Changesets"; +export { Changeset, Contributor, ParentChangeset } from "./Changesets"; + +export { Signature } from "./Signature"; export { AnnotatedSource, AnnotatedLine } from "./Annotate"; From 11ebba349c393d10144cc4e289698187f482aca6 Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Fri, 27 Nov 2020 13:08:42 +0100 Subject: [PATCH 11/35] fix integration test --- scm-it/src/test/java/sonia/scm/it/RepositoryAccessITCase.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scm-it/src/test/java/sonia/scm/it/RepositoryAccessITCase.java b/scm-it/src/test/java/sonia/scm/it/RepositoryAccessITCase.java index e3311f2296..21d46c45ee 100644 --- a/scm-it/src/test/java/sonia/scm/it/RepositoryAccessITCase.java +++ b/scm-it/src/test/java/sonia/scm/it/RepositoryAccessITCase.java @@ -175,12 +175,12 @@ public class RepositoryAccessITCase { .as("assert tag size") .isNotNull() .size() - .isGreaterThan(0); + .isPositive(); assertThat(response.body().jsonPath().getMap("_embedded.tags.find{it.name=='" + tagName + "'}")) .as("assert tag has attributes for name, revision, date and links") .isNotNull() - .hasSize(4) + .hasSize(5) .containsEntry("name", tagName) .containsEntry("revision", changeset.getId()); From 8ca64c3440cd0d0aa4ceedc929edf1aebef8d265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Fri, 27 Nov 2020 13:35:54 +0100 Subject: [PATCH 12/35] Fix signature check for git tags --- .../main/java/sonia/scm/repository/GitUtil.java | 4 +++- .../scm/repository/spi/GitTagsCommandTest.java | 15 +++------------ 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java index 5650f59938..72d74803d8 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java @@ -65,6 +65,7 @@ import javax.servlet.http.HttpServletRequest; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.util.Arrays; import java.util.Collections; import java.util.Map; import java.util.Optional; @@ -637,7 +638,8 @@ public final class GitUtil { PublicKey publicKey = publicKeyById.get(); - boolean verified = publicKey.verify(messageBytes, signature.getBytes()); + String rawMessage = message.substring(0, signatureStartIndex); + boolean verified = publicKey.verify(rawMessage.getBytes(), signature.getBytes()); return Optional.of(new Signature( publicKeyId, "gpg", diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagsCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagsCommandTest.java index f93fd801c1..fa20318e15 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagsCommandTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagsCommandTest.java @@ -30,6 +30,7 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentMatchers; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import sonia.scm.repository.SignatureStatus; import sonia.scm.repository.Tag; import sonia.scm.security.GPG; import sonia.scm.security.PublicKey; @@ -89,18 +90,7 @@ public class GitTagsCommandTest extends AbstractGitCommandTestBase { "tag signedtag\n" + "tagger Arthur Dent 1606248906 +0100\n" + "\n" + - "this tag is signed\n" + - "-----BEGIN PGP SIGNATURE-----\n" + - "\n" + - "iQEzBAABCgAdFiEEK6J3IfETwAXMFvBrrmPvvEnxQM8FAl+9acoACgkQrmPvvEnx\n" + - "QM9abwgAnGP+Y/Ijli+PAsimfOmZQWYepjptoOv9m7i3bnHv8V+Qg6cm51I3E0YV\n" + - "R2QaxxzW9PgS4hcES+L1qs8Lwo18RurF469eZEmNb8DcUFJ3sEWeHlIl5wZNNo/v\n" + - "jJm0d9LNcSmtAIiQ8eDMoGdFXJzHewGickLOSsQGmfZgZus4Qlsh7r3BZTI1Zwd/\n" + - "6jaBFctX13FuepCTxq2SjEfRaQHIYkyFQq2o6mjL5S2qfYJ/S//gcCCzxllQrisF\n" + - "5fRW3LzLI4eXFH0vua7+UzNS2Rwpifg2OENJA/Kn+3R36LWEGxFK9pNqjVPRAcQj\n" + - "1vSkcjK26RqhAqCjNLSagM8ATZrh+g==\n" + - "=kUKm\n" + - "-----END PGP SIGNATURE-----\n"; + "this tag is signed\n"; when(publicKey.verify(signedContent.getBytes(), signature.getBytes())).thenReturn(true); final GitContext gitContext = createContext(); @@ -111,6 +101,7 @@ public class GitTagsCommandTest extends AbstractGitCommandTestBase { Tag signedTag = tags.get(1); assertThat(signedTag.getSignatures()).isNotEmpty(); + assertThat(signedTag.getSignatures().get(0).getStatus()).isEqualTo(SignatureStatus.VERIFIED); } @Override From 0f7df6d8a8be251dd337993431efbc3900e1cd84 Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Sun, 29 Nov 2020 20:09:59 +0100 Subject: [PATCH 13/35] fix sonarqube finding --- .../sonia/scm/repository/spi/GitTagCommand.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java index ca3bd78c6e..63515d2c2e 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java @@ -128,11 +128,17 @@ public class GitTagCommand extends AbstractGitCommand implements TagCommand { try (Git git = new Git(context.open())) { String name = request.getName(); final Repository repository = git.getRepository(); - Ref tagRef = findTagRef(git, name); + Optional tagRef = findTagRef(git, name); Tag tag; + // Deleting a non-existent tag is a valid action and simply succeeds without + // anything happening. + if (!tagRef.isPresent()) { + return; + } + try (RevWalk walk = new RevWalk(repository)) { - final RevCommit commit = GitUtil.getCommit(repository, walk, tagRef); + final RevCommit commit = GitUtil.getCommit(repository, walk, tagRef.get()); Long tagTime = GitUtil.getTagTime(walk, commit.toObjectId()); tag = new Tag(name, commit.name(), tagTime); } @@ -146,9 +152,9 @@ public class GitTagCommand extends AbstractGitCommand implements TagCommand { } } - private Ref findTagRef(Git git, String name) throws GitAPIException { + private Optional findTagRef(Git git, String name) throws GitAPIException { final String tagRef = "refs/tags/" + name; - return git.tagList().call().stream().filter(it -> it.getName().equals(tagRef)).findAny().get(); + return git.tagList().call().stream().filter(it -> it.getName().equals(tagRef)).findAny(); } private RepositoryHookEvent createTagHookEvent(TagHookContextProvider hookEvent) { From 032982857f06d8c8141450a909b08cda687ff478 Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Mon, 30 Nov 2020 10:01:21 +0100 Subject: [PATCH 14/35] clean up code, fix bugs, improve ux, add docs --- docs/de/user/repo/code.md | 13 +++++++ docs/de/user/repo/tags.md | 17 +++++++++ .../repo/assets/repository-tags-overview.png | Bin 250877 -> 216209 bytes docs/en/user/repo/code.md | 13 ++++++- docs/en/user/repo/tags.md | 19 ++++++++++ scm-ui/ui-components/src/index.ts | 1 + .../src/modals}/CreateTagModal.tsx | 34 +++++++++++++----- scm-ui/ui-webapp/public/locales/de/repos.json | 5 ++- scm-ui/ui-webapp/public/locales/en/repos.json | 5 ++- .../changesets/ChangesetDetails.tsx | 8 ++--- 10 files changed, 99 insertions(+), 16 deletions(-) rename scm-ui/{ui-webapp/src/repos/components/changesets => ui-components/src/modals}/CreateTagModal.tsx (73%) diff --git a/docs/de/user/repo/code.md b/docs/de/user/repo/code.md index a779564ea0..64d6bb1dbd 100644 --- a/docs/de/user/repo/code.md +++ b/docs/de/user/repo/code.md @@ -34,6 +34,19 @@ Beispielsweise wird der Text hitchhiker/HeartOfGold@1a2b3c4 zu einem Link zu dem ![Repository-Code-Changesets](assets/repository-code-changesetDetails.png) +#### Tags + +Alle tags eines Changesets werden in der oberen rechten Ecke der Detailseite angezeigt. + +![Repository-Code-Changesets](assets/repository-code-changeset-with-tag.png) + +#### Tags erstellen + +Neue tags für ein Changeset können direkt in dessen Übersichtsseite erstellt werden. +Es muss lediglich ein gewünschter Name angegeben werden, welcher die gleichen Formatierungsbeschränkungen wie Branches erfüllt. + +![Repository-Code-Changeset-Create-Tag](assets/repository-code-changeset-create-tag.png) + ### Datei Details Nach einem Klick auf eine Datei in den Sources landet man in der Detailansicht der Datei. Dabei sind je nach Dateiformat unterschiedliche Ansichten zu sehen: diff --git a/docs/de/user/repo/tags.md b/docs/de/user/repo/tags.md index 932a8a143b..c5c2bb1bd1 100644 --- a/docs/de/user/repo/tags.md +++ b/docs/de/user/repo/tags.md @@ -7,7 +7,24 @@ Auf der Tags-Übersicht sind die existierenden Tags nach Erstelldatum absteigend ![Tags Übersicht](assets/repository-tags-overview.png) +#### Tags löschen +Tags können direkt von der Übersicht aus gelöscht werden. + ### Tag Detailseite Hier wird ein Befehl zum Arbeiten mit dem Tag auf einer Kommandozeile aufgeführt. ![Tag Detailseite](assets/repository-tag-detailView.png) + +#### Tag-Signaturen +Der Verifizierungsstatus eines Tags wird als Schlüsselsymbol hinter dessen Namen in der Detailansicht dargestellt. + +Ein Tag kann mehrere Signaturen haben. + +Abhängig vom Status der einzelnen Signaturen, wird das Symbol entsprechend eingefärbt: +- wenn mindestens eine Signatur ungültig ist, wird der Schlüssel `rot` dargestellt ANDERNFALLS +- wenn mindestens eine Signatur gültigt ist, wird der Schlüssel `grün` dargestellt ANDERNFALLS +- wird der Schlüssel `grau` dargestellt + +Wird der Mauszeiger über das Symbol bewegt, erscheint eine Liste aller Signaturen des Tags. + +![Tag Signatures](assets/repository-tag-signatures.png) diff --git a/docs/en/user/repo/assets/repository-tags-overview.png b/docs/en/user/repo/assets/repository-tags-overview.png index 32c9d9aaeab06aaf0c88db55efefc7de3d32af15..f4f5b6a47058e064482d857224387354810bbbdc 100644 GIT binary patch literal 216209 zcmV)BK*PU@P)ZgXgFbngSdJ^%n907*naRCt{1 zy5NDuG`Bu_iNbN^?Pg&?Z@M6G|q>X<|8xSPP+#?M*KzrEN;Hz$l^y#2Bo zP)@>tujb1-f6HK*PH;>?1|va0=MgEcWLsg5VfJ?c&su?}C*TWjfZOfp%k%zmY=8I9$% z%#X@3Oya=cKN0!u>qw1HnLegDguyz~-+xr5h55?%>+-eu+UlNehkv@=4!xfhmC03C z^V?Ad{iE~nn;Tw0JovuZ*e6bFx+b%K91kmKep31znM%x9bV7CYS{SqvW68M;lLB*k zHNqT}hysRBJPVCeqp$jq0FjMllMNe_{}^BHtCMtYJ39w*;re(dw1uG760v>AxO)F8 z{ZuwnIz@KF*n(8e21`n9dZ6Pef3GHekCYTft8=oeklyI33C_I{@fX6U8ev0q1MxRc z_7vwc9%MSF_!^ANu~+#~hsw#g#KR$p5!<*bM|F~VZQk)X>_Y#_rUn_I%SG{4zRngu zX1Iold>hCUNy1TeZQr|(Vj|L^YlmC)d{TIE#ZOz`;J1Okc!xeQapBkbID>DgJpn!| z=GrpM%;`3ms?lO~&t1SX&#!;lj``l6ut9G`ql z#s{@sU9Yr|7#7peud)3x-s(&JdWn3?7D6iE6Zuu)JVarH6XAvWR*zGr-xJ%7?8kHT9l?NC#dy+6YMVO&*O$kixi7#LC|f2sSAc|i#p$!>S$?v zxOZ69WMc~pB14a}9i2{NrnlrX%>M)*N&R+>C6#zEDV$?y-B}+kuBT#K8ENdM4W`>v z;#+)xlGrDez3Gt81E@`v_S1Q#oM-rI(}~OJV=XEsu41m&WxSTonPxgge9T<4`Z<S3jMB~F3p9OCE-o@Bil9|clesKPH3N3 ze0Z7SJNr{Q#BW`OLw}6N=R%X{1fLJ%)M#UNW4)Ba9>4Ggc>4^LjUG(AFt)+-a*)f{~$xriGd#%O9hUYYrZIfeRZsKp4v~d#}#77>?xDg9iX$qhQhyBWw`(< zu=#kktP;FO`(G9KFq!*Mr$!Fj{wip4M#+hH(L`tB7(yaQlNw7#DkwO%3R6~Im-NXb zB~8l--HcRqW{Cl0K_omuAhH_dMb6O62g)W(B79tFyHlON0S{C`k1w`kp}Rs;Vw!%@bf(~Vq5&1*1_pt);%|q=2g2Ly zO<(!OQ=zv6#23us876H^K4pSOs1w^`TFf?V@gc-Z_8q&x!J;e@YUPjmtwHb2zWPrA znA2Bk*OSnXX<9nGq+WQvJptPnfbtZZTCU9CXS!`XpNRZuqrMQ)#*J@#TPUhK`db8c z4ul(kvzvhy=VmgT<`J#4zwyz=Ep)Ue&9id$fP>z6XEhoY-y0wNX6a6RkiWFP^_i8* z^pQU)J5cV&F|cOl$0xQl%K=9Ku^oWp$=mj3+3iu#k_tL-oIA7#|TSss?nQHF<`G6p7g9S}6RWqy?DAcDd}8Ab=e zncZMxTpfk&SZpr0R$u$LD?3(Sr_ZZQ-L2|D8INat*ZERt$769nYF8D}4Cxx_vZ~Bw z^4JBy+xEnNDb4rXvraS~^T1;C4S0HsF^2#qKQ0#5!w={-*mX&GiymX1Z?WyYP;4Sy z8_o-kr_c+6jo4dFs3ZA2_D(W!m{oWw^0pkwe*0yypJ~2paoY6M+OmyLVwCF$FvhG? z=Qoz6h)Znab0;IAbl7UZp&NoLiOSp#x%Q^y?5f6xA zf285E6XgUa1n7?_t0xU+xahgwC|ND=UBv~EyyFD7qCZGk3kQg-zafgM!3+tEplCYDffjbr`V2k@soCU3g&{$(NV_mraFhcIgMKpa&x-S3 zlm60=Rf7ofgBwh(#w6nK3HyuPO!0TW$x--Wrp(qZ7gb;Pcx+ifd;Hbw;A4&vewh;Whpky$#ua2GhsDNwc!8I**MWu8t!+i-5Z%_za#eKN3Mb380t~xPOtF-H+4;ie2L-qqpRgM#8 z3^3VN`9YXWXE>+1XuH!jfl0ml60-w2SDU=_2Raf8QxZ=2_&K|--;u&T1~}eeee-<$ z`3=U2GKYuqsO}%866UOk=R=qxVe<{DESFC6>qiUw{=^vs_0)XG`nI)(uw8ox^E8gR z5Vjd4-vQ(@GX}0N1dI09=_j_av6=s+aCUCUPY9g}2BU7TVw>2bA zTd-+D55a|S|s5uPf&&)a1+I0vB`Q|}uiRantjYLw! z(axAZ6D*JEL_)^l?*T9j?Hk4u zA+QY&2^jhI(1d+Lqst~8g?R$eR}y+9Cu9D<0HR1*H%!SmOt*-1)&ua+l=+!RFLSpp`{Wy+-x8?_rB)R;g=vi6DQ6*Mv zoJHf?te3#T(7mGTMz#Pr_)@_$?DvktM)8fnyRQ%(Tem4r#Qg>VDUQLhZBsPwws8mi z7Uz4TztC1os>bX?2RaRo^kH0v#Xt6Gn~Z5bK8dASo|5_qp)u5{AEdWny4>;aXGy9;v{JpX;Px_Ej<*1hnPUrR=91`;Y^R9I`mKNEN7+sk6&k~z;;nFNzteNJ z2x8??!LLf_uL0pAzZ3;wf0*pMqU>ERKn&v6aaib@!QVwb9OML^E>6sf8m#?kIh!0Y zeY!YuiiZT{6@F*126a>?D!f-_hw%hQPFPPD-o$Rh{(KBPvG3(Vwww=sKw!*DZ8+Ka zl&>|?1OT3dgA%{NS$NZ7qL7`h7GGwxWD5v`J~tfQRxlCzH}$u1lF0}3ai4xeR?cwUg`e1=EX5Oba92D;Ga@apjf!0T6m z_n!c-?ahGuetf`dSDA9xt)F}R*!|%8#b_5G(lAMIW|Ntvo;*;Pze7HeB^Y*KKC<4F zu}fHF1jRnAZP>SUGJ3_A4E~45R9qUKmb9fh&|opR=_1AC+;OM4oyvLQ?`A&hQZd|5 z`fE%Ii80HV@f5o?{_UyraONzlsmrIy9S@Ww_3Q$iO2YZu3?pzbGX8GO{TQ zvqfKHeR$%`yi;6Uw`Vbk@&K>W*hR;|aT*PRpRbQoY*v@R583GWtK#+p;nhOl_-(wv z&)P}iBc#spYIK-SU&SA8b7i5J>$DyJ4s#=s)oi{pbKDCT)EDAwr)6M#p+05ghvKNH zpuleg-Jbe&=bNl1mE^{YcSt^Hs%15YUgg}goc&`Y4)Z{otg^}V8} zUiM(pKJZ50odMw6;8fKGEuSZ!CLsB#db|E~>;6Xjr?43~`PYmzud5@>?8XhdO2vci z+2$>k8U^_6`YwILV4MdTvI`t56G%J=3+cfj&=~e}7UyT@Nb2XignwK~cBIf)?le4D zuJ$Q`S#j*)9LLSet>pR=+E+yT)4v4v#}=k}m$f$l!+h^~Yd)#<^_M@)W;5eRa*NPL z`T4+K<^G>TxxAitQdW!oR=E8H%P@15cw@7xgbSd;yh_IpYvHxI`M>OaU{lL^Y& z^d>;4TL?c))-^#};LT+E`9%Y?#F%m91w8)EI9mH{i#T&4sBp5v2H|*@oVMNwKH=Db z@H$z#ziSw5I2{A5@WBVH7#H^yhV=D#F1*Qt-I7ldG*u?U1g(z!3;Nyv(w^FL883{Z zm?0M72{7nI8n79kf!S@0cFxW@fEg-AIM$c(f(*}(`8i073R`bm5M|8^&$ZpT&(Pq) zFnr=hG+2Vjx)VM?qdX;j%6Mws_S&96qQ14!$4->(BBLWqCiR-??v zOyCor0v}cX)%LiqAS4Z^`pn}}Sp{~JR{{D{{k46m-tLBzZVYcaC57d8#c!~!Yky}6 z@x&)?!b={C+xsMsV#X4mM9;Aw+W_qqz*F0o`F8BpxZRFeW9V?w@B2|(727w*6T>r+ zliQTg=Q2U;m+9f@1ig}uF-{Ce^bg6k0KX6~7UPGXS*$QT$fx)Ol%FE20)qTI`!Vhx z9O=j(vu0b*SfV9+o3#i^3Mb`1 zU1R*nos77!tpVXl$V>5lhLhMc!(p6eetqy+9Dg(aDYhEowG&4;N&6WugRhyzxCG8p ze}y+p1Eb6NapC-1^mK-={r2|4>mi3VzfL^1+<$up%1gvQ#55ef&f`dlF=e(uGK)YXkN@v_kl?PgD32xY)u-UO0Z+2!qHC$2 z#`wF|_|e65!i0D}(_1Dv^eG57;6sQ_3~&j@nJx1ogf93h4+h&Honbu=A23^tZE>Ap z&Fm!fp|*jRtV6p{lz@bAa=@@0C z(~&BOau7Sq^g(Yn4SK(bxtjkC{*`F1Qok$)%Y19=%XAEUVHqfHO2=>#$6onk{mcAq zh18pD`n9WMfs2$Snhw4p#~qu zKS^HG8!{8RX5$q4ps>o_w#hOZ+@AVcvCli@$PbIyNjRt9Ghch=cV}e=}RUv!Hq}8tMuVB>QGwTDI0)$;u|177yU2L@Bw9NNAep0 z-rPEW!I-ao;UA8}IZlq-gtl;NBwHNgojko2ZCwm(g{ z2MNV~3@&YdaZJBtyr|u{`0nsoDTG%BYsOPQFY$u$c%Y9A2P_Zt#DSGRO&0mL@rA~# z+)s@~kax5hzvhf|66QgPP$&iAgQAR%@{Z~8yS#|k{b6>yUNKD$oDAl>(Um1RK)7oj zCOamBEQluKF?}-~4in#Ch@JM?U@RBIHRx31O9ms{U;=`?Mq)a@Ss(1qt&S1&>Q1ub zLo`;p7mMaHLG{ts(dJs;04lJ z<9?}`9w};`SW%zgzd87!!vkGQ@dx>mY~YiU%7l|6(`B;lhZ11)tv`6YOZv!uM0DTo zVZ&08cKKW};G`&zbP;c6^T9qQu#`vY2UDLg$sGp0 zgYZNAk@7F(fix)VI@7SSC#5M3&Q?A1!zZ?+zcat!PqGVb0WQ-<*QY$8w(QyhZmlxd zGtrm%?_e_({d*CUac4NKauN08LD#Gi$$aQbW3Z2!;>He={Hq_SL#ZuiG5@_E`9!@R z+YYik_`4vS4|=R?WAj`sqkrb(uIAmdegFnP@o3?^DCl^54EC{08bBHIy*Nznx)Bpe=07*naRNIe5=iQ#-cx?;Nx8vhZ zyf>^5Rr)dDvCw6p<2~3XoeyzP=;NCW{F~8O#mL|~#0Ih(89c_B-4&rDle3MJ+5Hke z*~-Ed57%Zk8DN?pwAfF5vqdJRRmWAot@_WfrZlMW5#7@m!z4Dk248IQNSI_kWkn;? z@zA0sZQnEKM8k1=2I?E&Zckw*amisI`oxmp9`MNGBRVfaZZ^?%^=Ae<6J>ZU9Fe!Z z(cIq+6$UGj-D;69TZCW9X&74dK>Z!#7Z^M7QPRhfl0y4!mjcv#l(n}nkp)v{_ot&ud!Sx6j8`KXJl&g6l&6Z9b^^lj*ya z+tcy${%M=$Yg{sDx8qfLG}1&LyCo!2cQ!?PJ=*(IJK=?H(zqZ><;vZ}C-a(PIiXuM_+paN?ylYjWpEh;mX` zwa%0&LBf=37_1NKOdj?IW(RSGeDWi8zyi}g?#3T^)5UwW8v|gm!X4s72q^&;wC%ch z5dIKp(PO1Hm3-ii{?S2#8+c6t$}X&wr0|LGmGvZ$E6P(;9s-<$(QKj^{HZfu8W7J; zb%yxokaFT-5C!vdx#a7|#(N;<)l z?kp!h&ynlC*yBj1LpApCgSAawm-XwyQ?up!{rG6`yHA1lUp=-4dVP=S6EzixlY|Lf zshz6boWRiPVZraD{m_@`7hAPDU36joYeIZxLs`4oLUNc;QCsIxg8SK+D_3Vv|MA}p z{_MB&(CRUd4Ubxm(22V5ivISV za7`!8ue1NE ziM<$3nhS>oOZNW_rftEPm8w5z8x!1`|9YlxX0<>2u2Aq}vURJ|qxPpb%UAi0#=w?}seHSjTlx&h@0*uH@N(cc2> z+?N#d^LV0m${X~D!=BqVBkH@ZjvubGeslkfk%jm)^Rw&=nt$>)pi8$$Ya76`-zPlW z*JWc>X=hIyZxL6<2|!$@aDWq>`sE&$l6)}B3j@5;Vc43K`IoalAfoGjGU3Tk$Z5{z z{Hwn!eKZ~q3`@|_^H~W#pZ@&XnJ>G-*vYv+7~OpD)6@8|agIYecPV^)faWFPtG~qn zez|^*e>SwpKj`L(Z@yYm@v)6%hN8p+A+O8w?JO6XlqUfFW3X)CKF~P+uoX+i_~h?! z1E6AfI;*1BRcgbDFyqrXfPqQ+G*HzEUKo^qUeM|S!YN~D9e?sdaafEp!3ipr+7-mM zj9xLEYv-Ty4rE8A8-GyX(#P6m0Vyov1w|O~$tI;%uh-8eYhj`?4i(2z86@&xSUz-y zYv}>ZdDc1xuqVc6ydPAgBEHs4jl6A*s1?wMq6Q)&UIiHF(#c=YF~qUC-LPP4AD#o< z@FzgQMyv3Gc|!if#{C+;ROa`FNG(lpr_5 zMU$S)w}k~L0u*p9{ez7PL*p8&WQunfoZyI`3_gXJ=J9ayw9fqwlsoW>{*hqYCa9$a zqYa7gSWSejozXQc#*%+XNf!SyIueS10^dJqC3<3b>1(bTE!pA?)1(WMJKaE8=}%5< zQkD23zR6Ond=rH5tB5)}gRQtJU7Sd={wi2sz_uqqH;ne%^e1e!NALm*)bAU-J}v3Aj%1 z;D#0}Ut+UB^u-1JCWZPD0YCTA1LjUUQ6w;Gw>XVGw-# z7;Ml3)p^@KrqQvtw+goB7AGcoMyT519|HD#J&Ehai%RDMPYA_Xao=`k=QZ+1P#OAh z&OXHY_EFV0w$R4?OE-6=Rf!Q(%ux0>`u$D%t;b^X4cjxY?Z|sF8>3IO1gI_L5 zE@5MAEf?5uY=N|~PFX$x^cxo<3tj67<1CnDZaAoA75Et}>Z|ilrBMeAKArN80oSB> zHQDnJZ!!Y2>*9;G&&+0Kb06*>=1MhOS}KmmP`jbd@vQ%hddWL1_#l&FhP7&w6p2hc=y2N6?BHRWL-%ibz8CTXEf&6M`}_An=W)xf@iD8Pt^e6t!6V`zm6&(> z5GJk0G})6Zsv^$%n8moyqeu)N)i!3)fqzQI5w$aAF*{NiG(uMn3fUB`j%0JOL*MU0f7#HJ>R%&1$Xk^2iFp8f_ z@Gg|ZhortW2%uDt2?x7g=-kFMJK%{-IAPnpsJyA}OzbSYUTWizUHU$js{eXEa|CqC z@|)@FEZ7;K3i$R`_H>OdZqy4rTRBvd2|u;Q^3m7s3=aWSDq>oVUO+Od6zKb`rK5N}Cem_`7@%{RT7z;#!W z$Ut`xbRU1K?WsQTMZsUwILrpOP5w>IH`D74@dh0E;&k#>iC*S|>J#Z>6?n6SkqU}6 zg<=`CDL8Q6o`LOte3zrJkJFDrHy}avB^I#EJ*Pm2IV{Ezk5CZumA%NG)OKTC?84z! z;w#bX`Up(zgLxQuSZar!7xP9H!NmoKec7Xnds!Pbuyt30a;(xP4KbB zO-8}&f}7bylx;rCiwAl#KM4%BZ%wnU!r7;ACASObD;bf`W4qLw2ZMeI3?Ec@ki~`I zzxaGIxi5q#%W1}JrP1h{eM4cIW02nrb4sNLj)ngx z&YKYN*$bZ@p5eBntk`M8b~uaJ!6_RwrU?1Q)(#%Ayg<&Tw**%rTv*6d<$b{4+N zK654pi`V^ zg6j+N0f7V-$c86$m_M0xpN!rpi3i#YEJI3_e{{5Ta^lK-bDm$lBT zj@b?Tut-*}`R(HW);d>(fmz;bze8Q^{8aus$kKVq*He7SuCj4`VQxWxnyVx7A}g2p zIUpACa^05+chED1!@lIXH`>pfJI7@8S$dA~cV$1dkA2woi^8QXax3|t+WcR=qkkaR z+L>=ObS!?=qy2{NOE(-(*!tEQ9H%Bc*%QC2BF*^4{3*1{fy>HpEr)!zH^L1fp`)^*8Fde(Kw@Z!QusEH_&uLekWcmb!tjw;>)-vok`)7aF#uj2{ z`kLvl_2F%G+g~AH^T9NKjf&^FHJ-a4Zg%(7Zo2smR3Hgd2zgFulgJ3jbB0xY1|!Qa zXMb)lGaWFQp&wn$RL{PabH1AJW}t<)*0bM+(}x!JpK?PYYc_=76+e(1dwIgU-vY`8 zJbw|xE2KbI82jLnzG`lWZp4&I_31+If*@OTwd8TbsH-8skKjk3=mCSz?ahS`UC>|M zaT%UanBdBTxV`fDJX;BV)goHK1%5STfEYRGbt$A|1yq~#qe zNl2z8NjfrImkYi?e6lJD>?%J?4#G_r?OI~R#GfvZf=@sy#Mh{vRD>r13`Zc!RpDR3 zV|ud&owotcf0um|k1jsu=^|Nj9+7=9O;^YtRA%D1n8xg`Ht4#8Dx+L< z!A<+5iy9oXnhsd~@brh^Xn17!t`-G*qmIH5l(K%3U~ru9e#G=bZ$3Fp)A31A3$`J4 zZ~9h~ekr~<;Xm=5d7uvvYP>SP;d_s>%vC4sAL%hKHaLx}tbA^LXa27_mdd}|pH1ZV z&kp~%-Hs2*-JXwgd&1i$*=IVhb$U~3Dw2dRJB}y8brCSLD;W8rJ3)o$2g^6uPOA&- zr0Z7~x56Z+Vzk9=^d)My+@2S4c*321L{IU&f^UZR2o(Lz9`cWVD)k*G{jLOu+8J#+ z-pWQ@&Sskukl5b51KAnloY7sWkLz8fdU_ks#@RLiZ-BZ3ukZRe*<^wza)AbnI$-u1 z{4mALKqq=z0RB2lIqJv9@dp(`itUBtXo&Zf_zd)|xf=bJ$CU!SeFEOx zIt*XO5L`-$Fe}wpMzQv`OqSaMGjJDwP@Dg4HHcqD74=AdyM;QKs zqtW;LbSyynoEaEw1I!Py!F}&*OCc|_cC7OQ0>r~I!XM%&H((oMovovl0#B@AQ0GF6xP+O)^@o$1t7&z^r}KI&S{~<-ub#@l`_oUuDck`INC8M?&{9mJa=6{#-fehyd+kajq%N?`%#L-xO zpUFOJzW_V)Q!a-)!n}dyk;TR7-x$qLy#(mL)jbdVVe%?FMO!AJqaMMbZKIwxP*j_kCTAKe5sb~ z5dN`o+b<2oV?>^2Wf{k6yk@!<*e=0*1~-*gqO95`EHVmCwYJv^&-gtd(rnWCYqDk{ z2v5^@e~YD%9ZQ13e9{H8Kx2_pv!@0pfG!cGjHZg&;dNBdU5`y)4aZXcD~Z5tNuBQY?;xfJ*o zBi`P&yPL>qMzZOa`!YKR27de4pjegZEdBOs($5GGHXj_ebxv)R(+;+%qK)jp+08~Fa(!FDN#a8{a&{@XreJlYVE@d`A{)>64H?ganqawZ? zsAQ?l;#eemdIQ{dU~f5hvAwV-ux5NP*s2eF6DdnxQht`Cf5OX>0hr*)4Tp$ z8_e`5qc8EB%1)L$BWPpW-0IEKvAu@oujVh9o=tekcr%WEB)v#u05E<}qV~R}z_*=y zs>h9IzcG6!p9Ku+H;j{AF#o|mupT_S-Ht!b^&A%41%YxJ6JoQql_D^7E;Y@yfuJjX zBZqFn>pGD?;J{Axq_{4ye^N%8Zqub;3o{30Zx52f`CC_tzyoFJw-WT1umpwRJH=*Q zc8?5TK-HOC?RQqh_CtNMtw-mUkCHd*&w04VzjEA&w41ngtx&rezMOY-za3^EdhJPvZwhoWv6Yxv3m7) zhjvtkg};S-%&&XmtxtH;xlZVujuPv6!eWVbN(m~X1-=-Lt#9wXS*Rfyo!^n1Q%Ph9-0U}0jBz`0dPMC{us=iV3ycEv}^Rf zzCS(|Y)}0?ZO0_9w%;a49?x(zJZ<6}^if~)osb{$2!)}(WpW-CuOxABo1uQ;qq4|- zgv!I>CDWNL)^eXKiLAyq8;h?oE?H3#&*0BsWO1kZzp-BhmLDP>kds*D_zK@V&p=dF zwX?nSZ$7ymWw^3@T3vYK^~|qi@v9+M3Q(Spr-|zef)K(&mX$K`OR2LKG~|P30jANH z#8dugIhSG4?TQ=?rVV8R!sttf0J`#L30|u*%_GG(4KYO8%*KC&Ckm#Do^T#J>#zPV zv$?PcRuL8l&3_Ft#heeb-@y+meHH_x{=P@Qo9Wz24p|=SKa223VDeE>HG6Y=-Y=e|>D9>xG6W3sL7Arf9g5PTqA4G-H|;|p(&#eV>}*ZyEiF-9ouS|@&3 z<)ZV2Or;!zUTpHPhXuDc?YlGYW9%*y{=3{0pJe=YS;>5HE5{8H=L3&Jh`Zg@4%f$+ z@Z}NzY}W?f(wJcnaPdXV{|bZ~fIz|*)@jgISfW>jc_(AAzK1yk(NPUI(NoQ3S9~c2 z;X%!nzfzx89W~Ekue`cOU0{r7POrd_u~zl zx6j9XtWsM$S2(FJX*4G;aLtd4B^49dMmp{l9LRR~vgRqZpg)k8>~?dhT-uYKaOfz8 zIF;q~`mMGP(Jyv210ogJH(UJQ6Gpc{UhcsD0=&Fy!DBmK`@g*bN_#V)N+M^2c!DDe z=nnq`d;S0@2aPakv43jB8o1RFY9RO=jW-Ke!{Utbf$1>35T6dP>%1s5<6np|Gq7&*szGgd~1QiZYa2n$l-^{{lo|vZZJ%t+4)kU!GvoW56P)zyqX3>O9m!92m_NY z@)Iep?}<@o6Eq%Undlpz0l(p834nhzC(VA_(>#1^srWWrJU*&%(w5reg|F(@X~Go+@5iK2(XN_oR$`+{M6(wxYhz} z_PTE4W!Z4Nmfv9PWljENlrnuNeS)7Z7A5_MczR*HD~mrfSQ-vEKAC8Jk)o~Ca2!6v zZMX)Cg^0O;oeusl(^c`$s~E0%A#V|23+enOqMJ%3zix4e5Ony~hsLYi-hR`9K>_+x zj^beL`qLADx4`|~h$D|1jz%ZPT!NkX8{qVkZ z;f)E>33mhH16}@t=T&;L^1%zykTwP3K>?0O^#o&z5xaKp%SRmhwPVdwQbDR@h3UFx~B=!?*n>vQ( zbTb+sDH%UlrmDAm{c2&J9TnXV@*;}kQQA%a+mR3O{5``XTUfPY=KI2jMyVbN%^59I z8V$EbAJ0VxTLK(`own9^ej=RAH>(kd&z z7*r=?NO6CH&Py8`Xt|)oG>@YW1br`hM16B&=?>CWUyv1DbI`;h&E=DE+}^YJUfP3C zwe!2)(cjQ&eakI&^?Kx6YiG3Vdvsl>$6L7mfCI${p6`2{1k%NNwN1X!Fx_}T z{Sxr$KREvOPmg;0fS5UoY+%105m{&&BS=l^SkKo24h4Z8Z#yxfL5b*(uU!t1+4+UO zbD$W4y~01k1=+bOcUB6uQ;Q+KWD0v4u(_k^3M4TYPkVRnR3GEJ>CGuG71kBNSAJ)9 zQ1j~*2_9G{4lCMJoU;jUIA@t#;#i|&<-~BH$NI5zB)`KQ!$c}2Zt|NG#>59PJ?Vn2 z;9Ls)<6-=2^FW%6r+{ZFGxeXt0Ej-6uTSi|*0IeMT?cv+2>P8(I28@GzaYCrHi2iN z3uSCJ)#=$H)gzN&hCj8N2|OKtswXF~X5z8LBGav*^BK+A$8`jTCywoh<4RA>y}SbN zJ^|i;6?py1@!){kR)&_NE&{$X$tw-EcQu_!wjIdmO8qN0Yj^~III}^ab+%CBxKI2W zx6vmBuj=oLWE~^;f{Q%oA3U)DcR+~0Psdjt%kN>xB-XD=CQ9vF=wt~t^V^Fyr-k`r z`mq5|Z`;bS)7>JXjamj;e37BnYxHQ27k+Vk@KA9^g3>9 z>u*~j@{sYU1%8v^V@erL5!M_BuDC;PGhGZ$It)`Bvo9o1a6gKamD$^FSCssu zT$#&g;h3e174DntC~tL_=FbY>C`oY2@N*lW`GD8k3HM#laCWofk-4bhW!tG3$$!%>w;nf&Kw)NPM6R>V3Il_vp-!}5tPqZCpD*v^5)~l<3_L&p* zHFYuHt)O^U>G!@EN9=iZ9>|{L)4@+0B`!fsU5(0s>jm)@oQ1G9ZO(n=}Cq;5nG@d?oieaJ5AH2Or`#?+Kpi6Cet1j15!L!&lDeQmge0W2`npSu~Wc{vfTw4&ekCd@LGax=L zZwX+yZ+#p9%gKTB8c{~95taU2fba_%yCF-qG*uc;=h6kH)>s2WK|G zZ*QDUNEM$e3v9uER^f5tuN(*F{WO5B$ER=--qN%9atBa8IVOQy`%rLcdt3t;bRI?c zZHhqlV*_sH@6FGau224oJNZb~As5JB{ZZv3n z^&^8$*QirEJgbgxkyqeve{$UOg$3CLi*@BJzBmq~(?cG(A3l`#M-Oxt0z^9RI$?XR z3*Fq!$CBUv-4WV*-QPkX-SeSIXUh$E`U3F29#6~ihmLEd?+>xhr17g9jb^TM8kBDY zESscM`km!X26L!0T*a?vayEW=yla!Zf{EYVJC7MhdlS{Rn#)S9$NXgGpEFxqEl6MS z;}0>n`NF>2F1x;5I&oypWWtP#czC7LRx0mG6wVSd5ijvzm5?G3h%HSw)Fhu|EA?LftKC4>yQGRa0m(_E2r;FoU7CAcUI z#c`(p&QH=e%Yk?MV7=nl{?!>1LAu92Pvc!{=Tr9*Wz9Lh*G-Dc!ThzoStAqvJKCFu z4gT{}`=F-z4uUsb$l;uhiW2A$FuCt$S=kDv6ALY!Bz|U_r1i4Gf$GsJs#OPGpcpq zT>fD*_!ztSP?&aIwg>%Oit&Wcn_}`@-gtf6+E#5>(6B}seVP+Yntd$_+wDMyA#pM9 z2y=JtUoiUFlIwmLyC&z0v9t34^2(SFLFDA9sfe%L@-O5B);Z2(lPMd4x}$TqI?3M)5-zv4}aJ1#$Wmm|1|#0zw#sa zzTfw4ajX!WC{UOlO@SLR55e7$hL3V+I*nNonhZ++>%Edf$pNad~evvL&v zLoYUZ>Zm)M5M?(4R!)k4GTfaeuB+mShm4txWpz5KQ#`d_!I=E%;sqn%y2AFVbR>R| zFJ&TPT6u9l1kZ}&HGT!q45*ln@%bHow>i53km;)8&a?`N5fHaYd}8o@5=eAmX||BT zvPo54k`iD1C0ate*t{N<*W*XqWHvV}R@NRnE8sVL`MRF3Xe!zt`FTkASvgrC zk7Rmkj}4EYlPy`hzXRTX8F>E{;PtD=8vz!-fyR$Je2-d(XUX2Z<5|%rl@!jw$g8ee4UwMEkI$;|~|sW${H* zztP&BF8IvoIcwK)WcQ~6gD0;$Ch^o05V+$iwoR7UBl|kbF+BDr@W~|x+5r{GPXCaoZnkRGwVGd8Q+?<7r8pZP9Bs=e4&o-n2iB z^&8ntW*3uUy1dy(%oRq4_7z`}_}tmeuCTVE!RBgil+~9>eHc8!CBe~5!+pQ`K=Qx( zy{RjBs=QNl9|*RydEB(_j6ccstm^~ejbMD9C1VKLvCVbt;gjbla=DU2aQ6@| z^t?3+@%p#xj}TRS9|ps|!I&bp<~Pm?&TWGGuKeHR+RUe0E;ishv!{!;o4M-5U-r%F z!V@U%?w)PqGjrnA`r>f*!z{2V>H9CW>+K8FwU?UJ=X=G^{K~K6&;Qk*!+-u~{&oE3S3kqg{++*v|KVqT0ssA9 z|G)89e&PR(D9jQg*GK+n9`S|~!4f+4>j7^~B&oq5e&&Pev;En3F$$(%!D5<<@ILUF z#w!UAGI-u4(ODiRTqeCtbAXaRwG#Midfe)3lTCPXUUcly#oMgtB6c_xedRGrc2}8n zRu^+?0nnb>w|#s4X`~8NdZJW=vYls7BP!CiSY!Ud`G|vtjdVD~jT-rD@+yfAt|lEb z-@9Ds0O@D52RnE15MSKZ+CZDY4!UdonhY48;*;rER?a5Hy12h;GlQ!)Vt0Y7`oaCw zj%#wwpL}OsF43>KUQCHau-V?JAJdqiF$pv--@thVURw;>+Uw^&S+qubr_mM{_*ykT z8c|M3VV~_N8c+6q^lgs>n8z!?-x919zRx~?$~y+%7N^?yc-$sZSD^F$^Y zP1>)Z*(BMM#}57;1tMOK8^h1|IH6&Z4b9O54Hg%yZHwo&_dkV=E+3W?kDHvEy#|># zyD&S-@>LEgcHD`lO2Vv|F5YWf_67k`Ht{!|qa*ei@;@Fs>uYai7#^){rLi55;ACTlHWUv=XCwH|bW!}2+E2ZW zVBLPv^J1s3Aigz!(XV}7m9GWPsuL_fYH};b_G4_{S5W-AW3%~(8DbL~$*O~I`8`olFmbL zXC_FJ;FI-D`r&w5ueLAEzrF+ZcR+n@51O<)S(`9W^&iPOkFS0Gqi>9l`~|@UPZkHt zlD%c@T?OUjT1eDL4yDB7Y#dHHvLIU9O&ybI%0sy}OtL0kgtuV``b6z!uXMG=oxk$) ze+S?3kAE}%@b`Zg{;A*ft@xw=+;`*O`j`KC+_nvW`EUO1Fx&u_Cw4)6*?3Hs$+3=Y z9TpjI=)3iH-e;4(LT3Per3f!mdgS_*#m+E9?XPjGBQqYd^W#^(IqBksZ0o<#BBbh( zwVy4Ta$=knzOHT6@ecb7`w!u#{T3U9o~o_x<43v&J0#l}bU_tH{Zi{6CYCea>2LNW z)|bYZm0@2zvf(Qw#1u}n`N=ne7j6z>#4XcpZXaM!|Li7(@-@Xfxu!5QsAqjMIa=Wl zl&a6K$j6`IrLjt5I=Q^qCn$v!n$*qc8}K4|0*$t|HCAc+IokJw_Ln0ksCSYjO?EVS zJHPvIgR`kxi;WXCj6x`O8^6JdCYBWV{lf!FNKSav+`EA@CcLP zPTnzA^IYN7U!3_Cvsl9+*KbQfX{dZ{@c0PwrweAdB^O=`-O1=KFWK-b1L|OC%#z^WI_@nz3|6pgL|6F{55>b|q z$kX6BO%Oh{6SJkgEt(X%Zh4L81g6L0S5to3HQA2F;T5_!(%KcoJT`2L#Wqa(WPQy) z8T?xT-o80LWSiyqh2R#%T-1u@{TxHN%~>o@uhCzc^Oaa(<5ZwOb7>_(R|O zo%mn=uV2A0{rxWi1$g`Xgng&|7ejDSCn)r16NO=ND1l9Jq%minrNdl4Kp#5iw zVAkG!Ri*Lkb@HG)h*MK53Ovn@zTf4S(Rv{Ho(r5Q9vj`vcw=bc-i8SwMFBXxLR? z_c&7HgrXFL8zaSN6kPQD4F5CQR_!uA4SbvEu1^X}w?h_xrsvFOp4cheFl>yGG|mK-f1i4^o^+CYk=7(qhAAvTx%TdTpD( z%>uw5aeM{?M8umBGajV*qbZ^eq;Q(gF?v@EyDn?PS!Gt^IZCI0f6d2V#kd)bCcm`3(L{AY zjtVOoFDpy^WM0#t{=kItp7z{!y`mg9UHnh*3EvT5S|+ki^NPG_C#y{O%sNUsK8#Ug zy&6$EZYFc>E;?Nh^>H@EnU$-tKkIjPj)p4xeLpu}Nq*kr3F~>K`AEh1KmnawUl3fg z&COy^!N8!*7J@&ZHqP(b&oliq+L$Lcr%QFh8i?~{To^w-zZyf7SA(vO!yo5uzUTYN zHy-MPBaDmZrB+wG+i{&@Q_w%X3D*8B9;AL8O}_RpTxofQ>VlPe4D-b|$HF%Ik}!51 z&okRqUs0sZl?PN5-dQP%8_B~T{IUly=;54V+mN2D+}k|n?Gw$3O6Ttyx&G%jvh=2q z{-L)C-+{4w%i2}ycF}h^IKzi71f8n!;T?YXi*vq^k2iWYjCMNU!8y0FiuKH3N0dC~ zF&%a>n-kbrkb1UF9z^{D7j{)ee*4>xm0TC`_bg{WD<2x0z8=eL@!v{8Tln9)y>a{k z5a&?*=i3wD@dV)OsAO_pE$+|ap4Piv)$YGIm)1Y)GrXBL!y9DJ=2J3%XTNpw!+??! zrZRIMyoC-KklJOc(V9N9%MM{;jiZ*WvQ#V=`DNVITS5`s@Y&&Y$~>_>Hf8>Mh?s-|%Pu zS()AD&DG_v=YW;05Y~w{{3#xCk zg$sVOjp2leXTnd1ZB3H+pk=AAQf9ivu(I=2-7toXbJZSB$6)8D1FG(^K{UNqoUY*K z-6am8;+RlUEYd!&?}3+3j&BFOe-FIA0Ca@9bhcIDZTHXY?+Dd2Qp^R;2dSb!~X4-eo#f6GRG) z5n?pcPCQ|J_;;3D2G|){bv%-Z2VGJ7-*?(`dLdu+F=ugZRxb4uJDtu)%okPq@MXho z2adPO(9TtVR7Y68l8>?N+ITBnR60Bsxba4Ocu_5UPozpefxB9)nekTjQQKzucLlod zQrMMjS@5w3vu;mvY3p?QJlN#Sj5VH5d^y`F3Q|9lxdlG5J_J9fw6^0LTlkmU&unZu zcQTmd&)M$OX9PNhW3@y8dr^t&I4PAZRX_GV|R;*Zm^ALlZ+I6)sN6n5JVJ znET7IO^|O9V9w8;mJ5;Wyy#-nkQvY^3#N#WIN?mkASY-~+Nbz{0t3}ETqTc_mjVoT zr+6>v0e1qR6Um_&2N)ZxjBSmN2`h($#uqLoV*&WJFMSoi_1Qc8_>X+ASAWO1eKWrD z*?auYKldy6@~7|c`@iQq@aO*Re*@q5PkbBx*5CaN{Q8$ZL43Lah_Ay6kuLj&6K_E? z+zBiR9mwUMP4=|^z$9uHX*%(#mRoJXo+&0Kzg2(VXqo-nc)sg#iQqB`_#WqG@BW$01OxiPC)4#2Z0buY6#5bnHm{<%3o$J#Y zil^$?%q|CdGb5KayTQaz9=PciLz&w%Yxff72Bt zD#M!?CQ$QHXfn~sY=*Z~sL$8Bq5F)63EZrti{rC-2_jzZ*UCaB80~L0!9Me&j0?l} zC-p1(6LIEC5a&FBR-+5#PH2nM%Dz0 z8h<&D;-LaxnU;jV#(U2DL++S-gDm(c!L1g=g@3Lm!b*WJT9}UUB259pcPUU29t`05 zo95%3YiB%Wx`VDUj;#BWc}%Imn;Y=++qki~;y6C2ZYwflIylLNWGJEr_Y6K6>pFunzdS7!Iv}I4aAABL5Bt;G5)4qHA3sB!5-wW7Zjy9DR1wxRT zl&LbT`jxTCDsfkkL-K6x{C51%cl{o(`xn0Z_u;?&KmHc}-fw+^zxK<27eD?Z--|!?!{38H^GnkKFODF7ht&LYO(xwjdY=W9i zY}Co|>yNB=3YzipibcR*O(tjfUcR2uBNHs2Fi4;Z4p#LVG;tw*_@1@1KwJ!_#=PcwP6@*M!D#yh7)WZ^8#Vzj8M|o%G1~s<)*i-;NMH%J%Pmgm#vxF7D6# z+F2PU3kzKid`aqoAcpAUM5mp%G7$(iu0E3V%R#9QV#J4i57T2hAGT#8TzQg$z1xsI zt!m#0V3;+5!wd^sf6#UgSABD!Pi(=9CSnZVCX>>?QdiCe{JJEz{E_ULO=XLLhJueJ zHgmQxH~cQb(?n;&KJMZxLjJ<^*^zmn@C$V-u^wcbjIZbCOe0Uai8sJFu?jLU-ZKr> ze_}hFk2!9fx6v52BD@6};7xM4OESab{>u4J-{i_*oK4hS?^X5*ZbQzXJd{4n&mc@~ zqcSx(GI`phEvVfz_VVw9C$rpYRd`HBQFR%Ua~&_sa|_y*Cpx)PJd)o_d4E738=qfO z4~tig55A{5-AF90QIK=P4c zJ9)abt!xl=$#5GM>MqPrG8`psh&m6g%K88be641`w+DEVr&e`*i+9hr zw)Z&EGW*6K_w~k`$c2#h{vlcFKFi@GW2}DHn%fP33!*0dG9MWMquX$6uen>c4q?8m zqF?8mUMhcH0G;XnM!y}U2~71%=3j#xGe1#A7%anKr;LeRX6K66s;q48a{T!^DJdPb z-(6Zc%9|jX+?5b>|ImQ;0qvm ziTb-LbwqQRrz8R?(k|c^dDou&S73-wLKQ+3puj`~^Ms9)dk$oQNz5#PZP)CHghB}h zH?I3}6X0%d2E2|AJpgBh=-9Ofva^6^omR#+EJjVN$YjEks+IFIehx;)%1gYr-z(?$ zNWvJDitAaKC&^frbZ2c#L9M_~|H7~0kN<%mz_)zyEdbz)Z=UgczvUb8U;p&~iO*i{ z`1@b}1b_Sw`~bfA<_SOcecy#2|B>&-fA`ma9>4j?XF07E=x<37F~&M}EN4&5`FAK9 z08J7u1sgWVgkPa)BBKni%-I=^S0`=iAQfHLL7*r8*0$!b2HXT_m_M(0mf*XpJ4*m( zW0lfh8xIM(*=#{i<{ILI&QJufYkp&d$6}sYKRQos$;M7Gr9)AnTJ z0S}0en)se<{LBZ0<|WdjIH!2GK7?|QPZizq#-K)!V1vNr$#AOJ~3K~$&#+Ep+4dP_8h{9J`RAScIm9;!`t6=8D6NlrGVS93fz zUQ`@!0=ypI2!L&0L2c|?Ghtz7Ls;N)Kl3>xt8R0Ix8qY{{qTWCyTq}`CVo5y$!mu1 zY%!k~KTCqw%oo_T!C&!p&;+#}6UI&KWI)+uQ~NnL3_36U4F8SV7HY`+V>@AlO(%js zCm-$n5uczwU{*iN1EvoHkZcQZJb~G^rYSq=i+v}8o~&d$*YRdJtZ35W_EY1ccoxe~ zbDi;YimR7|XO(0>^t0m@*xGM4l1~YG#*3KjR}=Wb3`KWcjtS3MZ=c$4YiOknGfj#r5*#iWw3kDDH?;2#hH#9XqDo(*>S&wIYFy66FQ#;p5(%DVutff6D zQTliMtS^5w-EvsF7H|jrn>ltK<`<-_?wj@wn&U~}A=6epJ%Q)x4c61v_pqOZ-H?kK z{KS7~pMVd^l5LOeQeV!8sWCzGTEJz-2yhv8?i(*_ zAM%h#$6_aA$K=m_ubfwDGxS|NaCoVZ?#=w}5C<>V2*(wd8|kLFfaJ%BrnArJigM$Hy-4AcgWqiNF3q`}XH}Y#o;Jv6_@r7Zlejh&Y319n85<`w(!nh*4$6Xim+O zC!zxN_+ao$+bj6xE5OT_kK?`F955iJ5Vl}Y(f4v>&H(W3GwOKB1F{C;S|!0{eqdyo zo_ifBaJDF|ycr7NHG{Q+seQA-&YY%RS2|86oqzi`zJ&kazx*FVx1adY@5hh-$Ug%B z_;3E|&*3lqjbHR@Kkyyjj(_)G`)ZcfS1pJ_g_7}7xentV*3W*Ms^}^3JiG!p=@#8uBUn@_8WdTU`}H}CXRt8Ty)D$ z_W@(mq1}+T2_9kWq+RA)2R>Bv38kDn&qW{k`$K%5O+1=g^RcshX-Fw+?4y4Wd()gu zKz;6I;A`SrOF1UNPftL3B3`2FnC(rTnaUs|io>iMvy$Zj2AsE7nc2moC0q0v;#^jQ zm&Q-#tKrFZXzeYYvJX_=%<{QZmzbs*$_svJ49nu#*s0HpI6pW$4!DSZ>A8--g3IMY z7C>gQXPf7Ihjo5BmjL<=v?{V(2=EH}>eD~eB+{`shb!`jrk5pYy2|?&_2K+1@3R4g zmxVeQ&$pZOZGKw`eR_4udHYbUyIf zF52QZBskAX3ak@hjzpak?`_SmY1jQ&1bBIWd@%Us%fP$e0$#s*d`!^qu4GSD5L5NT z8R^3BiY%c$iw&U(3p8;e!(yhKp9TfN>qCsl#xWdCCc~ZO35+G|GF<;Je(G=Fzxv;P z)_*_UHvC6F@kj8@UwDI;`;I^R7k&ya_b#J9`G#n@r;BK_F^aQiU%NPIPmkY$%GX6VG@N*J5b;C(8NMQD41m+RDs+Bx%4Ssw@M ze}2VN<`LCa0 z_=vWDnEFmOO6*Gu>xA(UhfeNlr*;nNBR5V`cGS)bvy1H9ZAK8Uclfp})=r;1P=nB@jM*#b=I*DQ`W;uE_H`h(6Z|1*6P+-DDml-7s;^n=eq z9%L(5%R>`4<{wpS45+{ngXv8PZwvbHrtvtjJ1&FWwRWk_osmF#HnTfx=d@vD=?=t& zdcrTmUGs<{eVlJ~B;#WiG<5NXbwB&#@eHSoOue}^T*twm!QanlAzQTmj<=jM{v4~^ z2V)RJz&ZR*Y;lMyNuH>4Ezc=Puh{2@cuG2DF=Fs<3GPm-*b^VkXO!*ukSu^OPYUuP zU1xv1J3$?2*yf37_54Qkdca?BEEwgq0eCLQ6Sf{Z$u|TZWVUO#Qrm2?GK(2}&Z1@C zp?ay2)|ZV+hw6vu^pXR&jpQ!AKPi+62yVsS6lO(B{yhr9}YLD_0PX2z$?kxiY81P)972E53Ss|l_3m)s^I zSYtbWWx5K?VZZGX`R0oTigUmG*M9le@F)J@58|7?@CLx~@!$XFH+~C0{fobfU;d3R z;fKES_uvP=^LGOPzVYoFeC4zE_@93Em+eh9z#>;E6#z1%S-vxW=M_Ys}( z1S5T1=W^uhNx)`Ufv3R0@GMa*I)=iU)wA5FPCqJiB~WtmJLqr4U@OW~wNpVU^4Oip zh`-8nHF@T9wbAUiE-YvX!PySRPo>HHrNK1^&iXMpE;>q(avl}LeUK~0kH;|`RgOZC zCr#FdXydpbt|H}=;TR^(Njs*=6MT^Tg#H;GPR7I!d0c7;*V=WTd7H+X1;MIQ6;TIl z9Oo&6vEW|fb*0(+TLr%wSVFa4{-rV@lR!0dV9rL>B{`w z5n=DV8_2CNN7La6K5x-Yeg?}p= zx3GadU1vR_J~r>{6(qY7>q|lSeoDw;tlnZ9UsZ$Vg*-HFieV*YTbc5C#vPDzwuz`5g&fh!%&$Nw=<{$-;ufv>-jBw`u&g_MA zVy|bN61i3#Phid#D6M!O-p=ZV@NK2gzVYFy?e(9|^%FdXd|HJp`iEZK{hZJ-(?#_m zHMy4cTNSkr2V6u3%_oF!snDsr?GmqLxG{ZGTt)tttD0X?_%pi*W0c5u9b+g7t@e|@ znZW=u{kWVvozw#h`=@I&yBO9jO5QiinLehl?=(Ky2gltfG#-8)<9%q!V(;0y$(0iN zn{CngtiAE(EItI-cJWMp;-i4B&lTw3a5Na|&oaFBkt9E_bmRwEnxFA4KPet@H^a}q zlLz$qN;|B+205v=&V*dyKGmx|fcwCV*dh?kN=QCv?2u5~M5q0sP~x<=?*hCBUf%() zpB!%ky!$fn{wu)Cr|_pR*~l_q&t+x!Q#xyY^q-_aMr(FwZv{JRQnT}*YMl- z@G}&9B7v3K@7nE`X!`kI`%U~Of8nP>-M|0ie-OX-TfPx{1^&~&_`l+_msh{`r~dE{ z;UD{kw|MvRitqmRZ^fVg_x=RF``f=&l7vL4AE1(4oyqKRQ zshMcvg2D3AR1`O;3jNs}v5i(D;P&jFDmSsMYJ18z#FA2z&eagp!{6uB~2W z8Pv0k*Osy_<25ZaThgZ(fJmgQ^gu@jFc0WvelBtU>n5@3KJ$Xk%-Nsv4w?*S$O0_0_a1c)<(j1#~>WRJ%h z%a%NnM^{oJMT!*f?HYz5gT1j$L;C~AX`2~6JO+hTfew&KbzQf6rQ{NDV=?|*M$0gqs^?}#@NVa&=AhH#`$vVNef=9Uf zEtcB0Ai_c}#>ZihLi+fMHVJddk9h%{pp%(jSS z+{d0jDZWPhjAEFmPBdOL0h}H9JS5t(V`#zxDJJc<9180KnaMoWbQA z2l&HhU&5>JUc<*8z8@d|zyo^k`8VFh*Is-bKYZ(5{5OC5SMcwC?x*mT=U%}pm#@z_ z_@;86_jnY%jVybaB>s6l@qF`i3qvY;WBTiU;c~ey@2|a1Y7mmbCe4aceG=Wm*^(6U zM~?x%3Zoc7(Pf>eVw!jxE`rs3g8?(&jEoXpk<;|FdAh1HY37$W1OFiz#f^-;G48DU z?!KI>O(J-*;ur27gXjhUB;Vc^3r^lOFCUt+m&SR zNs`r%1Jmu5jqAb&i;=zMBydeU1egy(d0%YmGEb7#Z$D{a88H1!EK7384jQQi#OgG~rZ@!L%OVC$*PhhkD z>fo@H$=ULV>v+1O36n~$Gr=NzZ*-jlK<5}a7Om`+%bO9KVW^(7eEIUUk}irjLwl9# zF01I_x`Dp>3xzKUJp+Q_t;S8OHfm`2-W9c%ER8;6wgvM55@ zRaQHHZ}`tL%w>FXv51Mq@|>r*Skx+g_c1~>c4*W$HoLT~@#7ejr-s>2vyEe)uW@3w z{4;OnIve5>%eFXlen8MlR$b8YX8o+Zl@V>ifvCSZOGEoh_HKH%snD}-4D z)z)-$J&fBLmmc;mKeYwaUe4u%;ElNJy-Y3Is~9TTALHuvu%)}Z-tVPM!m=7ByTp1H z@iuC|Mc0q>i}-fZq`DZ;?c)z$Pwi<3_H85Onoj;=a5#E?bZ{_sq4;6r*XW*ULwwPQ zdG)`*6T3Oi@N=f`*~+3HCyPlS=hAR!XDCq0z`QDu^5nz^Ip#hwsCxS2l5}nzWyJkec9|KRt&Hf`-w(tq;HpTypJg%{txg5UZ2_wm%ld+<;G%fExaQ9c$t;n5&a>Cdig zregWkjoHwa*%_ulf|pgwN9M%FunU&F&pcOLhQUpPDX@bS~Rd1uOQA@{Np^ z8^*+uyo}N6eJ}H%y)!YJRKc6~iuZ4S`1>rkMhAlP%<$Yj1aLglG_a8R2+9WanC{*{ z$@GCwEQ8DpV18>Rf)@p9TwRzS1Rm^Lz0HBUFLe~PC~$Q2Idc?bEF`ueK&_iZpMp%& zp86H2KpB-kvZ_&TWteYf0A)qQF|a+DJ`}t;n9lPCx|%<=Y=zTVf6h3D6MM{m4yc{) zWFACE&jNl3!YewHgDY)ocQCI4cpPMkkJoRK1mzVsxpw)ZC7jgO zjzveQiVO8e3fd`yCDjE{!q!>33$Jotm^O(L0H&>=*7TK

(iWF$Fv z?VGx?!rr4(>Sd2>@jJ=W)uSQ z9~r=QvSDdObwww$rO!{WwS1o8!;&6QiY6Nch4pHhY-4-D@w4zVIXFh{1DW->M>-to zH{;t%8ska31)pe4--V+Hx$+~hI*oAa=M_&hJ36|!3(nLBJ@euSBIVF$N@Q*h&N)D2XY2itIU0=a+g^-K8V zhc4o$-gh4W;QZOsc<1^peCc~H|BJW`t{x(9Voc4=j%94C|{8+EMgGMo^ zr6~y*I9TF7*2&uljsltUOntiFn|Q2nmOtYW=4;+>QD~@yXoo)H{Ln5Yt8eO%N7tO! zEm8#5!>HY6Kj%Jf9)@Ruf}y&+=jsf^*}}rRrd@MzeL$~u++-l@fXW-;ueQMTyV?zE zOL0!ten4aTZTOU4uJvb)#^Nu$$~xzc=ClHKUq_fLdlw|~VBF>aj- zM*d6Rupdzn9%sxiPxSCHcykAkyw(U2|I!pZ<<0caUmr-*_kUV?#_+h!$X0tj7o7ch ztM8%-fk9{#ooUEM%O~*QxpsP_e;LXbvp;i9lGS^+pLKF=gb$(unA(qmH{;A{m~F1c zm8G6e8jR3M5hh!3O9OP`Z}3f!o_oQppikVY=5G*99nZztY2P;U4K=vZ?ZfBp!>LM3O<6Z zcr~_!tMK$ToW~nHo*=t29>d6gWjh@_->0GaC&XhN!J!dnYs$d>UfJ%ap+nxkHe+3n zLr>ltWqSU*HJ+=Q3H0B;)mn`eQVf3pkoEwbv`qA%BqA%a3z6L~x}owG=p!(FV@ScI zS~psg$l6y89A&~xP%%fZ`vfbBU6>}#P6)U5Q(2-_y(+)XwzlM|>MNmBaHDuhzXMjv z_Z}+vxd(sV>dG+DI4qKJ9%J?F&5x6Ih1>J7p64wc^yep~$+K#2HR)O9ubh1Rq<9yl zUE11(XI(g6$O5~-_TGoS#yPv6_#xKOsy?MqR~D`<07nz&f%HxEH_&f>;4zN%!#a)K zL3KS0R6HNL$O}-$*#z|oW}n?wlFs6)1}LpK$bRL7z#yX*Jt+$VKVq6!EafY~(iI}G zg#@QOPHzQ_$H3v0>34h!$j5EkJtK6mN$nH56;4d2S#=?BNT|Fas8)EyD9uJ)3^Co4 z`X&Z;!EW_*oN=VADwqlcFZ=Vk%rm8`wTALbrxd={^#HOn!XvZ zw;J#te&MHql<)`7{1D%J?HvHXooDv(pa1%2N$`odNPdv*>5}d9lPpZGt`wxqUf;AE zfn)6KOndlrlgPc7FS+gHF$Z~qnjh?hJY#%QkSB22(GjgIxEYuyEJPOJ_Ve zDX16W(@9!%u>ETK7G>oE93OXqPyNL}jGlD}1S~B=uy~FED?jp^$4POh~6QEZ(V9@Ge(vnZHl+B6f~gsd_Cw%lIe{ zUvOKMz5i3qZ!Mqg&kVW*zN~5$n<;j4n13Ue1+~RAwfs*G>^RY9R$RN=zVH2{S~oT9 zJKs*kYya&QZzFk_HeKYOVaPxyN|x`yRLGv;~88P-6t5IgDA@#E&@thYAD7BqRf#C1c_1b@hKJdE}RJ$P1+kn-Wk!+dR1n32?1T57$KU;>PXYkG`0W?)mFHj8d%yYg z`9GfB+}c!I^N?fgWp zQGmdC`u@%|(Xlk~yi)F#`tIW>qh+FTEhY z)$e92D0gK1GM4EviTj88RPEbPlPA6@nrHXHf^I*T>cZZvu+3)q*7D^e!N-Td;jL+F zpm93`N{RNtM=U~y^n5~Ip)Oy&mMyqD{W1N*_KB-HS;<8w=b!?0Unyeqkx{CAPwK>U zQLM@KJ@5mOj}jXqKAHPf{SIHt{=$TV#7Y)HmGKd+87L_N~J!;3;cp-^mF81xx zH_EoahA#O|E}N(v$I2pSDO);v6N*5+1s3d*6DH%FKdb<(;(ltyusOKz zljmg%u8+S{nm(vGxEQ4JHJ#+g8VR$G2I^AFHP!FM^}FK0@j$c94h}AB!Yc!5Z{pJm z^oB$Oa21Pn^d_1#RT?t66UU3N9<1(hoM6ahe-zkW)BokzGrO5PUlNT~xSaNt8}}Mp z!wox}bGEU%Z$FZ^-dI!YoD?1z2Zx3;JN+NUU@g1+mo4o|6Zfxd-z_#A30SY~I78t# zFaF}E@F7~BWo5)HFX~_TdO&46CSY{jg(nT)*{aIp1*)b$9;Y|Wb>zoEG>N|uo|MV{ zaZ@Jz9qgP*ZW?yb)8OL4VMbzfKUijPaAXF4wB1ECp(LP*eud{hP~#`zxRRM1#r(^3 zG>vo|g}u?v*MW-|FDD@EXi>fsaC{B8brm?gHti>jGH{9}t0Fpm&=KOzN>pgels{6i zbz8{^st;iNlYI#kIk?WeZ!#M;<^kq9qdXn+drx|q%=jOE=bz)!^;-)4KmO&XarfCh z9BelDU;o*kY5v6v=kQyfdK^H;|NCdp;dnd2c;K!(@YzQnoblGTLlPYU^U9u)@q*9j zaMOJ}8+>FqUIt9C8+vamot_2Q1AmC%K9$@9uv`Z^jMV>2M z0(fR(k_H~$!SEAPPv26I%>(YRKZ_9`-5^MCQ#%#dr6oPxg$Dx5TsHyk&<^*597(o4 zEzZ+;|OeyfWsTW(XHui0D2Bk_qXp`)P2!P(SudrZz@0R zS42;QW&qnf)3TJ57bE!!)+d$`*8en5o{xD7P(`IQFvSdK#FXa;tuwK6e)w7|D)!Fh z>9_bs5p4T@a!r_`gI3bH7T$W4{&N1o)XTPyeY^))eoKK>Dg(m3`oW9zz2eSzNwz!; zpvicBqcy|qon9#%oDPfr5#4GV%X#!bLFkcuwF5M%9vL|QVAMazZ^ov%K8C&<2>X_G zva+cz9*{oZu2XzVhT3v@h_a#n7#;l$dlAZOfb*{T-bAR)A${@p%|x#@P~egOl%pBs z=S317;2HnQmWmuxJ3emVbJ0b0O=AO>2nH48*o1A6!u9PYn=kTEJ=2Y1E?9YIezrn~ zTxd`@$sT=K{sxHRk?L`zkv;h_&bjtcu%}3C*sXOMH28LfrcwBoZ2$FK9s4Yf>jnU) z_UzV=U0c6^tA>zyKC0g%9Z)|Nz!}FlF57uh(aVaQqc-o7&)-(^IC$`Iw>#&}5eQYP++jg-Drg*ONQ|l+OyMxCu9glaoVYTBKVcb2sj;O|6%+F5z z=xwVMS38(s`Z}twsE(F51~%c@{Ec&4y70i^#$yw1|1aZ1fL@aBO-?za+t#c3!|L$m z7zog{pMN2flLr9v8>jS!cr9E*N z(V=bG!(Zn^oo!(Iqv(+hY5A=ne|p@lUvh6$HUv0ATgJs0V^_cjj3!v{MkCL7HR92# zvoh+ZF&dORgJ=vV8FC)HNCDFh0~vr(Rt}6nDtibY-2@J<07qA*Hw4CG$1msP6Va=@ zkQ-t+0|yyR%qXon9&lHaP(;7sjbox3cxump@@+YxY>0%Gks!$jkMzp;cV2xH|L~8# zskfhc=wAHI&wT{Q8UN_3-^I)CT-AGj>vJE$dPw;Ci?89CSKrqBU;Ef&05XOI+;hii z)O%ktqFd-{IODYC%>~Rl#4{1{kU&<>4eq{Y!cNAfGq}^Bu`y`#0g`Y0qyaC(m2<|& zmup@}w#4H?a^amvB>&BT!pq|V{v5FM_`?q;BYUJaNbE}x-21kwK)zw%oA{AFGmr98 zJw~3|H-_}2$=3_)kJ{d#T17u!x0=f{@7bT2hm7tQeayNl59k97PZRgC@4u5Koiqp@ zTJ@ZLOSYprEm`6^T(=jfd$VukKikagD+YK1{g{M#&9r#`;VX(9m@P;sn2!2Y-Uc|n z2^<|2QHW+7yx$7=8PVCZo#7yp?=#}gmWFcTXwH=9NomSYU~{AX&%S)zRNc1Yjejd8 zn$Yqx7aEcPiIB#iN|pTN0H1p~PIbRZ8GgVilSPtbf(2<>H7i>$v}DH**gdU239h5m zb+oYk1xj2j-ySITP~RXZ`K+6A&a$LDk^6Zr+f8M#XZk<8hXHwEG9l>WC^m@}G(?l2 z-j4CuhGnp#jr)cNdOmKXwx!*H-u~dDPtin+(&tdA;>H}%>th@zUm4K1uohD=P}XY_ zLbdUceQN12qs9G@_y*~ShtKESe>DD)3EdI%17W{KVJ=%~W%;G~$PX$<&KEofcMMXf zQ;x=+67j5>u#R}*+oQ>R9xv(w4Ee@Vd8nlF>+8VDtZ$ZRNy?m7k97RX(Sw|5kgzdf(j?`~x2s z#RrB5dG_swuZ{5|+v}0*>>%%kZvJtepW}dSL-QTJEn6Gm&`O5nz_tOieGU1XEE}Sx zT6|_(a=SykUTVqeU$u#UpzaqnLB(du7G$QI*gx{=zb5=sooU?zs#vMgQ+LnHe5<@S z5qvapZ^`iEUU`_+8iR##Vc;kH{e*cz)HssQZ7oX3@%S`qm+|H@gzr$rT$=nuNOrMd z)QdX`qQ<$rdd3|ikP-OKn6913z=!xz=a_bKz3RvZl#(Se&yay}JAE7A_&RWO9oXEU zJ%v5~!fTRT7EUjKDLQunO{-fHb~C=!#DOR=p9?Jo9<9)`!m;ow)gNPiJY|I-)$ z6xVLed;kBvU;PZu?yd3W)$8~_zw#Z;|NIjVc0s+T@E@eYp+t69C}tv%PFla_Ig=s{`EKMYWusX5+$f(LniF{L-s zyYMW!ZmrsG!YY3~aSfdtmoFFk3Y?Q=KXIZm2zwq4+zp|}C@=%MYEvg@WCBdK#wfO1_88A-$c}4|<*~JrDg)sM#JYn~SUFjGE36lk zFAjXYadfnWTgi-bm1;cWbWjdUW>MPgO_*yN;|x!1{a~;%*~lwi9x_6cjS;k-VFGq$A!(slNMuaBWMTS<$;7AJHJr*p&pcx{+;%T=T<+ zXjN(t4+D-HiOzxQ;l78@JmbN>skcM0=_lU|?^|$Oo93Ys$vsxn)<47A)sgcYU4_IC*tOkAthTsvEtDCRe=6U-Z0Ic2R^?Smsj{L*n6=3M)>D0A-T;rzI%EAKyMyOF&#F+80p-$36U$#n0eX;)<5OJ?rSj<*RZ zVR}H0+EngDw{#G1ZMh>3-tKGPL@?YKEQ(KCF>7n#b@185mreRHlHM8hbtV->*m|C zHPEf{vEZw~(T({#0b_Bnj8<|UG8$~T@urp&2iRH-9>D`T##@xOoNFFU;Doa{3u$SP z5-9GsUwPY1@_**h_u=QC`T&50fB2AHVtZlRyG~=j-3s4+4MWefQ(x zyUzm|xN`FV|Kor3*KyYwTG0^6Nsi75*X)GXIC!bU{UN-QBh3_Nv%f^m3q_@&;HHXm z$R6J%o7o%ehcMmI2S2TP2FFDF^fbF;4hyorL}1hZOiMlx>G z;LS%0;<#nj;4wo}4C@Jpnw%Onb=tRJrfvPXyiK1VU&)YrL$TrIm-xEimy?@#61S^=J@ekjl#Z4^JVGOvJ@Xql{YxH7OwY4f$XskqY0f z%{br11*-GRpIv`ahmd9)FR^5E?jX)?mdlObNnrhXq^@tKP8L01m4|C=FMcd~T8#Sh zWKz&EqL0;g@k%}~TGbzDd;Fq{W<@@%{D(dlv2Qf?xqM{V>w`RyS&Zvks%(D2d8B?9 zz28OmvOCW~zA(zq`#N0g=6lVD0AysM#6fsUHNjeLZpuuIhCy}EM(_Sor&K{uBS1Hk z4Mjj%ICy1O5=0mo=|EZ`>Q|4Y)#NzGV_6~ zSG3$;|KyWcVZfjL@O3=*`XvCs9jEs2`6nI*0Q|}GKf=#G{(k(|fAg1-u$hR;4f!bK z*})iyhn0bZ}EU- zE+y#Rt5MKYRdfd5lxMkY9K%39BUs+wLnJ`$1U&V1_}bf44&r%IQ}B)kJ)y02aJ%*) z$LBsRO)R$tu0Ais#Ye&*8HxI-{8|qngl01cKSrN7yCh%# zBygHRyr+qIWeQSR9?a|@_bkf-E984G24Vbp;ySr|B`eY7vF?3N{h!ClZ*Oi+Z}n}D zF#CQVM@iKM8IZhQzeIB5ZN4YBf*}aC?wuf2wj^WbZ$vBmJg!Urp9j>!vlR4GsTQ6C zMSn)yULclcZ+jz_Tw2LuMch{+w_j0B`Lbn?s>>iO=jEIC}*&gleJa=${q zu}7Hmq&}ZBtmJDjp5&(2T@xxGtsUf|f=TC)QJE2((Z0?2qN`upX`9 zEy`zEk%=-^F}dgcfsex?epDn$zh@_#t&}X>R{2r-d#LY;d}zDL+OH~>rc-Z=nXD*w zsp2xS4`Q44*3%@L#wZIsh$jA{`%&ukgCZ7`kE-##gc^2Ft-N1gzq({|g-@#ltcoE> ztKx@97ot8=#?#xk=5^@N`gTJg=|bM2pA=ulht7Fk!Qj?{E3}E7OC&Chev9Iq-ot>( zTykGHeP6Ph*>(|!F2s+X(OzUFiDbj%x1;H%HSg8%PZKhW#n{N$5(^nnXF8n^hr=&gXC zef<4+?12loa_b0Re(pz_|1*!j4?xCiSFYoQw=Uzq_>G^%Z++^izOwm1)vP26Rw-2m zO!R;SndLwX$qKWP8|i3}f$7j(o!DX$00Gc|P68Qzf;c9-)rC$f1aiOzFw&3S!@$=4 z?&PPeB9O^7ese-}wa{i(e3n(cs(&sJ)OsWIt&2=`lk3Oq`OZ37EWE4$9rAo`RHVVP zrODu>iNk0xrTtE;Fuc4pAJ8$sTpd1Lnyid)^!>l|U?ECPei2>loc+X***c8|NlkO_ zb(m!$IiKT#9Dy%;cQUW5RgpY65j#PH8D8lszwPK&<2nAcCYeHaU+Axlh zF!S3t5hVkkeq!6i)(IbcT%>lp627=SmH{rCT>Gl4e^4mU?C-nt}@I=dQ>9}=urHp(OdWRTU@*}?& z%B|R5j#s5`zS1WpY*x;6P?;@E__8;sY zJp*eVpfI ziOX?67XtjlI0HIa&`Up$)_a*ExId}31UU0yNb{RDOKmUmjAb^F?DBQsBh7CIJeKJ5 zH0nGVr@-D+L~;@tC3~dB1Qyw}3Z-GTO-bG^3~UN#XdAM^-o+o)T#2-mr+9la!hD=q z$0>y;Oh=`cH9F=zVfJ}BL$^lTjzv`^-Xc89uYOG5ov4HD3qy3W%-(ep$hXTjo(0-Z zc=Z^hIJl!}kM3!kQGj(qIwHCkLHHgW0US;b0FJHzn`_hl!uc5LEENAlM{&-k0MsF9 zz!NxwMHGGi!a690mD&QFsJ&<+s3m*mb<$bpGJyZ(pMFizy8DjP(}#Zn{FASJ4_9v; z0s!tjvyWf@>Bj(M{NA@;P_R#b@FMnC11?=Vz>9BP#%f6T@BjV3hI{WgJ-2r|6Oqoh zo1;%AfE1$uEB{l$08pk|K?4SL=OL;=YGjlp$Ut4bb=2l4KYDPGT%T6Bm!L*JT9WPC z5#9lM+oS<_is5@wqd|@weRY}q%fwGHt{V6fUai#PUAscNZ1ix>-wOvgOHF!)JKK=~ zvz1L$w>2qJ;S$&b9+dE;PfLFM`7W!nj4Va^C3dwT;~`Aevq)&^(gLuT75ZXdQma6t z%@h}JJ=F85H)uUck_k9{*y)sH2^aPoGO45kG=bp<8HoEz`zOVH!SJd9o0nC8k*9A1 z9N(Hg61**YJ7P8c)Q0eYi+SQ_HyXO%(<_!|nLOnO2n@r(akDEe``o&3wm}GHYNB8{ zQNF>2`ZAIYa+?O8-Yj{tLQ%iPQ3bO#3@yTTUHFscdl4sq| z#i!oll|}p=4brghBc`oF!O1P#d+mafrxSl}f|@6KG=6lx3tL;(PcZQVb*aZ<>-+i7 zBQ?hm-nK+_8|P6WKVUa)G5m5q;2^gpG^7m1J84^|iZkpcS_z0{d6XIn%5-VnyN=p>1JVoIpCXJWst z3ol&!kOWEB=W4HWEeD}*5|BasLT;eG8Q`J|KC>-q+%MY}_L+pk;(Qtd?HML*v@XNA zNLTVlm0MM##O0&kNni!2HuG+`-6-aYWMaVdHj)Bj`#`W%C!Np#iTKtfqI*9^sn}wb z!(_z@fQiL;4#lA3;F|jkEb#AQvm*P_)HxqVlU)n@n()-`WN{yr`rY|9Zg=6Qwjd-T zNOhUPAk&&a@++Id2^V5I8(Hmhg0D^k^L3QiIQtbXp{+@6KJ=86@ywKA`YFdWaDC<% zJAj=6F6w+)g_rDQ_=CCtq=vM_Iu**JZt>lOKTI%ZHlU6wEAc^X^ zcvEqh3%PTr|7!1o&Z}q)XkPLKEt%uG(ZnPltA_`vcGy+_G-$Y;K{fjd{@#ELkj(&$ zX=c2H4v;@(y5JU&=fKB#ycT%x^~w9T-io&fo^Q9u%bpA-&TF)dyJWop03ZNKL_t(5 zJROQ(<<-o-j`mOK7wLl*Zj7V;iciR6c?fV&euuE%bKy86+3UP*$1^P%&m_mY$YjJ< zwt2h8GRYq$9wGl$g_o>@uwBUK9L_A+O|^OaBmDtj2F)!NMFV5?XH>be8NN(%ZDjJr zk$*^a9kl_NUC%I-4==7UKQsXJp&Ij#LWxS(q))v+_77XRzMwgdP7dkFI;ktBTuP2k zKbZ`^B-`fOOjY3;Ox4eME~Bow;b)ip4PSd4brLAhcgiw2SChiY)yQ8WUjlloz_aUyEWPgA&8+lr@uc8D=u7 zT1>_K_i*^=b-3ht*<`z5jxNvpf*!3*SFfz`d2qNietxVT!B$_>!Pnc83`|?clsB9i zr40zmgt&eNzBbwFP513Ew3MBUpYn=HppC$s#k9GW#orBc>HI|^d8QnCP8D0_}n2QdNR(Lm5uGuOggHN>bH zxdew%_ePHmX;ql(Ij3U+8WH3ZT8V1#RN#()c}+wExDBwm4s5SaZv^Nb!yAGr`xAru zuwhW5er4QDaJP`uxiD}J9Fs5HPRf@+k%(tEkB;$weEC~?{pk-qgwH+ker(4P|M%Cv zr}>|M;$fUWa~3~*`zoG&?HvHX`7@{S01E9knrGLcg)7g4~PwI!KDT# zjdB_wlYknrV~3ljpiMu9m}hy-AVWia%jKfP0kkm^1gjOu_ku*9dV`XkgJFsQWcvxm zn=B;TKnL|Tvs|t{tr5yb9DKkgcsXy_4PLVSG5%Em#eMG2J;J_yl502`Meg;Q zap8eI$(>9>=m$?551BZz+^OAkJ_4A7A|RH%mYj75G`)K;>}n=s%5r?{!uPW4+SRQX z0=pgB3y)jjXZ2yBa^fea{A6HjvUeB#--RFQ&r?jJuiu45CmFEc*g@dmy{={pH&UJI zykXNqTFN(owwvhzz~RmEf#411NOi!xB@w?G3gT6cd9q9L6O&E*Tx@?xG{G_xF^%{! zdLyVcDJR=`wD#VV(~2&GMO;Ho?r62 zztO_bpq}hx+5?7tsIHr?^Mg6RrPUJJEgf#?DiZ8skl?=NJD8RIkKi{9vmX~k3d??7 zV_M8d#f9qn_@R};iJAy^J{SE-mMk9Y7@Qh5uVq(F85r@IC*9I44uQJG?52XDJq}_C zW4okojdq3qVw~jLmi&gF=uYegGP`8=D;q!zO94EQwb3)RBd@!tsu_d2_Lkx$Z6mwu zM*GaeCE4@7#>5llIIL`ZS0fwa9QAWFvBGk@x0?3(N4EHY_;-@=jZZs`k8}N#d~a|3 z*t}JYGcR%wUZ2Fyak=Dv{@#0$dS<#;mi;D=qvfdEco+JIRQCE8U_K@RDw)ae z#V@sgV?z5wvb~?gnv5$yNJvipJi`KC$a4wVm!TB8_3Ums0ZI)aGIlx7?Q-m{x|M@f z{&0QoZ8jqv=tL_ft7yxl-{ai8yrHR!l2Zt0FvRYX*by<23`d`I$V!8t4acjU+nyRY zVMW(&FJByjv2AQny@AiMQ#MboeOoPIh;S4K$x0>rM z{!st420^`KXev%$z?uoeCV+xFYNzPiQT+3)4C?4G^Drg+_E(?5JJ)Xk0QT1_{5zk1 z3IOo?-+4i|{(0!aIehxji@14sgm1p|1_0pH-U=Uo_J}O(BV{uA= zSutQHt=yYk20!N*!$EQVE6XELBvd=1T^Pt%j|pg_!7e+*fM?TxqHT7&}=O!D>yc z1GV4Pg*yZ@Bkf<-uxnFR^#>eUdO1^0)@R8`uq>CZ0h?B*P17Fw9(XbXA+=px6lWgh^DM&+`t5 zd!_V)eSh?_+=PQ!xX`F0`JSHM#0$_4Ov1r-kWzwODJHnFp1YNXL1O{Go`2(#*~|YopMDaj z_xJGJ8<+6Sm)`^ctXBg*^VmfI8DIYXydBWv58MspgjX(I)4Y4mox%Pv;O;Z0Iss-T z8hWxWgUnLLZ_y)tFeD7C6;|s#U~eC3y+&HEFs$~F{D-Fja^BTwW5$blZ;WBK#ifeT zL+R_0?wufb?%kJbZ+m+6dxI5`J)_6j(e3K;Dn&M)fIa7xT1GFNZdCNP&J$`~aB0yo zjHqP6tPGV^Duk=T9HFnoa#;m9*8P!CCbv-Ah6)d#Nl95L{2whmqgtt!-`e<~;AHA$on`RPJY;J+6UFqbnOJid|!F)C}5kI4It-qsOLafZN8Xl6@UGgH&LkRS;#0r3!~6Pgr*8pl4yQK(w#UFI z+xbO!ckGlF$#b9eZ0auY9Sce`kY&5!Y>B}2i`^sma^$Tk%+KL!K157l*v#p}$28j% zpy-sWiji0d@tCv~=9Vw(v3TP)9TjL{b z%h@IAQ!|L=@|gQr50M??Y|=$vr^4MG<({k*La>FNJ=?=k;W}*f8B@ zg6Xb=(aKA-=!nZmyqeOq&;KC0P4yx^@5J|r4#MBt(Fn$_?Fy~@%^oSQzOB$@9?;il zhIpH{xJZFD@Vo&~PZFcp)#8g}(b~wm)6k=wF@JbG>I;YGl70g-zc^OfMNFfV5-olh zW}f#40qZ|)`j@`6S#>gYL!F8Px;5b^2CZ2L_N=z@~i7_bW=e}FXbXkNq;cu>kvZ_~k zS{MU5HXn9a_`P@T8UzH+wi&GKsFf{c^FbkB^Hb+t1D1vls>|is5psE9x+&+C&^c!h zcb8-ap&9ce9>Wr6zz#v$-b`-*Y;R2u12)&E^Km=Fp9w{%3y! zcYgX;ao;C?1^0dG*KyCse-V54eE^l3p1lkE7azg;?u*zzdnbm0CzP`5&z{Vs`NuLO z*&_dD(kl_~VRhgn1BWQ}>ibDZUtS!aX6@iO#K4ZA2cu7m5`jkmbX?%g*X64r_wOPkn?bW?%*%cEYEXyv6(H|stC{umZnyU zbRe<=(Lnn|_(;BQFV(Une!B%S8jwY+$+RqQl_K)Y+ptAA=efT6IssAiRs0@*rzCHH z&B64O?*delY-HQjce2hb@fUGF_*HZ*7-ldN^{2NL+3`_|5wF>=cpRc+V!#};zeT z6sd;qb>7QIqN@I=ubNX#YwV~T#gCCc6MYgts7La52)>=6=(Z-Z1@DGDhITxYY%_uK zz?~;l5X-M5W5WrQ@fCa{S=fG%$b5veZQ1jFfQfy$oaCAQBiYhHt>cs73EX|L-K=9l zIk9;%z?K0yQ1de4Yt)~;__bl$wQM)8aQ3d!m-1`9!4=`-^WW=uJBpbiUG{aoZQ${< zhhh9|*?W2@d-2QLA-yrAk0-+TM~(^D-?RO@h=0I~X7VveC$;QjH$Fp6W5sLG8$GDs z=;6Fxs^}uCL*6sGAQi z<~;F9a?~wQ*cLjQYj7>h@p|CTqvXex$f&-jA~9uDN6PRD?5cghOx%ZK5<0JeTN*Rq zo+$tLHtJthO2M)9%XBoqWbXm9j~g)QmOL!;+bpS0B^o;fKR9~`?7;I~jTUU*FX^K9 z{nAz|_F`T!A2qfE{an1-U9ePa7suZA#M0yGl*DgdF8QRM58?T>ChK$KNQvt%#vh)x zJRi$%T^WyFa0Dy|!_7`9y(q!j;5)|Q9p-1+4h2L^19z^+gH0ARFPxP#PSAamgn^09 zLGZfxH-g_V5w7fD6-?lGbYdY9Uq&ErON@04Y!jxZ^Q&pE*r9xINuBIi92^TeIZ?wS z##dGvOZhynv|!_@uh@A$dZ(4`xf)j2kK_n{|JyI(`8O`%@dxk0sl63`?PHJPPo8@P zzxSON@n8LopT~MN;L{&^2xs=zcX@Yn-)V@Mg7Zyn;@8wYsk!Z|#2 z{v0;rh`;?aAHo0jJxaT5HojwN~+`@XZ z!RGiD^37|=2iI`(>f6{{ezS097kP8MX5NZ^L`ITjGIM>A*N#3;46?jrV;1q)+ZT33 z`apuqp_Z2+fVWFxId0u&T%vo5L~{IfX=yN!KsstNVJ8!ly-m%VK*i%4O@MPg+aKRR zh<2V=&j4<&B~g1UOpGMqAvEqfQE1R`vK8Ii6;3sAnP;@Ulg<30wV>UWJrRKHt62A1 zwDpqFv%s$~QIVeAZt4a`j9Y0xG10A5e94l&7&uXz+1ermZJX*&nZ|5a6(*`=^hW$x z?(jXA!P=($hG}AVkO6q9XmptDU(e?D>{2z*bnNo%l~t9*hWTL!(awM}70!Iz&UQ;; z0yP07gL*#3z6YrJnn%nN#{nI!fv+h;_NXV4$z2Gzk^7aAOqkxr6uZqhldMU$9|PB?(~=9 z+ENI|R{=Xv9q&gCjtllbw0FtA5!A!cPYAPbWSuZE2(?||<77kRsA{|P-&_c_z3ku` z-SaefSqyz`VD}crG>fr7H{OpjiX0E+qqO6;t{0^UFGEuSzZ!t`&~BTRGSc~qPO6h& z``XZ0CbAb}6W2!6PZ4e=7AMsFSi0(GrrXn`K&%`krq{RO>ZTQt_JMQ=r0r~{GA17; z^A+O5SkJSxOL%k@j!7WAtGS7Vx(uVzGc^K0B}9>Iz}ezF^B}^vhl@G7W)!CLokkD1 zZ`kHkjgf4SZ(%y_>6fox(EDY<4_)UY$H z@c_rgO?wddDAosgD50w2%a@a$4~vGV!j%~Ud%iUJkaM4D1<&vp zm5K7BpR^q*_U$UWk=ek&ck4PQ+XXI&6=K+dcE6S6lrQHgxEhau?P1v-==yZjj|C@~ z)xpTH6N-W!FHLheF%43#;uZZ)YGFAbAxCrR`b~WCTQ6v_fAbTM1IYNsOK;%Scc(3V z?mc%FPhPwiuV227*DqfO09-tO4rliFaO2gOdtJCm_8o-$qzncWpNjM**}f^ z^e^&RUBV`cWUp#16Y0R3pn%fU&Qdf$FVo;As^lZ0Bla5!TPTIaO$r6Fq}Sz)v!XA zR}{z6e`3(W)anNgJc7E7mqkowYw)m?d_e5&M$6Gf_SVbZNfg!FQ@X!R936VeQH$RV$juoEql(oPi>kXZ)cFHEZY#FndFJv z*S9JtYR<6oRXMtn8JbR)84c)qGPO&;^5DSx6=N5vj0qkBSWTHOe689^G}sAfW0%DBH8iYGao9 zE%mkb)i}eGiGNRXB7A)JkK5^YT($(-9Ao-GFzKR)r#woH*H0H@JJN|(uv^6itv)OC zS2%S15x1{)i*=6QQUbk-3yUWQyK*$5z}KY9q7(d31rB!0PH-J#cOyEf3~$knfL8q| z^=KEnpt@5&oR=I=P5B0#&@a%D&-EKzz5vDRnewuW_4!=nk>wJU$J=!%PlWD7aFXLc z%lMXXBYPPo9%DAgp45llcI?`}YzM-74#!pu;bVl#zku{DJFILRzB&t-ot3M z!T1RNe*EtzV0p4yf7xBrs%oPr9lCowNh#jve}{0Sn^=D;-PqxcYmqITJR_fD+KAfq zd6;4C63ZHNbAW2e6Mw1O&1C4xcP=aasCFThI%`ae3gP(8{VEHXfMxdMDS3#pwx-esWPO1D+FVC)G} zn6}uDg&!MDHc-vPhSmumA;1@sqLCkz}{X;9< z)_bR>lf6^GC%yo@?{N(4J>ce59DVZ-arp<|0>%wir|-b{$zK9K`ZK`#6xN$#4Ev{W zc;hOLp7{!HeDg~3#pP$d zj7#7AeZ2eZpWxuqYtZc?(t!23^VqxiA?)4vFjjl?A!GA!$n}Fa=$VfhMt``UdE&#^ zpTI~*$xmkPl6-kD>xvtlXIF2j%|s{Oc628j&?r}U-`Q~>tk=Xb&$=fAkU{dqb~UO- z`IU3=hPa8WtL$%g?3l=w4&uGjlD;BmsP=>{w?`>&LNA zVJ^b~VD)jzfZjy7M+hoNS3hUBB02~0gIsKFxpADn2XK5i`RMJjm6Z&_Up^w61O8x+ zCxE`)GxoCKyTic;mm%B3bn1u80DWMoA2g#f0NKc(9TVV3LPB*TP6_Oq2{|+Xe4`BRoA?M!%_?Y~c)ZdEBIZLw1O=6)hCFfq?m~x$-GdpWFph9= zd7otVtvy&RU*3|VU1FZdf61{G^GY9uu}GTrn7#e-$L7-Fui@7+%MV>Kh3oH_97Z@=OL?!@uRXFS7gjvv+y>byq&0wA0?;-R380A zB%fz_6OFe25j(37v&ERucAuGn@I%1z8?l4TlFe!wtjJD?A4#yX-H`JNr1&lAV>!p{ zGppEH>Jh2@{U1NJ_H~&y(+}jAM3>|zJY;j?O^dOuph6+xP#*DojPWxKdH&0iPD+~i z*VRC83kx9UpPB9cxw!cbAzUAT?3e?uW~voOAntCBv63w}rbdMTZk5+uJ?hGxn8|eH zg#~_rRpFNwDScDLwWxhx=o>n*Lfh#Cc#rl{@)Fx@dLS8r(M1@7XX)>3P;-VFXe zup%5%!XJPCM|kDZRea#y^SJliS$yvC_v87uF5?fLc@e+%@kapwPd#)mkTafr{cQl# zQX0$hG`s&nB%Y(M^a;I6xY!vkQo#^&e{r(gOm@WW@2%Nqc=>ptL-4`X%T z`>|c`1ILHh9v@;D))-d_hc~YQufBp?Z~PF4*WX3vC&+1q;jVj-?tKV%oWBpNGv|Tz z9)@v5x^*4LmtMuqH-3oYTk?Tp4xU|7Ljrd{>N{eR@=AiCMxS~)ZVh6h)En5C;GN1t z@C?fPbH3&+4Kjc{(q4VD{8f`SQPK$u%>310kpjrpgAgV|V40>Qk9ZGI8*sRJonjl} zc@?w;!kzD%vMqa*>^(0>zMh)4(cLGUTd%i969EjO^Fx)03ZNKL_t(AEqOuzXM&}q1hfpv z@&X`zjC_$h8d6SfwSNaz}XVLiPal1H*b&YmzH#t)UY z`Q9k_1oflTdPv$TGXo54%}H%>vTa87qlr8}kuRdY#Jea~@b?+Mm(Qhmi0k?!wvzh{ zKs62#LNk^1KAU+#Rp!__&|Mw_FwN-DrtNvV23zMO{T{(L_El^FwW9!sKzP4+xWw|% zn*24B%;=iJkQRm|F{QTc_~Px5OrAo1ExqzItyj|oo7l1BI?7ynzBlZKp_P4PgU*W20)r>LXk~rRc1B|X??V)h zDld`e&Q*5BE(o8A=fg0UAAoSuUvU(@F0n~kL08K2A_Zwn?QEKP36H(C@EFwTxQEEgITy-qvLOo9SZIJRIpK!v~O@riq+^ zfiSM+&*&ZH!SzvV46QQdaQ5{7I5z%YtHgR&vQnCDQ)E}zF0mhL`G&CBJlhO!TdL&y zlJJe<0!iY(vM(UNo`WPEjpiAa^q!A;&U%DO#Alr&L9s>5NujI_r!a8$caoK!)G6Oc$&dJgs^iTw!=4oAYpGg<2d zMp_+6;0z4@0yizw!t96!O^MDGK0Ben*jQvRE1Tmx5`dxXySN3?5wKZJLBRUd^dNwf z?BmTVx5Qx0KrLZvlyXqS@tEoMNsXd40B>HsfiFGt68?jq|7ifguYB|o{O^DKEqv?c zH?-+beBeO%kwK9&@pp`83syt!y=<~Ssq8owWYY27#F`1>TpNTxNoXz0lhtY80lRO>QsEB@`(y+x9}D) zMV~f@0FI^!U;Pbb|K!nO}i;fI%%$|m|Uq)$ke zj$U$IUf*=dO#V9AkBn@@vqhX*`onnWpR>i>Jn5^-uuQtFVC*r|R^bCDBYe!n4_G~m z=!veCriPzZ8|E3{>?uF+@dFuV(Gbwtoiqz@H#~08#C^ZZWNMEuEgR4Eqz%)QYc~OQ z^=`3;1`bf`R!cV6=TaLjy=uy{i+fuA!xIUW+-KA}>0nfOj2r2Ke6J+>{*xa^MKmg2 zLYHe_o9f7q!jtl1XW8y2%Wqk@Mxf_5J28%@$@4O_{Z!AF?Zw%>zEvB-<&vd+SYdkW z4q)>Y!uI(*=_#xJWwKqLtCR4W#V}~|G?WQrC}X^QGL!Pz;nQ(e%0JR0kB>YI*6p|) zxageie&h#+WaUa^JsfN#=!e1+O1zTF!{}oon{0`(DI9MA6;C}L@WqB1w+vfd_^kG2 z!LC=aw&Q)Gx`MM=QCsNOSl1ED-%D!YVQ3>fdgVh}TpPNTQI5N@>5t+13$r{kKcrmd zi@&Ogbeq|*N_NYiaLm)N1)3t8;bd0I`3IjZ9GkGY|NUG;naY!(;SU! z&euhT`8aw6%i9T$R@A)U#Sip-+o3%sduL+7JljN#;jzp%pWI4+kN>@|I;6O2&a9bZKYI#~K5#dX65hE!?U{dSZ-w(`r&a#jvYO_2yTv2-T>t=l^#`vii-g|2y?q>i z;tRkBK8*9<`4e1u{Uzj&e-`+_6O#dW_bu#y<4d@C^BRWzeT*OeH1Oz0faBu{)MktP z!Z$Iz_-%|iV;BaEA9xCQ^rO=Qfa9a-0l|6?d2@{IyRTt*^#|C#`6C=}H#7aG?m)W# zeb|5SgBZ`jyGk(|L6c289A+x*X!v!07thl9Nfb8@ETSCPMO?}I z1HC@0QX??*0arATYXx3%uO$;pI%Db)I%!9|JRag4q|P9LZzHt^_0eQk$DddAHMmQd zKctQM7};0J_W=nznWl4f0iJoKwM;q;;#7w@zX?kM2(dZEh>m563J>PGJPCY)8RYFC zx4oc(Cr*TJZcJn$ngFOif=W1gf8gz-E5f$}EJ_~q>0I2wWN(d467o8p(()V8FNCg6p4tb@H&+Gl-aaSSK)q)cE}6XpdM zt;s;<9k-{fq>Pri(uq)MCt-eY&@m|52HVp{Bi{dpBimLD;1PF`+WVHQHE8e?Sse4UV*ZH6rPS<`Y>yGHRo`%Z z53dwx>1}JmQQ$WF&e?zCPknOss~QKg95(2P>P56f{jifRH0;~bL`>D*g8r&qDdqf! znDFvpNPnu>eSyX(J~~k%8c&kCyq04Mc*eGZ`l0gC1Y-d7tyURd zL^NwWkTHKml>JS45G~&ntaQ-%A0H33#$|@a!cVnPiWIfOb`$eM;+)H3i5%zz(IRa| zAF@}O+RSxAf1TX5qs!1tG$?C4-&25dkhHCcKF1%$dlz3z=j@k^{w#y}E0L5f8CdVR zOd21?tVg zbWqpd*ZhK&;_m_;FZ3t1C_TJ@dixG_4&@>d6H}rU7z=@qDhHu1fuTG!+jUUnVMfM& zCufkR#(AQLX;CMy9&OGa#ZVms+wzL}YE|9{SV30-N8Qsyhkdo-Nu$z25c)^odl@$l zk8sDSeLVWW-FWo=yYc;3-@#i~Z{YmdQ@C*UH10Zc3U6J#iR0}Sd#e?4&PXX?T~;T) z{_b`B+>;Lj0KWC|n-=AqaQxU$O)L3dcm`L#{|)3Pe;RoF;}b5I-oXAh{yC0rUIWgY z!}zJ62kw7(n$TbG1Mj?s^|!x@<124ZQ=|7jgz>{q1NS^Mebn*jU@EuWAiwzv@ba@5 z-+mR_f?G-h@;wg%4}A!@`yz(3=a9D>q|G$pe~5%(Sm9{B#{Tvgf1QJ zaRuY`E7%+#%v%NVL!gM|9FTC(Vf4laW3Ya$Wjh%DQlP(-B#_&sjx&NLKN?t6gG|Pa zx2ABkM09x_7G8RsA|JuHn4qrp6rP-2XKpr3-W~^_HNWK$rC=*SsO%LTW&coJQIu`D z?Bq`;eKXnchMal3MG>}m}O`n zJce366*rh+`x>)14dt%uUQ~RcTM&4oTYnc@&ryAZJ#AqS70^cnvSf6 z4?LJgK9N2tbYx$#JU|=sv}HmP-#lPm4PFp1eJQw$Z68qEEov_V;be&pqA6}OeMUNI zYyk7x)6X`P>g?nS*wAHjFf>HGPk?zlOeRwV2k#R=dAs_vUJS>H`lyA&9Px=$ES-u*&K+J#6XJvJ5nPLH- zl^3Fi1l#*ywcD;a(SuyhQ?UmF_Y3Ny!WF#|eiEGt(;~s`*4oLCt^(V~?NKt5nxw;8 zkL4uTBGk7Z#ob)CX@kfYXguZh0JZHAbhw;PMr@rtdpqG}lj9afmAC6`wbwMYM336j zxJYR8ca4w!(j=y{Fm08rUP-yg2j#{&;OvgO>HTg?k21@y*NLDk$9%s0PF_TgjN|>*kFxXBNUI;%D*=U1I zb}RpT&XuoQfvFGTBLbsj+V#S0FXv!(0ZywkS{=yueOo(q99*E$EAMeyaP|=`ky1!L zA48re%-bdaW>DCSgei?9kdMmS<;T<0%wY}lB8kCchkj8yVEGssG9QEy+!x-ujOSjz zgr^_5i2Lq5i^m_hfahL&2hYCtHlDb65AMF>G#3C%xc~ha9)29#yY59=?;{@{Vmvwkaz+~Vuw4z)RzWweV7&Y$u3dT) zxPBR%!y9w3Xn4sw2YVg`?WUhxom?2CaHZctIl z4zW{UJWiTC?h1<>j&@f|pZVx;5j;oO*WI=8Qo-y~N%p|>Ej19*8w4T@Ck43r`U&#{ zahAF=87q#yQ9n0$p!c`M-X*fxQod(16+n%DYmjZ~v?4i5y+Jm^UjP#)UbW=$p%2w5 z{GzzkV3n$iT(JB_W+gB$GyH%M_PJ)lx!kC>AmNU7_~>o2OFCHdeZq7M_7-1wzV{|c z%w?+chX@b<=FB+f%cO|Gi)11n7aLn9|JRs~YI_M^sg#L#Vv8(+nBQt}_l!K2a%xkl zywW4On=K3@Q^X6#S^Lqk3nR6Sx_>yyq*JCz8?~!`dosa?a8ViTw9!ht*cZ0>_J+kP zVYY+%k>|4Q6IM(Y+)?LcdfX!n#4%dFU&W#NA6mA(y*Z% zr~4R^uVpW3kzr;K^HJ&y0z71dz<04O zL^SbvG;zg#vNyTK__X|MI6iVGO`Q_?aW>W48c&;PE5NyOdJU$x`aR+YkI`5+dlPD{ zn8Ki%m-TiD=UvKF@k_yLEE6sRFl}4LA3e-957@Se?-(#m{7cN}?a5He>sx0Pa`s&G zr5BTVzO{I$V-T(E+VwW3VH0~i%??+26Vcd)fK>23s;jVqdTMVIEl`!+0(dc0hHga{ z#SPlO0@KMemu0>P5;?=f@y2&#M`%#j^OoO`h*YL4_bk_}j|sCpJ3k^erq!>vlZ-EP zuyzI6F;}(!r8X+L+ChF#lDv$cB(?m;?bbaJUZpek_DCk?!^y{Tr83KVWIvWt{`X<1F!6$kTjyL$jXI{e7k6Z)*eCpBn;dj6BJf3~^9sJg(fODt!aqpdH z@xq($;^yHo?mBY{r}n1R{{V2j8FBsa2p@a+0et&MZ{hVTH?)}nz`^4`1>AWz&VJ>K zxS100>7NJoPXlkhiuKq2DUNPl2kv_a_{=W>cic7U(%}JyXa5Dpm!8KqCE$UFfscF! zxcmNT(to=J_D&6Wk42M%^Fh2Y^@X({cxeF6Zjt{XqI>0!rkoNb1 z!&}&1zl4104GeF;f~(ix#df=$crpwy$vYhLN+Xf?wssWeCR-WO@xi?Uv|K`JI zRrFB#HPb%JcqP9sjc#H`idOzeaA~Ym(Sl@nM8CJi_~%W@TgCgp3C@*clPzyB&qGy? z(67eJn76Ztq6qphoH)*C|5);sGYE!DPRtApoYU>~8Pi_TMjx~@H~`axz4Wn1GC0aA zcd9 z4*I=`H2XBH<~*$*w2>S%lR5opNAQRy%um%8IU|Vd-b~|kclveYKK0lZd`=tZ8z=ou9ly;Q{T7@@y zn$v_!M2p`8S@l->km;r}oa8|sfNBM{4CYbnquv)7{8}yJ%QmgpTO^WE#>4qDJ{J{| zkHcq7{5P?+Yu?1+saPi;jpBl}hECew$>p7N1x6mK`M z%S3>oUwjww#oKG{7b7!7uf~{xzY?FATpoh_838&H47o^TKUJnM*E4cTc=NYSgid+$ zO+I4Ic1gGDl!w{grc>g#Fh@XRhNTG&lPC018~Tuh`qhkc0$h5j73Wv6QXoesouFXf z;qBo_umaQ5OkQ_@!f&T*5#C{3~TFSF!`r^AYhviwxS@1mT;wz0|X5tOqkf_P&l$8?eLq zQG%my&kG(DuaB-RMZ?*V{7;4)waPG|gj%^-h!Hf@Et_eW`A%Olxox zU5ZSFxYgCVZJdrZ_u#+%$N$X8%HH`4IDF*8z{}sm`09(m&;1&3 z{vP1cn>h3JFX7gW>%ar=pH}>zy<P~Ax2H*%4?jI^8MInYAMM>c1>Cp} zyzq6TAAS#cbA&M^{Qum&X|N^7btd*@)xB@;y&Gr%jRv~0gV;e3B*0Y?sAaU+3Rxp* zL=CC2EXj)^?C_6?2|HxVF%#o(%;K1lMl%jmo>0iPq_CvXLW&AdqDYVghz3CHTQ|@^ z1HGg7x80@EKdMgFmnTowy{|#Zk~8AHs+*O0@|=@r%TrZZZf+ia&yA?Az5&?06&Q_x z(V*V0r#}l+6^cveF+P0^#i=70TsQ+S-veO&bUDsoXocq!oQ%03oWfB?0SnqOtUxLU0+e5-@3qdt*G_PIln>N0|M}iQM@364R;1&&S z;N7JkxkOsBz>G=Tu>Z0LZykSF4ET1QQMPv6IdtFL;_)-MvFV2~=ho^h=rh{+5L^OY zT5cpjMLYlI$`5H@oiveTTiDX4kqx~ktQ;eIWx=CsmhWf3o0EfZlYniCA$JkKBPOb& z;EL8xjE4w|wyLQ8vU8}PvV`hS{Nq>f1MkuPmTrY_Y?s(gg@=RDPxP|680NUSkrER3 z%~PSwlSqfU{Ex_86}Qz1kTC!JumahRu&2I&G<1^L7vQUQT9+d;&a#VmJmJ09Z5Xza z!?LXFWL~=T#43>;Gkhh8#xS<(ABm*+kBnc1ZZiR29b-puCfR7?oIlWRjUD7h!D3vZ zZIuFm7(vlX-i9sW1I<@>h1$xQ7Z;SfGrKPKDb5X*NMqM4_D0rcgqbFb!7XjA%|#HqwFZt+~jPf&;*3H1;gBWMBg!DUWJ&Xi7R;9jhL7kUMU}Q zrW-w$zqItu)B#Nk&AWa(xN7We@>UkeW-Iv$_R5fF)?@9HUBky{ZQU`~35*VX4Z3X| zg&wEcQ(fZACh=5XVBP1PBghU|>sxdEJVBNd6fVPG=>B}{D!I61BWp!2g{yCB3T%<9 z(8bUju`9w`ZV>ddF+eU<+W6;+Q%4>~$54p~=f=>$EWQ|hJLTTTz9Q(Tx+ZhLzE{s3 z#|sHg-at+FS0wQ|!a|?7LyPjQi1E<0i_f!4qC;fcy+>G7Bspjw!L>j5+cgOqfoY3o zdKcl*n24Fm4mPK6lNL0LQ?elQ@l&zE!RJvl$7Z;ZQ=uYovqm?Ar^S2S#_A(?8Yk_I zt{2Bq9UEXZm!3Y{IbH$AB`{jA9e-KY*Ilo6xJ5}g5EDF_JLWVtjIph`Y|7Jzk6|zx zW2RT)+8vwWoWs#G7ebdEiwn50x{kF$oh(0nX%(9nX0df~4o@C>7rVDE!8zcoue=qE zO95bg|E<7G5B-;)!P-q90It~wTs#jP_$pS$kUAl z+M89{2?;Oc!%WtztwIYKa%&M}2IS;P1OJe=v##ZWT^=jqmok2qzUmSsOBk+UgEdK3 z@M{*5nOrfiW%wPz)&9aGWY4T1))*qKV44lPZQ*YDs!73Yw7|^Z!06-_e{wB4XXnH+ z=#eCmqj6Ss_AEaizCQEv)uwl?RdFl-lSxc zjw=%cRoO_gaie{^aNkfd>}I6<%KuJGSg`Ho?SH(Q+cA>K=7pt<-)SF7hAgt#j|e%D z&4+?-%(*_NVPl*#wk%0_S+-k^HLcuC(@)puwr%O87${qH;GP$|D7t+tkJAKyq50D|LL}u6IUcK ztNN`Z{zf9liBtK!jiC_XlC3A*OYD`>kH`kAwprUS32Ew>!_$n7d2W!GiJa}U)~30! zrA>HSSN=M5H-Z6}YmmUZOn)7d$d4|1BOAa^6?ue*+#JJ^7+*XK?$T zT{!aI1w8ZCvA~c1(q^phy$M@hdk$+ev%u~50)qkY+&6*K$KiJGfq(E*z}!O3`$I3H zc>ZyWM`K{m4ZvL=sow?|uGjnhpL-9*t52gk`W6Px)pCE`Z5Z#rz4=Z+lk_io^|nHn z&H=~X29Cc4oIeA=w{IK<_8ZPD=k(<|>tlSe^QT!R8AC>aeNUt(RXfKzhzWi577o&e zfhwe<_|Dhk_!4H3ZqbvklZ*-zAvUZ-mpp8~>jg=eUvj|mv`VtT#$;SOot9U439b(D zYwJRV+4}f>(XLtGBlZwniI&!3pYZ59PNe@=T4*7qrdhV>bBq zgevpUrM^oiFc|MZGvUcqRnhDzFT4<#_YvPZ^j;QQVN8!W81m`7 z$hbj=sC@{gBq7_#CJel#fB2EPsc7}nv4mGg*7Kkb1aM+ff$f{nV2wfj^qeSE;y$jO zd&b>4)Y}4$f$^yRUXR?6M}hiDKCKVR&kMaCXrI`pHXf*7cXtZ6Oo@0cIw12bM|mw@ zo|;y=VkK;Z53FaBh)5Xc5T3}^cF$MszSL45jmda6b-ZO&@J%kBk6@S3+9&<=v_lNn zl1cfYZExAHw_2!1QL}8BxR}Y=NuyunXC~N)NhRkec`HA*Ny%&9uJdQaPvNgq7p?dx zkjH*X=2&>8ZI5B&H4VB1`;r);1f>ZTX|=TuvGjJD#k6M~5Z!@IueAo`@vSi|7*?Mg z&bf6|XPlz^N_#Q3(>d{ud_NQ*1F()6rcoX1iEHtF%s<|C%s1nA#h-!?!_#pt%k@S| z;xpC7ARi)AJQOKvuZ*`gtw7%)aWH*_(8=ePEHbWPE+qCKymTBabz1iIgBFpW;<1pQ zcT-+18Dd-r&oJ+DgR-F?jol14U4(CB!;;uma3!Y}v4rK)p}rYiAiQ}Q`jWkww9Yc) zDfaQicdezCEi;2F4 zlk9Qcl&-|8l}nli$4NSRImNPlTz@%vQ46MQwVBHmb{3-hud3vHH2a{ic2oFAc(HtL zz%TGxDLcomjj5&Gq?km0^EQ-|+9x2%_I1ve$-wqnvRzUKsL*{Q^3F5^w5J)>vF&h~ zC;tI^(2Xh{2k6>y05&YH(!N#OZn++kM-u`?Effhph~_IAGm-I3fZA#J3>tE!D>AFs?k#Ew5qMrbPh2t4B}c(|6r~ z-+AIitdHc0a$vCMdH@v$Zy&kC^6}sPY@O&odJz4iZ(+E) ztW`QLEQ84$Nq|>$2O-q7l@$)IoN9!O%=;FGIFPVdumT1kx#?q}7~3y|c z^muc4v+zO~O6JnWDbU;t4D2M6Mob9Rny;BU%g#nJX2H>=(~!sG=6qOmQFz?}SKGi`bI&KtC!Sxjxza@Yzev`a zbJ4wAAn1Yi+X3=sPqVlbd*C~sptO=Z-XkRbHN9E-8()HE%w#Td!I+Y($k#N!Ne|36 zhH+15&_j`4%NSZux!&nXl5u^EgXls6A2khw0Z@*b?*jDe`ogz+j? zq4X1MTHg)!wbwkt7C->fx4DQ$`VMlO9BP2`p4)nC0PVi`1Vb8`iM5OkVLDCK72AiH zUse)`f6E+-FN+mEg}(7cfI=)tN63Es0mQnB155Y0&< zj$|-_H=*Q`W7gbS^Zb4iHX)9+?6TNgB7BqqMWupp!2Jq``=g>z516}JDj(1rlG*8%W>b0=Q1mDO{;JPM; zf$FRDx~l{pWo!%Q$ifgplqxQBC9PeZ<|5X*Hx1wDj9K}-MnktcR zL9D;;2ajZ(rN+yxCjzV~Y=w?#lC^Y4XX%@KJHm<)99^n;+a~|TcUxmwfthB|v`L?? zYg&n-#gw58U5-!F-z5j^KmsfVq+nV{jl1J>;U7{y)c<8LXYFQB~p1ll30|^D{kM zxpfK8zjXq`alObd9I!Cc$84{M!Dx)LmsW89zWu1Y$MJI)vHyx~_=ms!XaL{u^)cLk zGqxUj1sAWl3U1GS%p86l7oU9+Zqp|Chdu>t-U6%*u<4}(xb)JqaQ!~2`yU4O-PR`a z&!2;P;Ys*ohill2TY%f{sXyl1E9>omieCL@z?oCP+pht~4g-S$hEbp<^U`EJc&}M= z9(bNyESuTlQaQ8&ELj+7S;-YkCv~7|y&=S%9OFm*qSrjxiCIpqkuAMdL_`zQiS~Lf zkmSaJPeKP$-3ol8wi zpwS~<>@xp++m3Hu<%aM)AA&cMY0cx;RZl#qDta>206uZLm|ow)jO0w3HaBCP>cjq= zdC3Tvbj#ejRL%l!lZX+Ved~8+UL=SCl0{+4-4C*8p-no* zx*PPikuxhP(CKqsilQZVrfwK@THabFBg`M~ed~bmcAgtF+wt|tzvPBhwvz2?u)(?r zpV%I={-ZI+#DMT!2A|3}$5jzOyyCO6*Ws-%@d1nv+nEk~5%9~{xG3&PPGa92$vMGF zl7LO0DA9_%Etc&ST?wGsZ#fdZjLq$;5A-3X-C7&yGKDL$`zd>8;hLQXAkt5bTJAS5 z+(O-iaV#7|yxM#ey~_t_yPTL;;j=fMSe>G1`=VtYKm2z32MIUlp!?+lmL(wtuEqC)b2d{`h<%4?vq__8EQ%+8z2VjXduk z?^@XMrWgpDc~+@#JPs+44>!C-9SXSwYj|G`r@o>WFFX(? zln928ZCwcBL5(uSgSHH5Dzrj+Pi->7&uw*p3)nojcx-I}q)X1(y4)Qh6A0qF_&{Ky z<+L17-vsdWw*h23prT(V!K1NV`t*SV+9yk6Iu4$AFAQ__wk14s_+6|HM%cCpcz7(% z^)NTn!}9t7C(d8Qz5A}h8z;|V&yLM_{rG!$@tu2IJYN{k=)IIwjmFj&Wy7oWiSSDr_IX)}fod<@vVx8CNb>;Xp(0na`Tzj_HpuSB)? zR^ZmVfrZWW&4DrMC;cy+0S>(gymP4jP$K{{qZAoKV}4|j*jjUv7qkILRIh@OB;IoI z{%2i_;OOIbY<$(8)SmkiuF`;mXFvtBQW&P}Dd`dEGe7wo1=Gzp0DM7h37>3`#k7lq z@`#f1A<-o8S$>hyrh`^Zri^RZp2$gy<5o5&wB>pOp0??rru;(!2{|t^#x;am|e+UO9^c`+TvP;UT4AB~lU zbcj=Ue&b=LE{W-zWPDs5M-^jWOmUL;4JjUpt<~q#Bx=nhO&+Dh#s}8(WOq%vz%uY= ze8O)&acO(T%~F#{znjX=2NZRIR4GKnTfWIZG$EAGI!*=ga0qndG+GEl>TvIPulXEFY@%Q zG%|I~nTI0v|X<9o*KgD^T?W#1I70X*8ZT7#dCFCwHwKImy|W=Ht&I?==P z%5viaql8H|{gJ(AeN$uWYrG~GdIAk{%~87!JIVehMbM}VgQh>7N4u^rQo5({0smi@ zoNobQIqN#=!g)2BZ(bL=qLpuXsEK{_#ti3QK{0%9Rgs?(ALQdMLR*k=1#iP>u->Wj zDg!fGOGrPqAKZA#_(aFU@3)Bl3oVnTT=OytJ2<|e99*zt)8Nc9DBJ$9(c}Q26OLh+ zO@}^Zu>yh+TpPH-GWXE*vdKJVnU{U0p>f zhK46?5~skt(aC3-Q!$jTap+aEEzq#JTiQeTIAPJeq{3g8j}}ydYkhd_SeyL6a`O^~ zqY5kQ!%){R3iOHs=T_D*t}5Jm)lNM3_6gj*cQ-!&m1j^jcN1L&6npk!;p9=A-hB)7(bw{ZUD=YXv{Fns8HfUP^~Eqtm9c<}(-YtO+~ z9@w%S)!h#QSMII%TpkYUr2q1H;Ek8z4!;6FTxTXH(_seU?1aMBK4@bVapDsLHZ`VR zU}r_1keX^ysPP8Eq9z1QG`<-K1MO27P<)xPm|Gg@HfV8TJ2_Rcf-r4JI3iSY*#*}) zZ7Ya>J`tL_$kY5XR@Zz**OW~Ts3!(8MlK5C$ri~`@5|SG45Ohj|6+CF^A zYp3drz8=y1SqXq?N<q+9|!foS0qX zox}N(c1XW$iIs1 zi40|Yp8G(jo(4V&eIf|jX6v^4BD>?9p7`V>9@|O~2A;FuM2esGXW_VRW}d!1UpL@u8D^O&3e@ZUaZ@K3l@E?^BvM#r zokRHUQ+N|z(HLx)fh5PN+Pp_ecJjsARwuSjZJX*n;$09Fy~4xyn|!o#aTALcB(h22 zx;&I2?Q)9=ZvtPAiWpUG|8kc1_uZ3)Ao+8nTrbzYeLaMYd9KxgUvRC zCnzdfh8GI&uCW9BMiB~iJp`f#zRAKtIg_pgz8R2bWFfa`j{-2}omNgq?R7mVYc&RZ z6ZrWOaI^Ir0i|o4yvA3YG5{1feCjN`_i)Z(`_eoB7ls~=#@MlG9!qmGc=C;Rv2}4C z*YDbjCl0=YU0W9M#b;j+xEK8b{T;ioe&|)q-2V`YH($fKS6;%x?RTQM25x4ggd;sC8 zWshd>Ue^v4lA{h`AMms`jdU96IE7E_KMc=4;qwoB}Tu{CS*RiL5!bcj) zS`TF7P%Z0(Zm!73`YainCUKIhx8iBGJ6irsII91|h6)Fr$dJkMP+Q zYmQdT-4zc+W=-^jWIuY_i{#C@#@{F-BuQP2hONA_uh#2Pk;|%Ve}``Z zS-y(#(Y6wH38X6B6r7R=TbK_H(f3pITdavsp*aXh8Ga?u4w$-}@QJT6Y#Jk3Yw}GA z<`vOdHER}m13+X$Y_nCgPyCx&a=EYEZ(Xm~w6gtY$q%IxjKF$BKXu9ZIz9ImE>?X6 zljsP(S^P_GzW64V#uX$sEc=E%k~o5M6S@8TlNe3tBVSlGyoeqS29j-qEWU~D)(;=* z7=cyBD*SQzWFE>Ek3`LsT@P-7Y@e_%vSG^3bcvE-KY9s~f_Sdz0GI2M0VfDHw@ZXq zy{a~ao}`O4jtXYic%5TRIY$#=dZV2ZOje4i$3ndT z!Ah+_qY~)#>qLYzl48v`7gpD>ygtOz+zfVXT0liOzjO8?wlB?NrdQ&XcTeN`U0dM+ z%+K`kd*6Dw{m`%XnBTesGlMk@w(r8$nOU59=5gSPD}lQ|jQOI#*_WONUN``3+llfM z-;eP^{o!DoIR*FlpJV0xSzvw%{+X>$YzY)4eVTs~a952ihT$^yB;hqr9@*{Oje~@2 z;n_GHGb&>mPvON0673(t4QHTEKxi3}-&M^oFbqA<%63F{i_aVSBOB3G#IB>prR>+= zb(r)O)=4_6OrF)z z+c6t7t(h{7-L_)ph%m9wgj?`AXz}w5L-?WN1OgkMP(OpZi>d4wA?I^J=vzUIhJ zMKOU(z-hAEp&i23St5T~ztfzAb)9P1wRVVTfV#<}2hw$_zgO)on`w>Pg|CJmWHXbn zjT&mW3in{&3_SV9m&X77u4IK~x-=6#xJV!aFT zsQ3@jC)GA|P;EKx(75Gj-cWq{K6s}6H$eF03~3iG9pmtt*0K{3Fm5vewk|3*>Lm>< z<(;NzL7gUHGYJ;s5bgJl*lC4+bk0fqod3R@q663XVvLK%lO14~aK!W$IYfmP;!DmT zYMTjpm0052RlfluAO4@cfRkFzUl^;7@k$jWWoQC+$SxAz7NUwaYbi|4WB z(?5h_^A=PGUqW@@F<|QsY6Fk0M%RqwHM>@ZfJ_$tOL%fJ=a0QWx(Y}*N}uhm=p zoIek|{%zpRSL>~TfOz|rz~8`xJb$`^f`pd@QwL+#LZWLSrRTnDJS`syng-tdYI`n0 zp!brLfKD6i5W5sH-igBj+NU*r8ynKsd4jYli)0$6Yz|R$e26{hW0NECw559rS_*z^LNIs$FIHIMI zkJ?eGb`waBe18{hN_H4Wwg+CdPZDF?S8yaelh}=T7cPlT2-^HW0|}Sbx6oJc@F{zl z71QWYdqEFmR58xVKIG(dBkN4qT; zm>5MhX28+6yvwb{qjfBS(>KPnKR3xWc%j$o`a5uzE(IG-{fZKG^1spBnX-v7UF)|r z9i}|fH2}$@`0O)-pQ4VzFE>DB47N#Kd|uI+r#5A&j7UB{n3;9uBhXOYLJmFPh%5Y=p*Yf_0dO^l@ zMUmd!OAMkhwvoxr001BWNklP$b0AU$4|e4_2DSA zD=Lq2VF6Xy$3m~fspp@<+#UB}cF%r{P8`MZlaIkIE@AV>z6brS+p+8&=HGY~YfpX^ z)o2LZcpGr{hk=>ddT;--2fXz<@cfg&rSnr5T!*4RgKBObWp5UKG(=U6fVJiJDGiyA zNlt?K4c`VI9zeej%+AC0`Y7PxheNpG8pgvR0Z{;?KwH217pe)SMNnd(<)mpJJvm9R zO>iPV*0uol@Qiw*OWF1;pJ)@?!NDjpqCs3b2IJ;+zZ@JM*Vy(ahc_>Vf_;F(*~QK< z1p6BqL;4ukH67M<%irYM()rHCIqX_mz?S)0EDuIl9ggtM`Ab+My`8%7oXF8N7ZUzV z0wVpK{raK?V+J`YcuBVW>f$ZwGY`}i08X<1I!MxU$2Vjq&7ocxMuC(XN8191#eP=i zipLQi1U@h?P5f8fM^ zvMmw*WMncI-*zsph;P|NPt*~~+zTI~&uL`jljqA3NZLj_x+!J_k3l{}?}~ccMA<_- z=t*j0lUTy>;6jUj{afZ)ZZ5FFBO1fUxQRX{!=oNco)~4r8BP_wj?UYG5PX{0lQ4Ir z@1A(kRRm?v<8=sv*5`uuO%Ap_)1MOwL3S`5o{=nTTtRlg$9zwck3M33G;pFSWLvED zNTOTh2gEPPwjVquZUC-IuKtrR5PQljrvfp_h>u&h zHhzga<#G$!7Kv?0Y$Nd@`>;Ffj`7xk6$4rEnYK@+Zg_+Le4g_k;x8Is=v*DMCGmqC zEjWI{^;|Is;dKz_YeJU^$}>$o_P4E=`6^%AELo=n6P4jrHnH8o6K%${Ig?{z6LLlL z(K7HZ{wYUGoFd()AN<{~5Q8ZI=6YC-9f`4P>m!@%sh!eaEwiRxW@0QJhiQu9-i(b8 z?Fa;a06M^CeN{GD^qqar`&66uk!W57Sw>ISzMo04`6QFPOMcG+$+yv z@bot^1~7BqLm1q02YQvq$hkWC|H4yn2Va8MG8yC-+E}n%y{tk*0@1h#4r@9dFSFzp$Slk5cz81w**Pyqs8RK5_WS|F%@fhWJfa>gN z_!CD^o;Zf_XxIW$a3 z`tn4y2Zlv~D=(bH$u|zdbHGRCGatSakKDcwV@kf3MS-s$Jc57wm8Va$5 zHsc@tz(+7Y)30wHIlwuGmBA4I!yi6|lb2R9-9{v!c@q860L%)%8(Mgl&v# zK{8HBoZzY5SjmK|x8xfSo3{bVCOIQ-0thVe?}+0KUKq=`g}%|*3|i)cv}h1B#xHveaLm`ue$2Dy|fI3eX%W~J+*Z)e`QhXX+CoN$}6^|`(sCOobam^`m)jsnYlOoyJo2)?#!N(UJ~mdWU`bEPkl zFEM;b@&+uy(RI1CzI?l?Pp~7~;N$i%t}*(Y{0{nO$%k}z@jUPYOA*RaM;ThvpJwFP zxti5xf{f;#{c0}vf`+DKt{dAK_`y7Nq<1tXk004J5;pN^k*`Ahl&?dqXJHOXgm05E zTy0k5dSI^uEP;>ww&7h{_u!`H;$Wo#eE7)cCh*raU9@B~2Ykmx61;BPq+<{uw@ z%)2N~Q=~@ZEBkBZ3IG3AteDY?qr2?#Wfx2Kl%6L3*7Eh9Ky)}L7Lj0sBE#D12k*cT z?3sL1Ou^N1VaiD~cs!;Bvnv+K#SMurG=QVj5CHY!Ym9VcIcPaznr)Rlp6>!_Gd3uPBoP;=4mU9O0zt zpG2SbyV@~I!02@2OwmDcmM+T}7<^9VQY$Rtc9G)AA3xpE5bAmW#?1==zBMjlh|p{9 zEDnJ25Z;gBt7c0bROlB4w#?7r{K`5mtPF7X-racYmA7%Kf)H(d_6EDW!Bl8|J ziwnT)9C~Gma|d6>!o43xxwHu@-~2MxP8`FQk9``mSMP-%k1>4tIgFqD8ZbKteE5@? zx&CI1hie%1`oQs{n0e-#7@Rp7#YLJ#04QhYF}~vg`0H)}%07zm5Z?Rxuh)ZzLvMB- ze%lVXYj1?VbOG~kzmD}cUqQ9DMtrSE?#UsQJ>aH0fPFUui<{xAF{)}@e-lCI@Am*V z55Hvx+;ul$eC8zZ%Co?UBZy?G(TBO&0?XH2kHMy`%?+4_$g+>V1Bz$Afhq)QCCP*6 zMJoq0^K)3g@h;$st1ukXn+Lr)Y<}kjoP6W;wob{~LpNN5&wS(#=<>+z*W(M%9>kGz z7h8vwvk8sf{QM{G#V>r~z693t`Vjx((F1kz-?!~shpKER;rff8xEG&$=+02JJ{sfE zR}R++_pXwB=*{DSy;tHh58fV{{KN-u#i>iH`0WEPr?%4an*bi(e+@qKp$~-LkG}F2 z9)I&_!-q`JrghtUeCnoa@sB?JU3pXU!YFUO?5Wv<`DPu_P6uHCvR zfjLbXjw}4DuRVifmvr(USeotQvk%;k#hLzwV4hi7!xvsTjDP;sXYkC?lL)~#fJnA1 zK^U3f%E}(&C4ihhIS5RtFb_X;wPM%H`%66O`x7n<_ns6%hH3qolIoe zsrjaXWp0_r(aj~xSaE#eCi7m)5~Cf_q3o(GoHYy`H(2B4^dgBl6fPRaD8`cnhV}M{ zmK{x~>dSs0dK<gT)%G&+aXfeOuZY>h zg=L~FYd6#5EisinjA-R?o5F88GY;~GTJTYVm)I?bD3QfuSZa~bL;TR!^*UI`2@E5Q zsXjWZw?*XSx>r16xu{U-{Yc@H?mUzB1H_mBOQ(OlyDCs zVc8(db~6${JU-g7#IE_qKL%D9a%B3grY{iNGxiT5R#CQ;*8|yj-WoHms^5}Ub(X!< zeUmjwQ^)o=_}0J#1YO@~Nph-GZ?r911B{pvd_HNBKdIyr1y(!Dh|BN9h$Ef@W^&Yy z98VC&Dz4Ws1djC=jTOx{($^1>3WRom8jgiiLfd5shc3Bf+=iVN;(o~@ufzC7AIy|~ zJU0TLKHe9Mp45}_H!w%zb(~*bZorMPW!7PCriYW~FQF`eYqoF3(}&;1M{l_f|Mt-X zIDYO@f@|69V`l4ijE=m8a?3U>-uwZK-*^S*pZ_*C-SZ$8Z@dMS_gFvp5>^j9hGKCE z3m<<3+xFdr(Qtq<95%i39PpQ4#Nf)w=1{J$q8JXE z?`rkx4=MNha77PeUyol52XNc303P@*;Ffz(mf~!hft-hjM{hg^25Tq>>&@R9-1;)k zU%3bKTein^ho_TezFJXO-@O;ux((&(C4#jM4AxNT?NpSW49CWHD*$$HS;A*1=^pxK zr=b&A5@>qgzBUJ7 zqztYp+y&nNG2R^~-7k(7~`0qSyCjN8f&Z~FgcRu@r_@969V-Y+)dhgqhdS6BvjK_`W zvHz%p6c1o+xN+Fq7v}KO_uYyw|NM{QXYRj^aHl{0TLQ7*Q)GW^`hy%hd^p>EZO5%S z(*e0va(-OouhR7dJ11_r1&IeOl%%bKnJr!&CzLF#2?0LSl?#CN&(K^G|$^HOcgBdR!@4?5i8zmPAH(x2d*v4^lRhJ;pRj+ZU zKSw+h*^s=%>9UP!OPO~-aEm7jxURG)>OIN%6TZm_992WWDR}DKJJ>~D}o6>swAC0>n+oIb#H;bAWo%4x! zmKjs$XeOBzE~Z`Vu*;#2FO1Q~KSsaH%Hd?{c}=S8(}5?CJ#}pRH@HMM?9d(y*UCPS zn!b(x0qML1y;JKvxVSFZ03Y`gpAFSdj`H@=M4>heoWu*2Z??Y`n+4P{qigNB@UaWD zMSJDr>k&Du%Tw4iw!a!?vSw@SR(J!oX(PwnU-a;nBF^z|9^5KZu1#`9(cEia4QpOK z;17aLqnK73tFIW4?7~bOle)&jD{%C;=JKrfCI|M(*qBDZ4HWZ%%{FlhDx zzqGQ7D;Im1?Uguu@;zL$Wft=@JzQEF;=PM2_>*T|C4}0;s6UJOxmmn-WcaE=?vdBuvOIWKjRR58RGjMiTpn@468; z?A(e&r_U0N9;vPqo*DjJxp@J<_LGm`hkpI{a7sUw-ho>vtb;n?o8VHnyYJd7@x8ZQ zpR~Af*H--4J-6W3zW(hAgYx+Gc(-1$4Zr)jAHp41?M#}SSy{uO)93Kcxr+cCc5hz9 zo~=vKQ~cfoubn!pP|nlieVx#+rm$o6)=wjN(-^09tHTlAK6|l-9Yn=pX||8KUWuKH z^HKY4^RxJuKl}+i_0CDWc>HW8IFKVfITsd&p8SSG`?O((ARQPbPm!r>Ie#z5u6AKO z?FW1sxH0Tpz!p8pNB&RDjDFHYbSo>@mm6FOUYu}ML2lBX?G6WnglClW)*#ee8R)b{ z{Ex+t97!BYDH|zvnEj;=b9~i&6QJ2DsGI>%ssPxvw!6yNwhmw5Kr|8GIChG*%^`4{ zyx_hgk#428p6d;Jz+>tpS_GS~DLzC+;mj;|GKV}a z$+X6YS;4ScfJ$a4reGLaN2am6ToQLuAr0tg0;5aDO^$>n+{aV6?pOLs+K& zPaeJ$27{gxm_H`QRzY3Lt15x&homer8d^+cwA(EfyaF zv~M{;@i%&)A|o>aXYnD{+pmlSXrB4pph0&HzR$OPb^9(E(y^@e@0Pz$@GxNiwUuVv zf@MYfy6-ez4zW&AeS#jzNzN=sYT3w1<$*%m_DtazNy9PG?~++Q@u}@IV?H4E{f7K9 zo}ESOXIvGXhnQE>E8MO?jo3!HO!=FnSsVE@&4`JLmqa?>pS#UFhQBhi7N3N_>AcI?2~+4nGB zoX66&`|#e^9)g(aeN|b$!-+2?&)8Bv}*4z0Eg~w$d*l{JW|5o7Y>oIreIb1mM zM$A%Pgw8Esc>l+MZ9Czcw+X8L42m-+Fn;4@;N(%b)fK?iTR2w*;1}v|0*r3B9d2nW zTr~zRok#D?DGU<!6Qq zuE{gtvmd!LyT#3CKl}mwA5Xl1l@Wc6cY;mXK0k}!_^Izp68~?!cOL)hYtP`1Uw8ut zPt!LfoWt%-3;6gAd+f7JvZU! z9=sEC&ByGv&ClW&KXMoT%Rl&v%_I-BLAJ$Dww>&!K=VkBC7Ybd)ah$o3mmI&7s^S( zj_R{PKXu71o*Cb&YWJ2;l2JM25~r)$HulF^{TNS*hZ1tw2Pt|i+PfA_PLIoIlFiGh zWALMvjhEO)Y%lR7^3_$S20Sn>>Ko2Q*~0KmJceG~#x;5pw$uRet+7YqJCZrqF#}%{ z{0gK=`GzL#Lzot$d5AZxx#U<)c;(P0m%Q-J#~q|z&yxik3Wjrtw-gcmbn)+^S3fk6 z1eD6(LTPQynts{t+&Zv)=$bAich(yb! zU88Y`e&{}IZ;57!cOzL7TS8kyi4IvlIZ7mPEF$gsTX|P-fNGB^FU-y#|Ftc>jBA*#$D@H6DGy--^g(2FZ`jcYb;;nP`B}@{dC!E3xg8j zMpHx=TKM6bY|F(u%l1gdRLbm|m@oNOf#Bv5o?w-3+Wtr1YKaU;%iqwJiH-(R*JT`~ zi@BIhKt%CggRtOi#%4LWCAe(`!IiC{rApgsZs+3eksVZ9N<}=(*g72tMK(VnFxIi? zO(=pRZ$@akCnVI8b8f5qMLwgEMSi$ZaELd^tswusQIxgWi0q48_bq(ZdA|9`+vap_A(#Ru9DFzaEK}Y$ zF|P2zaib0xN;e|lN?r;_xoX({Nz01PXCyM@Y#QY)gJ4sDxFOZC-4B-=`HdcEfiafH z^z&mB)|1GuBIRkrgI)`-5u{*b1j%MHIbqKXOq`RJQiWh3l*>3~P9*Wd5N!yhP7`L0 z<<*d`13U&7v9I{*ML9XXDl{P+j)=JC^b^_`=5p-+Q&dv65@#-6ZqJSHX>cszO zjDF$jn;tyhf^cr%Pt;r33`S$j&$OR4`I(3A#Q*--vp8}7QX4Eu-^LdF^n)M34ZF65 zKErW^)xi*(=V#MF1SjoGJk>eiNAA7}x9;9y_XqHq4}Adt?yJw>)bd)?FD!&*LC$+2 zTTkFM<)=S%JHGwS3HwFETB26>Pg|4>V5!v;g<-*o^=9uAAs`{V`i%#eI9O z#3ygsgD<>%mi52acjcQ6?8E^azp#wo`Sxr0 zqZi-6fBx`Y_?>URhOrfdGksJ>RfQLhp2nf~&MP#9{{`_x$-DeC6A3_7d0bc@VlW;@ z-7c;V0SCNs<^mo&d=$qnEaRVi|HI+>_uOQ{(r$=trw){K zQez{fgWoY;G8WZw0z8-qg;S(&+Ws`WVE>RykZrhV=gPl3_Hk!C#ZQGruL6_2D&K`p z2XDhzR2Mb3^uic4N>Gq|c_2J7DtpleU#;Y=YF<$vj%z<#_Rv1*>l#Nz_yoEN1IGsU z$R7Fh;gzt<1<7xcWD{P~yhZUX+W8{3MZV9R1Ez!FNI&MYOWT9nUSlny52`}iZyIuXbpyw!d`;fuhNYMvWMG!mWG zyml4#ivhfzHxNG*9?~Y!OErFoYZ_Y;#-a9BvP9eGC_zXAvP?5?gDq~_nj)<$eT!pK zZP3bNB(})-Eq&U~nT{a7JH;=;eNtj`qA0NK6Mhm}3F6+U;(5sUp|0daVx!bBUg0RZ z&2}idE3SF;$DZz{ts(6_4rRc}$H*S8NlF@9a0yH7)E5`FlJenJplzn3q~^ zn4i&}^}eXDG#|6^w33whw{Nw!ETNg z-W+?FepK6ikqw77=4Lo*;NS=3k8nxGY1)PzW27BDfgk!`rYtBl!Z?D1UT^54dDtlf zq(_NgRd6DILUYW1O!{^bC-{sJ^K434?SijwRub*B`6o?w5SS{)&2n-<=_9IRLC9o@Ede&;5unnr9h>9#0%eze;4zzyr=ded|uHR3@A&kI_L4j;zu2M zUsxU>3M3T{k#HJAv(v~e8nOzKSep2}D`1J*J5^;Eq2!$AGU}gNhF(!%%R;@S#))$m zv48gttPO@(9gML5%AGiL{51aLzzg*PbTk4+%fRqFFj%f%SB3)$hoSda*tHvHo_ZYp z>#oP<{kNc4K95U}|0T-N0GmGk-B{YS8>I)Tqerm(l`mmV$8y+4G z+o~b3z7~s+Z~8Vm>3szpe;eb$TGp@hw(bP3*@ymc005|ZecDIhsyAOx; z<%_^mU%}$H9>w`1hb^L_UsX}Sudkpu`3}a-_X&E{7^ADMLw{kh#XlIzy8qnny}*tu z>kk||hki9i|Ja*YtH$U>0Wpmkh88()c{&)4@mo*4fD5bZq3)L5JMhyVz9ZHT`rElQ zkH7zs_}c(~@XTv?=Ew;}ax;HCCi9Wb7yJF_`vH~r_@{sRO&mJaKD~a+?(O)IyKY9j zM>`On^5MN_^~WHa!rwb^4)~QH{3yQr=Dmn2VANaUNGJEyj4rQRFV{ z4=#3*?Y_3Jh96Ayh|Z%rZ}W|Ph5qa6YyP(7nv^~rH}ac&jrxeqWEfoujLwO2stvbQ zy4wYc#|`$-)85unr*+ow*8)R=?w}WhfR1yLIZ`CaeB|UM(95T)ec(CUWnXUvG+qZr zYxSQWx7QsIJsAif-qV)kwQCX1dxCP`a0AS@N0uM5Md9dSpUcqC zbO34SxL$vI$sIJ~@-zk<0bpd<6=idv`}tPK91L4jAd(NuCI>wA+{?M5SNJhaE<@Al zgnpO8R``PBxCfu8=02Rj$$v4J)@iTQ_M?l%&zqV$Flmjr9YG8RO2(LZ&!Qa z6CcZ>d7D^`IZ=NuqgcM%Y)41m*g)UpPCNa8QK{$A$s)I&NZ>8nn_{=crtxE z!6Dkygg3%y8Rzh42v2af9_>v41=soz3L6n98aPmL5dv-Bh<2AQ(!9ki#PkIp=-c1Z zmf&YeVVK7nrZ~?aW10qocfwmXv^rTJgNTgej6xX85>Q=lC?1b%204aMH@G=hplJG> zTVBD3ZrY1i-#v-zc5TPS)ph*A6EEPs3(em8Mf0yhosbxwN52?gw6>19-Fs1;Jc{+@ zi`abMgDAYmg(ts`l~c#C`J>;3g+2Rf+}}Qg3xD|~VC7Pb-=xy;n8_%s3TNk+P+Wa| zu9KqM;*Cd9dHB8ifrU+|sxii84-02cVeaJv2nz}WbSQFpG{EwyW9=439mT_88-OkE z9s-t^Q5FUKcmynM!Qk2(X}#PIG&|GB*=ujCZ+>`>s@F$x`WR+UzKiTr2O(I3=>%u{ zCBE?7LHz#HuSWI%;A3}V=h8d_3AFyb2k*e`SGU{ETv%PluYTpJ_(Qk}!Ind4+kf)r zYw@A$uMWQtojQmA}txgccZ1O9g1C(b~Q+i@*Qi9ieOGJ^tO-pT)oY$^i`MW4hmW+dh2o+TCbn z)|2dc@ZPk4_r6=OgZ99G=iEj77r*-`&aVwxyeB#F=m`lUxSXb+Rd^8wAX*ga05#V) z8Lu64WiV>#1Tf$0Vb{`J2fh>P!;u1}N`eojBZnJOo=ggkbg=@vuHZb#ANefCY2qR( z<4@#wv}ozTB_3G8%rTzgf@BgHoUwT01%>!uSp4utti*9k(;;~a8?Twm1l%au0)8xN@u*om1=_>C(m-xL2UJOB}%vfVs7V4`A(L#HlhS>r5oCG*(2jr=uZnEThxd zRE?8v&-f)b9boHp(0?D}63mDAnGS!LTlj}I(V!`eC<)XIoRbMlhK*P)Uq}|Cy|!J- zGfoKbIGy09i1BiB*>yd{JS2Q9+Puim#z&;DP&7yIb$ha>e8Y)xjqE_v*il`tNAl*H zx3ZO8j+xNnkSoH9@DPpoP1ZU7t>sDPUyT#Giaa!116A}pQsPNP>u5A_ZT-Y}So#a@ zo@}GiPlneO7e=z?Vs_`y@qqb}bd9Vl)V9z_an!gmSk7^9v*cWC!vvHP6g&K*gB<~!Qsy%Y`GY4P)~_(v{*K98kzl0mZ|LfWx{0J8lL+9 zPT`h;fk2b& z)PyO+qtHZHER*0yHd0`AFeGQ7ctNgxcJg!|8*ily3DP-%$~fJiW?x&Ar`-ch10XnnVo;B~7riI6I3So0f2Xc@?8-jN7i=jVE3^jE~;7 zAAfS-1w8Y{k#-yhv>$e=o!;EcEW96LVdoB<911 zDEI8g;-)1al1*S{$5p_#D=^zU^^f5YGjAWnSUwgxRf%zMaHzb;ul~hTSQ!jM{jIxq z;>Yg46+y2X_&XQp@bjOzH-ho|&%A~w4Mi$eQ@7Z_|z@eqP=m+Z#QXMq5^IJZ=5=ZU;ID6gfq+SHc>ZSu?@fe zQ{RV8GczfE*`jP)#ro$%Z15v@-H4m7Xtzgt?%h*(?9dT>>#d{s#+&bk`ni4&pZVZz zt-OmU2Jx@q7S7?3Tds>R`S;&?5r@xS%=0@63?!KGs$P5q5;^5E(yug&Z!>j-1ErQH z6aBZ9bZLexT>Z9^lwnn2bui-2@p%-SWOT$@C|LoNUMO{yuEkD{zmpOcp^fld|i5fpWtzGP)X`_RZhB98dA@6E`LN4E{({bntEqPZs=Dv)n5=01$C@l`)9`)}dt zntzVY^;moae|%H$sG8*eTD=8bH9~kGLKrZdE;9N)@f#l?K_K)Mee z)7)J5K)sL_*{fRo!b2^jqk7(wb;Ojuj+>cVoX{~OXoT)YZ;AqNJ+gVtzwid@6!Dfu zNZIsQ2b}sX{8l>Sbw8RDc(nU*lb^&mUITZ?I$yTom*xwP6U8a-lN)Vi10A>o&c+ioO;3vcZxCm?kuEsT@QDb2TM znL!&1Oyj#!1ZnL`e_=h!&3$@4(I#j5PutF-DWbKhEA>@gewSX|8uKAX_8z z9B?!EmDn87>j}k58NjI1bDNE^Kz5MY76c=A!%`>5%$ta8XI*ia>6T_S%mig!{OHa6W@Y1>&Z{;+yxg@n-4?G|lwEB0!&f#du zM3i62{Yg8Cj|kt5#Q9d@v+Kr^W$UaX!_t4eZtLRVq;V$k7l`MtaJ9X1#KYVe8~w}T zA%h!#o~{W`A{|%P`CR`_Y(pk4Nv@HeTLD01Gdx)Q6p;vP3~8@(PSKhIF|1tdp=CP4 z#Ty-cj6?VX9n~NAiD=3h`F5xl#|gH;I!;-NsFS%E@#&;kNm{9&P8!@J;D z!`*W0L7d2F+MvTl&tsq#&agL?VaTPAbsh%L%I}*e8yq5}D$WLV7?A{b!7YQ6Zp)Vh zrqEcRHcSp^KUi$^V@1hKS9>mZ3ME0=@Rt*nxjRrU0R~gPA}6T~iZ(`ENKqDMX0T)P z0^U4%2D>&bVQFp_$IhO|*2Q^z{?Tuu;t!c|j@3KBSE$Mo^SiFZ;LJ&khHKbz>)ohM zyo2|?@fVoC`8I65^)5JH!M}Y7r@#JX4A$3MMpiiksgA^#@oT#xZ{4z?!Fe7U5H_7Bi59~g?V6cGy3BZDpz1`eFdv0j^=q6@QHbu z;2X(KN~?!MRaNL8IS9W}KmA{h#~3ee!Q3_bqPOMy{T?n}cQahChmo(J`ky&-94n`e z*54*bfGZ{jac~KqGrbZA4j;oGe!G3j-Z|hGKXpI0FU)}f{K!2w)+geO<--LngyzI|V4_THsc{PuyD01tfo$O(M$#Y5p*uPpGh58sJ0 z>=EM;^a~(8L#m?y=4X0%@~z|eY;hVLi8Gl5&+R+4Vdkf z_}qhchBs>f;5QzB9+w6~3`P|`|IOzjar)7FZpIBeHlbepc(hx6lz=Y*@3C`n7JIjC z4t<8>3V-_Yn+S_0KW^=h4~`;6j2HdV2l7_|t~n|>DGP^v+qYo<4*J`^xjycc^Ub(n z#}@3_+-!3c1!-t`WxlB)ev|?#6`)_geKW4w-0JnpV2I-vSK6oMLQ#4uN5>U@9<5%Q5C&raX|b4PGf(ov1&+dLfoKv=nxWaWdk>A zOGZlenRY;Uo!yLIIZl=KG-lVLDVi%bLi#3s$6u5H<#9ng=cF}Ma#rXiR%+WNIvUa5 z;SXe<&14Cbj1iy4B5#h?aHQkBZACjE(cg?;G!J(8vhGvK-pO*~gY|?v11;ZyC>brX zQi<#-yD0W4h?-u@W&Ysl=Du&~4szJ=Cir0SF`9Ozzg_wtk?qsplltWPM$LRX*Fsk% zI)+wGghnX3gRfCO-9hs4>XEj@NIoUtI*=wzt%axEXlfF z)2lC&>`5EeDY%+mKZ1E<9&B{IDR!F?o)K%)b{$rZDVvlKQ(c2GdkRpRTHpda(=p&_4`eO|c?7qNl z&cEQzV%(EO#1fY%RpY9D%5cZfaIq0R3+EW$NH9O5@_Kg zrl@CsC$PkaXcJ4N*D|#WG2b|1kTKJYoQATdU8H2JIOLor7MC^?7~Z4(kP%v83SVxX z0(@pjlTRIU9{TXU*PI;J3%oSb*bWfJXGE;Q)wKyeDuV6QxmOL6p}m2EL0i|&js!Q0 z(NxFA#^f2WG(U@7o0stC&%K80uiS}CYwOs(Z8JXq=;L_z%mqXr64XNBfpTF9vzxYI z`NacRyz_%7dOe)|`kw)dbJ+Ue!*KmR*57^uXCM1>4A<7Fub&D(J?EA87#?~V*t!dT z-_7uYH563^4A$Vw62o0rqq=erM%5TItIP0bPGb1hLAYb@z-R8pR%O55Gt&d!Icy&d zaBi?lI1rA^g2Z_soiAP}TBRs3x_A~i`X&Z9-hr~JZ;q^9a|0HR9K`an}fvAHL@%EX>qzA>4V*75I^RZpLqX z<9PrcTjpo+3!l6%nx@}>`c)iw^B5NAa!<``rDCP2@%q_^?~Xnc{726n#H+{80073` zNB|Onk(>gAH6%&{WstJ0G@yM z6n^u`m(oBWB8g=e#M{^yeCnp_@E~nv^v3CP_?@R-4!{58#W(QcvD3Jt*+Oae=0*Iy z2R?vb`O|Nt;F|NDi}P5T?FSgAF0J6`g^Lv6XqzDQKx7-NJ%}gR{H^n|`0bzhI~Y~Q zjUFlv4o|&v0^j@Vzt>c_m|sQ|t8ZkVlr7BhEa{gi5~z8VkhA((bVNMTbw=PEaFX`yW2LPlxmJCoV*uHKlgK2! zsSzWa3lzG1wxYu$eDkyI<74oNPFUkrXcN0Y^pV>DmhD#aFHtx4y^^>yUUjzSHsD#+ zptw)^L_W;x8MN}c-S{$BLNZ%L6L+=f)Yh05^1d! zMV2Tn8Gv5O%U3KrwH{E^uoYQCPo}TX7fYke~NKUkdBE!^8 z<(dZF{>m#|JYVUD8mzL7VE%i9e}*%3FEC6j!ewkc=?#1#I8}6v_20$8tuRuCiq=v_ ziS3ZkLUuL zB|BK3GG4KpNNrMHn_w4m;n5p=yp+uYlnu@KL>nK_sL-#-cP$M~rrG*77KpKIlV8XS z46$)?m}M}4ot z@}hwBO!3$aqI?{=K5s>oC&i51)y46f8_oJ z`j9-rSjOgWEnAo?6@(R+Hi=HI8s_RJ7X|rq)*uJr*A|hJo*k#D_B65pmCL z*mBBW#~jitJUu^LgU|IRCAPhxd=XHqqGAdIOW9kPm_?F}Th3LUyz;T0RR!b84dXb@ z)Fv$tA3#h1rWG!EMP<%z&SG^$;UKgt* z%?}kYMywVK;4>cszHlF~SavJ?=NpI!2+Li}cDq%PaceIY*W3iW`9H6{IeCnL%(Awd#OJ@{k6mRqtAa;k^R@c{Z8!P=(bq;fjeJ?H(Yl` z&Of!Yi(mS)`_epD9B7s^^va-DTy#FZ|ISzD+_Sq&{OZT=N6d~o;$vTV8lU`HzeUde ztquI>8*fE#R|(-MDMqwy#6NidpW`nceQB+xU%pzohJ&Te#%B zy|{RP{qNBJJ-Bdh`eH<_=0Mf{?cJE;wkr2O8F^?;dBowSErr_qp;2F`zvs~0Lq=f7_j*Y z7E1aBNA{;o2X6!5pg!1cITLJtn{tX4j%5fZiK!GVw9+o)-R4L6%5tf6yyl=O#T5YB zYAOnj$;rzq8rvQ2%}R{pR=uV;ct z?7jrh%tIb;%9bH5_eJRORJ`G5=;OEimuyCi=(l_t`;vofpqE&8v+Se>)#2k3hd6d& zY!botPpxff|K(1s0h-@(m9Zt`1(b4X^J~8W;zw#@YYw%2T>x^Qg=Dv)Q`g!a(Y>)r zwjvGKZ8#*=J7ha83ZJoKS3VG{7*poVn=LQx{sjw z72!oR{Ved=$IhVUAwmO$jbtto4EYiQpcsH*rmN_^JEsKVRqDUYcLtJ@H%10}`Hakm zWDAQr=!C%Ss8Wxt2+#%6bAvT{(- zXuD!a>|ia>e(7G|=|>T+x*qZJYp`+PAa?h32cgbaOSG#cX1m?zk&t~0M*sjI07*na zRNI$c1>AihHtzW-7SDfO%kOHboIz-2Miw;9TAyS8M!Q6`dJSf~ z-Rl1ruDB6fk3Rxja0ynIUWLu&0tnsKNAt%Y#+jA#2_)m}>bjwa@N8p?U-v7!Pno6_ulhG{LHuAscO9c{;%NPC!QUqG4~_kK(_BE-h4Z*I(Q%#|KLN9 z;nOtH4*+KuOZ@65AH>^UbxnTumtTJie&J8=!(%TU(=@Mg+@`(^y? z?|40~PCR(!B^ToRZ@Uq{_7`8!a+ctq*;!zBwF1!f&)$tW_HAt7=-HhS+t|an^t^re z)4%m2xa>f;HP7dtc>&-1E5C=+yGvx-ypC;m($;+D2a1(++ZBiKslWXrZr+}anc6x@ z(uW^?8o%|xSM`rHpQuWaa*VE^*A0@kx9XdIbkN5Y6F5V$N#O;oi(sKug=f z2`yGm;Pnre<5}r3^Gm6;!If=q8~d-oHaE~O zMof09m>5m6;vF*Ywe8U>^vIVFN~cLa*^ay8Tur`uuI!m3&js&mcn>(^DKVeG5ZUJj zY<)XP>cxw-e#t(9-uq z#T@R}zawzgNwvB%KLb?!l=SJ$^f}3y=$Z^OWIWe3z>W34l|G3LmU>jb7Ngqx!NEo> z?<3I7QKrR-)<)&}>n5S)9I6hci2yxW<2ZDx3~_8TlIHzhV5mD%>F8`Tq(hQnW@91Q z9mWGlf&@kevg~QuK*`lsCc|V?b|i9WsPz)*bNJjY<3A!iwSk&v9ES#$L-5@|DL-%& z-U&3kChfBfSDc|!o=JiE3{=GuWF#_7x1fVl&EbLQugHfJY211JRrtp7lQ^(<3kUXY z;Uf=z1z&jL8Je*02$j2t`FZDIarzj}zvf09yXT__7hZ}BZ@&xi%qg7y|`)Kk??d@687m-*MF?_~-xmJMfdg{)brBK9?I1 zO91$ZyKcjITm4o@zjOb?`0_W7XeZUSc4AN??7)6}{lqC!Z9y(*n-c>N8Z>Bd(Z0R;JcomOw-7j(O~tLe zpWNBS&wuz{JabIiN)0;p{KYfd{d4|gUS!SiwFv?HHs_d{KJf69_?h>87-tqs6Hq6d zWLt;e;5a3@!4h|brUsQD)a!wTix(SE$?mu5rA!n0iCs-lU$&STGV&+)lXTEYY5)%nqd<%Od)oRZqyumP7ykp zvW&=I3q`X>TWufTb_*@O3~nZuKl2r)aBJ%(Zm+A`rqV>e%OAs zIJ;vG7=5JbqPJmyR*z<@-!+~Gq)7?s7nXHvGcA7BHp7<#JMkq2tjsaoqG@Y5MRv*W z6q6K$qr%_tZE!Lwf$&}cSi0SbR}Ut&J5_GS;9DDP?=znAXXHZ)WVtiERQefvoaI1Y z)jsu=I*8rCE@*dTyq3l$=?dR(=;P3$bG%F?eP_%CtrFFBU@bO)En-uh190XI&P)8v8VqY7@LeDU&3= zts>(YC-giErhl{ijo@%D6UbgtA|*d)t86J_d05krseH3r9!j!udaje@=bAj>tKrbfi1gQ!vFMziOCgVkc5@s$_VFXYQ(whuz5!fz6;`jh4YP|b16B(( zi(Q;Pa0q)Yz8rYw$&Aj<_BOD67VVxrh^uZJp$o3K8r#Q@`UWzyl!KAbKOYd|p|pGK zCE(d7u(Q6>TFNz)I@xE-{&5|ZC4z^|L{F;&Ch=H zjjzT7ho8qk`_R1=eGC+!>YQs19>5R1?q>DuTd%tk|M9Q?kVOJOz{UIbs;6(d{z|;< zrfcwlFMkdFr@~#?Z=5`f7f+wTRq0EG{hJ$j@{uiT8f?VLW;CWZka8KCkJ{xuwq?{s#W}pMMU&^Z7@y%Ug3P_+lpsk8{z zBj`2+2mYOn0!)E)Z_R6rP>0|F==O~#|5+R4D*m$1;Nn4Nb6>I_^#-}pz75zTl36zO z*40akw>?y`nB*d+t1{MZI|AU*n)6bXNE7C63T3}oIRN@?EqF!0au%kZWXV87@T^TZ zD)eKA_iEJ-B4;!0Q#0NX-Ks%qm-!qy!|*ku&u^HZ%c?=K!JFk&?U`+qHtPhpZG2ia zZY6X)BzSV32NJpyy8drwX#ys8*CDYMSg=fbqT%Ygdyts^? zmG??p7M~i9*+|QaI%BUg-GslLfXr~EjPQrY8b)@8#*`LE)kl_Q@?-0|6mOD=+nyqy zwyc%;jF|N`+#Y&9Ixb0pP<}RLv=P|a=)RyAo?xZx<~|Lb?QiMpw<_NpdG%eL)Vm&DI=8+32+D{!`Y*f=(ulC>Q+&fxx2E|6?K^NDSc z{c=p;OTQwft-tu|_%uFfX5B&KZCm25@Tf4tvu9o$IQDEP316};a%`&7mx{ftrLlRc zQ5ZrO{f>fbMW?;?$J(pqdA7;(pB`U^p1<5Q1%?|(2Vl-|!61NhZ-30!WV;)X&$0A; zel9OxYD!-w-;=)zmVym!yU060$O|G__zh~0lyS_S7JipxE1v}xa?w7f?3++LnxaG0 z^mv|A$i_YP{#??S9u3iD{WkNcfLA^$mn0Sjx{{{`6e({gXjE-jW8)EM>eHg462Te_ zlm;CrR}0BKzm=StR4|PG6Gr1VtN7(IYY4A``%O&TFA`|vz4l1Zq}`$~Y(H?Yl?;tI zd$k&_axaF58;tN}iwy7u=k3F-*IthQaL*U;rkk(FKlpclfMci5l=Xsbue)sQ-485R z*mv30IC|eFvG=Ciu;-c^vHj3zaqNLlm-ILp_J3Ch!MLRo0vWK7^TP{C@@45X({Q9TUzWH9@F^FED|3Cf7J$UWam*EFq+n+!1-+%X8 zaPJe(;_PDS*UNoR@`-?Vzy39O8y`t`UVRzvym}g4^QOVizU8&};KN@tM?*&Ju3CKT ztB3L0t1it?fAX$d@f-Jk5oecX<&O=d)pHHEv+MHpm&ldgRw^K1?}n@}vMVujp)%Qt zM5kY#I(icS`s4Rwv1$=QKnvi)JzMyDZ~qn?pf4!Caq297^Ztj?dJS2-EN$k2CEMng z8H{ks3-rmq<=^R#Cod##5)M*ECTJy&5T7ioQPSs~-lzXj_Gbpvp|+|&Dt%MnXJQ03 zkeBD77a_qZdXt0B{^_}ywrsmnw7@OXX70U-zd`=9pXT@}=q%NCM8CaDqx;OmHTRd1 z5q01lqhoLmULpAzJKwr$JKdgbb_aOMq!0q^%f(!occPMs5SL%#gFW9uU%UpA-#lr? z2W2uHvBRnOyjc2=(B;6tY4n1a%p-$V))VO~wt2!gBpe7x2;J9;F-@@8K9ZQv#sYvN z^Ryqg!qw3$wE{5ca%^*yj5@y1lbxvp!m+_M(`j{Y$lgi}SKwe2OihrHZD3L@zpcF( zjDeyqlVdi==+tb>)Of?I)#x7*n6E>swiFvfKxa zYi@&SVwrbf%GDd++Wwe=^NTW*<3uIvf~S1( zMYdD$GGbA*$4P9o^`)5~j;~hr4P8~6Q)7xPX5e^ni>ohUn^On4qGRI}u_dP8qp9zi zUUi?^=0jw?i9jby?dlL5q;nsnNlO5EVltq_-zKkL1+EuwOtBaItk5+f2L0~|Zpei_ z_I%w*Pl1!ef~+)farW$b%~rdyn}g>RoNM-NO8RDwe{ACU!=|CR9FwnpS8yLg(aKRZ zIYEN!D+M2!_?L$fIUdZe&)852??Cx3D%Q5gG8Xgn#nrKlba%~r@&{k$7}p%T8+h5r zi=AA&*1FQmvHdTH(~Ys z*YVuPKF}S?oB1nnNVBbR4515DmJ49_46u8u`!YZUXcT}RxB%S&XUiVG6A-O-w}EG$ z?)LFdd_*L7g<;8qyBk)Tf`3z3)EZma6_qj)K z-;>YvIE)4IR=p$ewwtfTTW`9?tF%`7>APQxJu^B8DvKD)UWrowyL)hUcY(k4n;*iL zo_R56owv1#Uwrp>;+D%U8b>6-xoGbee)3yyTb~es!A}y7(dTI){V~%V<;JrQp@XU!*_+LNzS^TSyKY)Mv zvHS50AA11*XRQ5x{7X;M>01AXns6 z(HV6<_d_sz%eY5fh9762Rwt|XlLG?@<&&rZKA8skJ= z$GRucvsQIT#pV|kds{G?qWp^B&8JQX!5yy9DwD}Y4g1ajG;KAm;iO~5GvL2zR||o=TNC0Xn|2aSq+I$*1KrJSi{xLy_MI z{|h1E7cF8LGh<%ASiT4JQ+h4Y5l7CGl4SX6c?cjcCPVb`7?Km!7Rv$q9!sZ3KmS#1 zilqTCKE@j(c$Eg8MW7jci()GlMotU|3%Lm7IVe~yv7@o@geg-%+YYmaV`$R6_FTa; zWdT$_dzNxTaBbTKF6d!<24XZ=sH0ZoOEA+mW!_pTm_L(c0~SS3$}ecu1CBS}d_A5$ zavZZ+gP(uj2jM$kGe|))b|GSG{{d`Wa0n;A`VjWN>Q-#*-;WnQ^z%Y4*@&R zJp(-d40h7weY0Akz2P;$YhI6r_v+R+J&gx10q%Y$aM#Qoe`3CU(GuVFVc{7mn^kE>tsL6TmqfQt8;<2ye{r5jo6zf*~e+F?ZfRty} zhQx?j2>9u@z7`v_jnL6E+j#c)snNgZPn=d;*1Y+KtMIm0T}y3Di5mQL_}EGOjraZu zj-A=g&u+cqVtn5nH~AIVzNGtizUF$|N?RG7T`VWj_3ZIeIJ4WoY}voLfuDY}{xU+^ z`oz}`2g*;UEg9I>wvNuWCeRB={ExaXLIfJw29Eod{9?1<@bm3kCZ!o31R2w!6mSlA#v?MIH1y#k6M~;7HZBpL8&aE?Qg-@0m|S zfoeXej8lL*IIft)Uvz$SwEz~oz%so!XPFHvbmu>j3}qSlntQ80wJJ39FAa$?Tf9+6aIndl#!dffN_Yd z@n`B{8#Vdk$n})L+gP#-aB5|0_QgvaGmOO)0E!jQOt+oH@@TEut}Ge}MjO-DFofGw ze%0#O2{F%Z)^se_8Nj0rJsmN@%oBN_>%=~?eCIJ+=4S=ZQFxBLb01l;&w6e$Mi<6l znAWk0hMN9W7u=!e3CmNSkRrax)^Mu5^skM;jLt=ij0-nFbmTG()P%9}Q;cN#qj5m5 zH|XnUxB-Q(dJ{#NPJSMsURW?4>LoejFwnOa2BPzf%ZF}^uC~xk&XCOJml)EX zQ{11NFtBRbjy>V$3TJM^$Y_kidR|NG`0Uz?_!+X|Ctf(x z!^xAVN$Y~t(TWx~H?g%f$C2a5aM@kofs<%4+s_ib0D=d+MeY zi|sOf(mzMM>{{%;?k#9G_h9kr*8!JYf!SBSh}Cn4(+dI(dUe$+fGb}CtQLqNV54o( zoIa}iHvqePsfga z{HurY_kZ`#@PGUl??SWAi$-+Y7X8(?+^*RD-~Qf5@ozuZ6yuyv)+lk7s>TF&l{`e`6|z}Q zjV{8#wf(4UAh#)Yfb?5!^Olv_k(1El8{p*Y>iN8aJcfm#k@cE!W8O%g2J*RCu%Y)A zPtQcXg?QQf-`bL)1!zoD{{W~enZbF`UrC?4jz`}|`;734i67a9$+LkvUhLudGYEd{ z(;eF|L^n^;+B&0gk4YX+E&gLZdCXR=JI`iyu7-Da)5SLYA}u;Ns=8v=C-{~+5cG0n z12Tfoc(kId&|)rj3UUp)jQq$jt$swp#XQdU4t(Xm0{VlJLyxEUg#1M+%60~2ESf8b zDDn?>3|0+m*mhgE1ai#X*WfGE*d`0FDiv*i4yDWzP3U|*D2y%r&Q*ivFVJhMjQzjL>z}J(TYH&yB zveRW45xv3&D#Id_1z7k`_tnpcC}3gZ1FFljFTqZ_rHQx*Ty)+(yzYjp@rf@zhWFp| z1!7UG)85D)f&sGtY+iOXP9J^}`>%T?n$-eF?)h`H-lx^sIGH>)t^s;4S3bNV0%%v* z*l4hL&9`87{)NEllO3c(mm$3AQZ&bp07qWH?8Ff)cedrlNss^lAOJ~3K~xd8_Mkm< zIhxC_#%wl6+pd852HImU;`DQei7qkP!1Bn8z?bg9^7Y@2`E1?=%*$OYuDBNQ&=qKo zzX+T>4lH*O!VJy6eOMek1e|vPuv{W6cQKpKvAXzD9JuHr9DVkT?mpjY7O4fWdHAc? zz48WZ?AwR!W(GX-73>^+-jp1Gr-JM$t#aRVJiqs`XYu~~AHk2ksoTcpmUxX6nE$1pN4$Zo>t8`!6>B!vl}v!Ka>2F*(};!Kr@(el`aDn~&X(cinbl{&L_i z-F74Hxav|o@bou`l&Y7~a^?h5zxt`q;|f z-S;rgE*2P`Z0=zF?gL-J-+jj$am!_g005UB*oSw&{?+)OKYUMLF3Ih~&mX~Gd(Q{( zTYvQjaQ>ctPyGM#TW`Y;z3yh*^Tadw!ZR=6>&H)F|K=vHz3>2TzVsrz?wZT6cS9dx zvuYz&vRb4`gA28SxJwu8-NL_p_d9WFXE))DQFr*OfAIzU!9$M`on-G+qCkmlDuA!O za2$W{{U66~{Mb7&OOs_c9=ZVk{QJHQKlbncxIdY|2D?S@YHuibRzZX6UsuqVPsG0i%l|tm)xjHNm(H;&upw9S+T=IR&%S&)P6+&5{J0@b%Nk=9Kw7lcpS=nn}!DL)x>^W zV6aZ{HW{Qhxz8w`;(ioc!2K=Ho6zwp?xI%|^xMj0J*N08uf4GP>DUiGyFmEi4dl7b z)HuBGjp?52+q1rg+8wfiQ=bpw8+AK{j2U`d{mTXE3SEce&~k9rS7|LwK*ij73n#le z4`qK=^?*=Rbfw>Ri$mrW`_@qU@X=J`-x$6;cIES03LH_77iyDd-1mI`MLvIv{gKGC zwB_`>9anneOwWedezTK%L%P85InH9*a%zze78e@kO@9!rl(lQCtZ3))B<)%pLO;2b z+h#jXcn9aXYB05<>?)up!CaoCf0_P-YXpjMbEJD4uem9v5TfbMx3M;i^(c_} zvKwj)+ODJsk$8}|$K(1|H!MF1pFs3xJ+ohx3WJ1q8=Y>fmbz>RgpZN=8eP&i_T_)g zH&~ru|1WTu=G?bjE;kH4FC~Gg#JmEpVxv5Jm37A%1CFKuH8*2nGz~`WfyHA=nu43> zAE&fYvu#7=Ykc+QG;F( zmtlv3#W0lJl03O-$XB-T@GKAfotiwy7o6uh(?vohZ(!>>*<8W79Z|Hg!CLJ=;B|~@ zE+bB!lo?2q5s_9-SKxX4tQsk&yodLgBN24sz;D%+Qw{!*F&vW(V~j+(0rZmwz}>ID z4gm0PKKKcoI4g(z4&fL23Bd@2&|tp*JZ!)84P12R8}Z_2K7lhwUhK+w`fdk)#R>+N zd!M0;1xF1ncLf{U=c=u*TKEJTE^`Q>h&_+Kq|fiK;U)lM3; z2mLif3;}rRF*Gq?`P#dH{RhzO?x0!hA~pfI_zJX_UX?LhA!1{>M7z6#7y?$Cdw`QC zap0kQas1iC1H3eRO+4-Q=!{q%I|>~BDi+t@0_^Ny&y$Z}yOrRsu#V%+npFpfjwJz?>%3_XPVcKqDaAMR;gN9W80S{u6+`?p?k2zTE& zc1mw2Zy^9bbN3zUVC3KW?3eM4Q>P3~b^G9hEMKJyU%$@hL+e*6=6-HKoNF0U!ACJ^-RY=0Lte*a0l5{ z_U>drq6gvohH9zhSNKrnk!N_p~`sY)V1h1Zpb44sbpB3Zy zM2=&o#3>9%CeAY42&`7kwTQ{!kk7A+<6#ui$G1Mo9Li zA)!-r8(&LiJSSM++9~jMY@3?Dh?*X5ldnuW09IYi zf2Uu)v4f5Ef}xG$ks*F5x&VLcDz?w*Iu`fA$>+AzSz%UZg7eIw-HUZRzdd#Ss`lLT zv6g;sK|#$oTi9dmayg*m$;`2}gL85~=BZ88y_4`P_UlIpw^-ojIX2GYTd_YwzSPPn zG##P?kqf}|M`8Ge(*)O52ermxfubEEtk}^clyz+T*;aF2vgv?t_iC_eV@UNv)|6#i z3!r})9r?iDO3<)QvI^=`;3scVx@K^rVV)IWag1_r1<=Bi-?hP}7?X413kNKW3io5B zPcUe?Wt41Js$<0c_OuA`O~NN@YjHke-JqQ zc$(DTi>7H1S4%XD9n5xj&@8%_0suN3ni=NLJ_UUGPjK?-uXX#0#DB!@OS0D4^od8G#%CUXrtE}T_e9|I zVu4@##DnVb55M6STz}{ST^~R&0#)^mxxc#mV`sMUH{SC>96oxoC>pZO6^9gY>y?M_ zu3N9qWlrtv;x|A0kisRmGm!rMyoOoTBM_rlW?l&9@T+Lo|#{RB-*;SfJ21ix2ZQ zYP%fhKJOli52(uz<1&TUnIB9~lKpnbe|WwD zy1ejHuGa2aekeJi8`T821yuWjVOqT$>c=6zdb(Zkm*aqx=1n(|mQ9MaD>gX~!wf2J z$Z^6H8#y5})8Y7Kw~c{zt*MECIuzFZlUPamOX^0aZ;Worxgp%ocJggd4}_^wuI>Nw zA@Ag8EWDcDTOM$114Ad%mGz~85_gsz&n6as0+Qr$ioa%fOo*Im5hdT*o4%kW=)MP# zzi48g3Y2nIwS5ElvphxnTx_aoucb0Wy1mBu%uPeO$}+xgJ2l%sRJO)j`5i)ec7`is zMy9j>U>g`Jf6&)j{J?lgS#G!bVo2b7{N(yXbG9QEMdNqCbV?n0X-KqG$@YBRNK*a9 zm4rsIh2-XxHYd*$aBqMy6zIgLKY5y(6g`HY0lfi+Eob;J6p(p5D~y%J#erEk7W8Zz z>K3(sXQllDzag01C>#9LR$*VLkJA0-yuqH$4gB&SeN2~~nqrIQf(sEA3+%b#Y8?IC zr?J@CCe%16p}w?1Hyb$H2U!Lp)bZxA1(qw|i=PI*_C;)7e=~NkyaBTdE(SI?5NC6Q z*$lB=Vsp7d+&+W$*{9Gv_GPTjoInoroXK_1sf~`WM>>ESBA2ivZ@U1zK+~oziNx0+wgcj_7@iD`2s} z3`;Cqpv?z4k~1Y+x4l^6@TKd1VXX_em{jq<5q$S`gC!ZR=6=ic{W{O>>Z&h9YUly(9Aig{HGxM;QmnV)K$9wL32tRxGojLn2f6LAI&CfoB-IWPeQk{pMKY}0p zmEXm8zWN6I_+78TTW`1;mmb)My&Lm9slHgXIJ;Qlnd7JM(MO-cd+&P)AN$&2qpKRH z7y?di@8aanu2W!I+F@RW^e+G{TAbL~#XJRwr*;@I+~BA>zjFu^jWvlxtJUc??wwpEb=IZg~r?rGZx z2@v_fDOEl6yn(sKl-~%B!NHwq$}uICQ=?=#2n&hVCOC6b3pF7&=JOaguTH)vdy{z_ zl5W~9>m)gmW31&5;WrSsWl&nrsuMRuaB6X14POb4BgvBduKDN~(eD$zLY6c8^#I$v zjJtVJET6%ymfgO=vsu~-h-EjD3=s}WuVUYp#Wk3I8|(+N&!h2NCBKG)jTwWLEhoN0 zKtI7WgMR51eBH|JI`^!zZk$>18-s&eqD5_`Xj9@r7J*3eNBGD+RV&)GTNPQ}dU5&C zM5(3A?RUP8@Plc~d7*#Kgo)h`HXqbiN#B$l$@9?b-jvDJq2%&0bx@161(joydP3@O zhjfK?WORHxB(v#X=7sgM23_S}*|CMvzF0ghEDuJuqp_sb(lBKr&9i5crpyb}U;({+ z&1VyE5uK8I#)EMY+dYD-ikm`Fy!bLD+ec78qUUw)KgUK*@&mObjfu`tUuU@^nmEqr z5p?8dz!tlDL%ueTF(uR48nD)eZQsWGsvm_^#|9ywKO~j6@u;+8+pOU*CAo7j%2?|( z3AQ!DeBYF1*e49xhFCl-e-`Qz9CU1-Q@dXOSs!TUK8Dhi*p*?OtA2TYy4F_~C;75e z7C|{C#{pul0v80Jrjw}K;TZe*NfpnR;L16v8s5~ORMAdQ10y~#;V}k zAV~(V*3rp;F6XgQhF*ZzQEn#KHM-P(7BVZ@9F$pFQobEHvQcPTtz0!jW(|=tN>K}d znz&5)R=`y!lA*V_j2S={h~V&oX{z;$XDo92>9^Xx2-M#O3G3u*4dm{W{Uaj~W!n)t zkz`p%>^nJg9<#Is^EwW6s2#rje z_rgf^6-Wk{9RfTZ1lR_It-Zj3^APv!N0@D*S+20!-bS;1x}Qr9<|+dJ=w=-F*03I&ao0oT6G4P1G_dHv%M@Wcy8v8vhl+(+Fk z&i>5}TzAp=xcvO{aB%My7ONFrJbf0=o;ZVNPn_yrfG8VobS$N&3ApBh1KrsQ-at*+ z#hzb1>;^BMI*nu7bP#uHYu*6YTzCMpwEy|ea*4yoPIfYx_w*FF+HYNb@I3W0rU?O0 z9XpW@Bj)at{;73>#!1OSp1d=1F`$RtUcE7mMQFmgl&^(l@0|uZ|r& z%QHlDdlFMUC8x$8s8~o2Y-HSGvXSXL2ibNYFkJNh&Bky%Xi<8Q-0IV6{MAiOBn=h8B8p0qIwv zY9gydvrHzi5y&w~&_2>jmNzv%S^ls+&o~CCeQ~9n7h_M=TaVY?)vLpJddbG?wK~?0 z^Ef0hjxYsnVqYP!0B!TaFbKxM^RYuZ#cgKVs9#v`B@gIhUfFty^Q=AOHhFvnAn(Vk z^o3=$KeK7LKLlquJ{D!axOE5QP<#&zFAIB`GpVe>t7cDzC=Dcn% z8C7|U7XY=_d_>m=?V@}cSmW22E^_?qoPk1%LZ1#@qU=JozsNvI}gI>p-y? zzp$9kyRR$+c5Ojp&3@MWkLzoPlIgp_c0uJ*9FS#o)xE@zEf7|{4XW7`p2wM*m`45` zLcb#3l?kOxD2UCA83M)3)K|GJXJS;!h&A~dnpQpn$zi(yM_Bq$9`GH#eAZcrZ^oaV$)8(PKVaTqJ#dHO3snb;Kt*VZ99GoLc9jYVb)I~+VqN9g_ zc+GZvfX*6!q`ZoE5<-y>tHA9h{|iba*Agl#*9f7kEJk<|cmVw>4z6EIRsk88JaFpi z>OLuv2?8>#Jn>U?_z5R>4^d+jJO?~V5gkRIlu{hs}rKTV(C%z8+V`e%tW_uN(>z786B;kWdGg>TBKd%8+{O)!JUX!;~LJaH2Dw|b6V zH&|C$PY{y*T9tOK=7fqM1)3ki$70}X?F03hR4*nfjlJYx)b?}DPD=ao%(Jb6>(l|< zShDR69iCOgspf8c_wnJ4WLsjUX`o>UROgt{pz;1A>#I64f^JQX}hk*4a0ZOa?C)bgjm z_3{OGZydlb$1}&-e#lETfoUt{&HqsXZRsa{!OCBOiOdY~vEYl-_sTS|ZE*H_2BuB^ z1Ae^0Wjz^ZUm&Y*tZ$e?D~qDC2cjdXfTy>UVxm-^;bN#>#TZSQoES~gr?IDRYYuG8 zefWxx!Yj#x`5loDclTnCn$Mb|ixR8k@dSd zJ&$p0+gTSZza1Hrl;;l2OS2xK9#*z775-!&%ah(w=K};UZ9UYkdK)&z(g?f%WV&it1Nux56ET=AZ=ssNI#gL%KsJ>9N1odEVDDX zfZS<(enZVCOtDwBcxS|Z(^AAp%mZMJMkcI=5Gxo{TZ6SmQbCjXiedFf%aJ@8J_G{P35wqj{sIc zyWRaQ&vaKTq4rOf!8*Trv}XcDIP8j*zqYSm^li$|`yH};lhd;OXkoB}8{%0W09K5y zvS-BS%x(+ckwt3?JzdOlU8(DVw!F5Y?F~pRuqgN9z)V9mU1tQu>B(=a$1x;v3Q*gs z$VyOEmS9*ud4p=EZ;FGPn%qH(tUvG=-@RLtV=i*2e6bYbTXN@v;jJwwFH)nZri;T`8fU}EAyM{5>IMDyPfb6k`)UoaiwP)JvsL3 zkNVM+T0^7k`7c{5h(9XaYsJ45y21FS{)$1J1EeO?1dp}?zedxTT;>TQ2W|~sO~-8+ z*LDmf_KQPt{1hC#^1+tR4V!0HFQq-v5yqLT2UADDcs8$2o}1VYW}2vN9viUFv3kY> zU)Il>o>~7tHtw?H(aHeZO;x|QmEml6hG-kIGq%HW+|KZ9p9o!j zc20J_!^RmraXhFy(7ds<3GGaRjF)Ms+WTn-Ste8Ds7Wsz*U_bQlTj3PTKf%LGoIeyBTRO&UQjI=E zYsCg|vR~~N^EdWy;Q0`qUVjxa5H*pJGBP5M>kSbMON#@$n424s|7y0-4#;kA2L1?Ol_P`P1 z+z(doxPQFnl);dz2?D%2wZ9r{n^XX20wcji{GK=YUK3<*5{-jiiyJ#i8;r11TeqvM z&#F1(qMwYybGaIT!eM&IG(eQ#UlMvYnoWT>_NkCiSVbnTr2YsINnd-1r(^f}0uM(`N029VG#VoI-JUVt)>2>S$ zg%_l>`aVwxqysYZOQjNZ*BK2>I94a!2cB78d;Mt1<9p8rSNoRvof02}H8t3bK!ss` z`%LFKICj%8bl{fcP+sl`Zu}BcU4_3KE_k|W@Ui!5AOhVtcHlb7S4aMWu>tGoudO#_ zAW_X9kiVgRRlYm;@N*wJ@{)0PXc?oSW`~AkugJ5%X%aDdgT)-*9`sV*{#+s z8#@bLgE6oo!oAG{qU_@-v&Iu1=yExxZ{66O6A#*^@P0~La_`vz@A(wF==xj7m*@Mm zm0UD^sA!=ZHPGhOlz=|8n{+;(CE=hjWssqKhs{fWL-F?z+$px*D>r3=-y2g}In4Lb zjG3a2D{^xZzsn)zsIV|lybG@M$#Olw+tlZkG8b2F6f+-UM z`WKZk*(t{sd$bLuT+Y}R*UvafmGf}BH2nYoAOJ~3K~&=LP|`f+7bFfB_%e>M?Rsrx zRDyqHoO7JQfE~NUvf=3`!_>etNS!aRqOP9{(`^hun0H^lOTkFxc>Fxo78LwWzCIX* zVp$ZQrNZFY+rXi=?OacO;TllB8FBPf{brt3^jG2T^}n%CwWfyBn0i?|VeM>9KZbm{ z7f18G9UscI=4(A05kmLEl4B+r8%I8yf&S!+I6kyHzxa|^)U%hK?}@p|Uasl6ly76V zfJLq2GJFou@C#X>Z7>Z<{j)$<{sYR2_BYF{)1Nh+sXhlSQUvs3ToZr5xdKTS=`YA1 z=vv{28iR}}iIG3R*irK}0N~G;@JiA^-_9Ve})&Q_|f}niDxKY4$k_zh6v+Mxr zw_I!XGCPO?W0Tu4Womw1RGCsB+7;i^uxp$v^UoL3{YDo2z~9U z+pBlA)4dF67pbB2G9(8D^$6|9-y$`v|+VU4up zx4N8WqK2b*8U215(sdg^$o-U+yagO?o35^Wa6rWEk2p)7>~U>cBwV85F(^ObbGp`A%B1hR%P|?&`Ot~!6oCQ>{TTINI~QccRE z=fBne%${UNl@B$ry#a}C*h6px=WNKw{f}zO*am@H8w}>>wSHmSA$%ZyDcT(xg0xRE znS*<;AGv=h#>lq7Dj{$4XnB!V%PkkcDt#3bL-L;(=`)`tRk^Z#R7-3#hw?qYG$!}f zC+Fv~eG`!Ff1b>>a_{JWAxqpQ2I3#5Pim8AZuMCIJv2#>n(jq6=n1V1r=rJ0{d2B~ zVGpH(*C~FJ0c;bK&z5a|gvg{{{F%G-RS~N(b66gw9?J;JBi*}y(6)u?F6acZ{6X&1 zRoU7KZ)~dhsM>^twUM=YL*)vX328UZp?rxqyn(H)JLFCnPUe|yx00+66u7w>>nY&c zg;}FlZBLm?P_~TZQ)tQ037H7^j2KD9*gDZ=eMsQ^^h_qLbBsxOoNDqRd0x3ft}D+# ze980}`^k1ie5Pub+wkO4@{J6rzu5CmF6@HyR(?ag;CrL$$_ScRAJN-;; zb4hm0$=BNag+gjg-*5eu7sD|=ZS3OGw(a$N%(q%NOskL(02SzDdl8|wEVYQ&@B}b= z4p5doI6i>nlH)2@$Dr+v^*J6A;up9s9yRmsB)<@URP84uk&(-g)j~jSe zQ!@xd!Lyg=P3%k!G%PF*uDw9aGe&^X(Qi`c)do0IgMT)lHrTdG!0k+7nP=2pL2!cH ztc;bm0{wY;wmnb5th4e`kw*wcz~v2>&j!sRFvP%sX3t)nIs7C}A9=CN9yF!{V8t*g zIDzCbXxS0D&d-da&-BN>KAOHv+jf)ws~uo>2Uu=*D;e8#aB+~YBGRNxegn<4kYgE| zXe{KX!iZX+QOE}Iz|(`lB;{!pTHt4FyaW2T^`^RdMmB89WW&oD{AVyhKjWaU7F0z* zZHXbc@O@FI5+F<^LCK;Q40dEgF;ipGeR3FW8S7|$lWoaFj|B!kTi zrM;XmHW;GCz6h`|BdAXU3faql(0mZn!tHQ8D>zvGdH8!1D=m6k>it=|hj@_*%>+|> zweki}YabMC+)U_sYQOTbi%YppmzMI83aetQ6k_~`vy1A5jifSm>|_flTAco}?I=9S zXRM=Rp3fM3R%1xi`L@^)N|w&7!erxES29in*wS72MdmGU8z^6h@|VVh%f>9l)fUH* z__5}fvad}BAa}p95mWWm;^O8*!*F579v5L((cZ*yRiOjITl&lWWy-R>6MS0!?db#c z8&9Ga_!)a>!M;6y0NYU|7wr~a6Y zsFf{rV5+?_w%+O)OurAcJs6MiGXp#4nR2e)**xgKHkSAHg&Lxf=Za16lC?9|ciM5j z)uCBsz90a_g2X9*-eOh{XSHP|H(rzRu_Sa`JsMg(N%(kIRfdpNcEGU>Q)0<6JgPC3 zhgUuOWzF4qxOu;8c`TcD9#Ec(jraZreWQT^B$;h7hnGBHc91lfzDbOnnlfX!`LRKK zW$-WMM<>ry;*;bpe}*>&YA>gpM;@I;s1+StH}r=F}R6gi=yp9Q^uLiRl6V^W^wcX@@Xu5%Xv(a6{1~=N*7g@COG8Qa*X=pMv6JN2&5r7=%oM|nD$Vr|< zW!W*h#)m4!*nI^dhXLE<9U^UQM3G-XDd&;CvmNkAY>^hM2GXaX`%Lgq&X#$=NO_6n zPmo}qK@SF$F2ug5q?+AhJ5{rr#iU#;;W+3Gj-^G;6^x*H&o~w^qVDI6ztvlo3u!x| zn5g6dn@8tRAbU>1iqSDgB}&l{`AY4|p{Okg=hl~hi!b-}%L%q32kM?J9kUbg?J_^N zvgg@-FJBEPE87sYw*LZsb{cxrWsr2vtP02z=)vt=?Yl$(?BP*4@t(YdBVSz{xD8Cu zYp!E?xI{kOK1Sp%NHRaub|#n&@XhO^&|l?HyFA&OCbgQh7ygWFV;j1a)!8nu*oG&Rkj<9Z`9~B$VTulfR&;$G|uD1W4_D_6CZjotR6G(0vsJ} zpuVCTrSZJAKDj#m`SIgiVBNrJ==>4GR z643cUwEdWr?L&r3b~yyS%?;aX%L^6P2}~>Z!lMQVa{w!JFP+jtIAwpW%o{!lT<+t> z^f~vtH^(E-TZ*@=yjUI)nd`^&Mi4#wV{voAtf2=(N!i|-Kg$15;P2vM`hZDLx>18S zUc`+_IZtf88xOzCL?WtUjQnyg>9999kmE1-eVg^o_66G*TaS&z8nWmukSxYH^vwFq z+})0SWn0)reHby3)ahKT^tHzaYX{Ktr0P2+>PQ6o@q@sjmpGj4;nYAsZwnZ^G|@(I ze|UB|A<^Up1~uemrbq(qs zW*jNwF=p5c932`wbiK)pNVpEkp@ml{Ypv0-O6$~-s$^6mpbs+>8Y8w(ox;xPQzP)D z8tr|_`coT(DaThSC%D>)A*m{#e5qgt=vUlC=)uCO2h%QrrF;pnon$S22F^~%egamL zp`n3}$c=Z{kdi5qX={G+Y6}Ip#HGLu=y?|PZ)FUq?Wt+ZPI10+=q6Qz@Thr_@v8*p z7M`ldvL@v?@bsL&?VAyw!1S)jHn81NvNB*WtW0^fUL2$+KMcNb-a*TwTICbXm8&_y zV3BMYMyQs=9?$@R^}=h{_Pf<9ex~rHJgbix7K{ymRui_@MIcGK_HvSyd&Y}XZGy%T z<$|wnyOdY+>Gt>7M69*pJb{))SM0PMAR1ga*!LUrpRvE;L3ok8#$ouDgd;}e)pfPR z{t4&@C_ovMdciE~b|JG|hULzYX>XwD_OArxo}UxEBl1}Qt0k~vTS2(VM`to{Q>Ju+ zzD|`>`^C{Hk^2y?Ij^AWomL=40s~)`2{)F zNikCE$bk!2Y~C7!*}3q3jGm`8N7Hiois&JYVZ z*3DNV_Y!aL>QUBRzGi%x9&=yAf!nO{t>{;akfRe`iiC5FotU-({a3!SC0RNHpops@ z>1;$l7HIWfK9Ds+tq9LCoMA{XKLSd5^6W|gFrRBZ9~!q7@=~#x3KvgSz6r@|n|%uV z`K%DP3%F&$K$VQRO#0UbEofR0-S#z88+ko*C;g;OTjGNGr#zVKW3&ucfr&{Z+CgK?2#-^TEe z7gT}ni)RiV)nsHQAEa$`j$DUHPf#aM^#IkwB~n)t71kFNQpbI=9ErVRoZNrOC|5EIFmdr%%HX7@F9gf-777$oJ@<+4ibI9VOX&i_1-!fUmuw z8>*vtJ3I9$~{^9EjBdk)h-W zwyH|OnQ}sL;LoY=wwJQ=;fARV^`^Z-%b4DK14^4Lx^^IBNn)MyXz|+j+EjCP&Om93 z?X&f#CXRu|27T%o!|?29lHEW924!>@NGMt7k-65O(>6uHjSN`Ch86Ilk5hF*bOeuD z8j^{=QRiO#LgH_T09Kui%)VvCAh&uHj2GxLNaQLwd6mX%vNq&CGR}?x|L3tMYd$*jeW`!ghydDSfT>!lx z3o0CO8{+uG!(-5%IL{)r9YJ;!C|;!Jmwo7C(MAra$2e~kFOz&$$8ny#IQ`DQWo%h= zwV}g)34AWe+A8Za%{s>-4K3n3H-vgT_%A;TbfrHRy3jcO|=znaEP%15{hX_-Ej zwW^~ZLb*b#r|TYVdHkR7m2;LvHa(daIQ)eP&oQ$sdU$!ZD)Yn9sdV4;KUi5v65>!~ zR!KH^R)af+v1Z5EHfl_rUizeYp=!$qUuzgk#>4e}sQFxpG5!GHEUC<)B9@ncFhf^H`g01s|vQ81t9RvI1ZMv+7Q?2yg!)R&;Sf`d!8_grSg zw`ARSno(O@RB%vV9RT&dG;nO+DPQH_S(6Rh-k2`190-gM^e4h&u!6bD&1#9f>adp1 z)y8=?C>UJrOSlq9+0NA9btuo;@2P#E`oZEE9X?aGn=zD>LYpjEDJoYW59F(2%o%nI zgG%5z6o`skiY#)SK^u9@OF}+pZG zRGejBnsK@O5;OUL+`mG*#FYW1EL&J8aj~(JIy~LMNBm=q$S(?V#)z&@9e~%e2Pd_u z4SPRjtdpN51c`~Eg04r4`%xbty^u9*%rtzy>bWBJx{{UXC@ZM zxP9W}`CWbyD9tnOLw3vht)aguiRU30=bEiAY+}^?9f>H<{?u%3(Kf*@d=t&>STZvX zCRrQd*$Gtm#xZ;LIl?o_bLF}gAfb~%dHEAV_Z2ddJ@)LB*Y^bt4(^s_rh(B^rYH11 zKx};^o-29<-`XG1P|T_mjW%v8NHV%PmOLJMb3rv8Ssd3%JhxYy{0u|wf^-W0i{>2r zvC zXH6>l2U2igc{o{oi*|+_!$2Au)7bgk|G(4FoJu8DYlemGn}`q(rg)-ds`K|?PE8yL zj0FYUj_0^*&x#XfICy~r2Qj&+FuniAoGqc)J)=o}@NE+KHc}thKq3O|Hn4jJ z*ge}#YDCIA7k#s7ogmuMpbWR=^*Y|IQl@BUB;d6#fu;nGV|g{47%zK2gyT?qgE&@x zdlNU+i5^=pl+L}1Lxq9u#Sw^^eB!L%9AkXXbY#> z2e zWCwUWLBaKu?P49lKsl2vT%pPHIf`YrAM99%uGa1=c+$7g@Fx99j6JA3jtr`h-YLuN zSeeufq2InKB7Y?kycwrjiv8FrmnT>?`Dul}^c70}t2gC7D8?!yID0lZ$3n3?BV{)0 zY4WzV7?bZIJt*SSh(3l3JuaTEOi5GcC#twvo;bJ%M~6I}5jkgB^xAJ4$Lz(vUbbsw zcQQV$Ps>!l6zSg52~(yx2cSl}(VxsyAisERW(2_LvmxJDi|?jP>J>Ic{12f$>Vs@~ z{vkeuezvh-2>|*sKj~hMgP?6=#f&JLJl=6!|IL^ikTeC>SpP}>&=)pv=;z;Jv()bi zDa$v>Hjj&JL+a}llI0?W@^(xlC!sv%ha5mt?IwQ(X`2idZqWHP^hD2d|2cdaMyfA7 zHU^tAo~b2kFVuY7NSℑ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 YZmi~cC=cg%Oo?8FN2)Rf51+mH4>bI4r~m)} literal 250877 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 diff --git a/docs/en/user/repo/code.md b/docs/en/user/repo/code.md index b0037d563b..c297f06f44 100644 --- a/docs/en/user/repo/code.md +++ b/docs/en/user/repo/code.md @@ -32,9 +32,20 @@ You can expand the diffs gradually or completely by clicking on the blue bars. If commit links formatted like "namespace/name@commitId" are used in the changeset description they will be rendered to internal links. For example the text hitchhiker/HeartOfGold@1a2b3c4 will be transformed to a link directing to the commit 1a2b3c4 of the repository hitchhiker/heartOfGold. - ![Repository-Code-Changesets](assets/repository-code-changesetDetails.png) +#### Tags + +All tags for a changeset are displayed in the top-right corner of the details page. + +![Repository-Code-Changesets](assets/repository-code-changeset-with-tag.png) + +#### Creating Tags +New tags for a changeset can be created directly on its details page. +Only a name has to be provided that meets the same formatting conditions as branches. + +![Repository-Code-Changeset-Create-Tag](assets/repository-code-changeset-create-tag.png) + ### File Details After clicking on a file in the sources, the details of the file are shown. Depending on the format of the file, there are different views: diff --git a/docs/en/user/repo/tags.md b/docs/en/user/repo/tags.md index 1b5462ed3c..8fa9ffd16d 100644 --- a/docs/en/user/repo/tags.md +++ b/docs/en/user/repo/tags.md @@ -7,7 +7,26 @@ The tag overview shows the tags that exist for this repository. By clicking on a ![Tags Overview](assets/repository-tags-overview.png) +### Deleting Tags +Tags can be deleted directly on the tags overview page. + +![Tag Delete](assets/repository-tag-delete.png) + ### Tag Details Page This page shows a command to work with the tag on the command line. ![Tag Details Page](assets/repository-tag-detailView.png) + +#### Tag Signatures +The signature status of a tag is displayed as a key after its name on its details page. + +There can be more than one signature on a tag. + +Depending on the status of the individual signatures, the key will have a distinct color indicator: +- if at least one signature on the tag is invalid, the key will be `red` OTHERWISE +- if at least one signature is valid, the key will be `green` OTHERWISE +- the key will be `gray` + +If you hover the key icon, a list of all signatures on the tag will pop up. + +![Tag Signatures](assets/repository-tag-signatures.png) diff --git a/scm-ui/ui-components/src/index.ts b/scm-ui/ui-components/src/index.ts index 32a950d4af..a261a60b60 100644 --- a/scm-ui/ui-components/src/index.ts +++ b/scm-ui/ui-components/src/index.ts @@ -75,6 +75,7 @@ export { default as SyntaxHighlighter } from "./SyntaxHighlighter"; export { default as ErrorBoundary } from "./ErrorBoundary"; export { default as OverviewPageActions } from "./OverviewPageActions"; export { default as CardColumnGroup } from "./CardColumnGroup"; +export { default as CreateTagModal } from "./modals/CreateTagModal"; export { default as CardColumn } from "./CardColumn"; export { default as CardColumnSmall } from "./CardColumnSmall"; export { default as CommaSeparatedList } from "./CommaSeparatedList"; diff --git a/scm-ui/ui-webapp/src/repos/components/changesets/CreateTagModal.tsx b/scm-ui/ui-components/src/modals/CreateTagModal.tsx similarity index 73% rename from scm-ui/ui-webapp/src/repos/components/changesets/CreateTagModal.tsx rename to scm-ui/ui-components/src/modals/CreateTagModal.tsx index 1e83d784a0..304bca75a1 100644 --- a/scm-ui/ui-webapp/src/repos/components/changesets/CreateTagModal.tsx +++ b/scm-ui/ui-components/src/modals/CreateTagModal.tsx @@ -25,19 +25,29 @@ import React, {FC, useEffect, useState} from "react"; import { Modal, InputField, Button, apiClient } from "@scm-manager/ui-components"; import { WithTranslation, withTranslation } from "react-i18next"; +import {Tag} from "@scm-manager/ui-types"; +import {isBranchValid} from "../validation"; type Props = WithTranslation & { + existingTagsLink: string; tagCreationLink: string; - tagNames: string[]; onClose: () => void; onCreated: () => void; onError: (error: Error) => void; revision: string; }; -const CreateTagModal: FC = ({ t, onClose, tagCreationLink, onCreated, onError, revision, tagNames }) => { +const CreateTagModal: FC = ({ t, onClose, tagCreationLink, existingTagsLink, onCreated, onError, revision }) => { const [newTagName, setNewTagName] = useState(""); const [loading, setLoading] = useState(false); + const [tagNames, setTagNames] = useState([]); + + useEffect(() => { + apiClient + .get(existingTagsLink) + .then(response => response.json()) + .then(json => setTagNames(json._embedded.tags.map((tag: Tag) => tag.name))); + }, [existingTagsLink]); const createTag = () => { setLoading(true); @@ -51,9 +61,15 @@ const CreateTagModal: FC = ({ t, onClose, tagCreationLink, onCreated, onE .finally(() => setLoading(false)); }; - const isInvalid = () => { - return tagNames.includes(newTagName); - }; + let validationError = ""; + + if (newTagName !== "") { + if (tagNames.includes(newTagName)) { + validationError = "tags.create.form.field.name.error.exists"; + } else if (!isBranchValid(newTagName)) { + validationError = "tags.create.form.field.name.error.format"; + } + } return ( = ({ t, onClose, tagCreationLink, onCreated, onE label={t("tags.create.form.field.name.label")} onChange={val => setNewTagName(val)} value={newTagName} - validationError={isInvalid()} - errorMessage={t("tags.create.form.field.name.error")} + validationError={!!validationError} + errorMessage={t(validationError)} /> -

+
{t("tags.create.hint")}
} footer={ <> - diff --git a/scm-ui/ui-webapp/public/locales/de/repos.json b/scm-ui/ui-webapp/public/locales/de/repos.json index 7647a67d60..78371d3e9b 100644 --- a/scm-ui/ui-webapp/public/locales/de/repos.json +++ b/scm-ui/ui-webapp/public/locales/de/repos.json @@ -96,7 +96,10 @@ "field": { "name": { "label": "Name", - "error": "Dieser Tag existiert bereits." + "error": { + "exists": "Dieser Tag existiert bereits in diesem Repository.", + "format": "Der Tag entspricht nicht dem korrekten Format." + } } } }, diff --git a/scm-ui/ui-webapp/public/locales/en/repos.json b/scm-ui/ui-webapp/public/locales/en/repos.json index fde688516e..c789a3253e 100644 --- a/scm-ui/ui-webapp/public/locales/en/repos.json +++ b/scm-ui/ui-webapp/public/locales/en/repos.json @@ -96,7 +96,10 @@ "field": { "name": { "label": "Name", - "error": "This tag already exists." + "error": { + "exists": "This tag already exists in this repository.", + "format": "The tag name does not match the correct format." + } } } }, diff --git a/scm-ui/ui-webapp/src/repos/components/changesets/ChangesetDetails.tsx b/scm-ui/ui-webapp/src/repos/components/changesets/ChangesetDetails.tsx index b730b74101..e2bb6d7a12 100644 --- a/scm-ui/ui-webapp/src/repos/components/changesets/ChangesetDetails.tsx +++ b/scm-ui/ui-webapp/src/repos/components/changesets/ChangesetDetails.tsx @@ -43,11 +43,11 @@ import { Level, SignatureIcon, Tooltip, - ErrorNotification + ErrorNotification, + CreateTagModal } from "@scm-manager/ui-components"; import ContributorTable from "./ContributorTable"; import { Link as ReactLink } from "react-router-dom"; -import CreateTagModal from "./CreateTagModal"; type Props = WithTranslation & { changeset: Changeset; @@ -226,7 +226,7 @@ const ChangesetDetails: FC = ({ changeset, repository, fileControlFactory
+ ); }; diff --git a/scm-ui/ui-webapp/src/repos/tags/container/DeleteTag.tsx b/scm-ui/ui-webapp/src/repos/tags/container/DeleteTag.tsx new file mode 100644 index 0000000000..83cd2d0db3 --- /dev/null +++ b/scm-ui/ui-webapp/src/repos/tags/container/DeleteTag.tsx @@ -0,0 +1,93 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React, { FC, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { useHistory } from "react-router-dom"; +import { apiClient, ConfirmAlert, DeleteButton, ErrorNotification, Level } from "@scm-manager/ui-components"; +import { Link, Repository, Tag } from "@scm-manager/ui-types"; + +type Props = { + repository: Repository; + tag: Tag; +}; + +const DeleteTag: FC = ({ tag, repository }) => { + const [showConfirmAlert, setShowConfirmAlert] = useState(false); + const [error, setError] = useState(); + const [t] = useTranslation("repos"); + const history = useHistory(); + + const deleteBranch = () => { + apiClient + .delete((tag._links.delete as Link).href) + .then(() => history.push(`/repo/${repository.namespace}/${repository.name}/tags/`)) + .catch(setError); + }; + + if (!tag._links.delete) { + return null; + } + + let confirmAlert = null; + if (showConfirmAlert) { + confirmAlert = ( + deleteBranch() + }, + { + label: t("tag.delete.confirmAlert.cancel"), + onClick: () => null + } + ]} + close={() => setShowConfirmAlert(false)} + /> + ); + } + + return ( + <> + + {showConfirmAlert && confirmAlert} + + {t("tag.delete.subtitle")} +
+ {t("tag.delete.description")} +

+ } + right={ setShowConfirmAlert(true)} />} + /> + + ); +}; + +export default DeleteTag; diff --git a/scm-ui/ui-webapp/src/repos/tags/container/TagDangerZone.tsx b/scm-ui/ui-webapp/src/repos/tags/container/TagDangerZone.tsx new file mode 100644 index 0000000000..6e3b421939 --- /dev/null +++ b/scm-ui/ui-webapp/src/repos/tags/container/TagDangerZone.tsx @@ -0,0 +1,59 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React, { FC } from "react"; +import { Repository, Tag } from "@scm-manager/ui-types"; +import { Subtitle } from "@scm-manager/ui-components"; +import { useTranslation } from "react-i18next"; +import { DangerZoneContainer } from "../../containers/RepositoryDangerZone"; +import DeleteTag from "./DeleteTag"; + +type Props = { + repository: Repository; + tag: Tag; +}; + +const TagDangerZone: FC = ({ repository, tag }) => { + const [t] = useTranslation("repos"); + + const dangerZone = []; + + if (tag?._links?.delete) { + dangerZone.push(); + } + + if (dangerZone.length === 0) { + return null; + } + + return ( + <> +
+ + {dangerZone} + + ); +}; + +export default TagDangerZone; From e8044747e3005f89decd61ffcf7bb8df82ed8aae Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Tue, 1 Dec 2020 11:18:19 +0100 Subject: [PATCH 28/35] fix review findings --- .../sonia/scm/repository/TagCreatedEvent.java | 41 ------------------- .../sonia/scm/repository/TagDeletedEvent.java | 40 ------------------ .../scm/repository/api/RepositoryService.java | 2 +- .../scm/repository/api/TagCommandBuilder.java | 19 ++------- .../spi/RepositoryServiceProvider.java | 2 +- .../scm/repository/spi/HgTagsCommandTest.java | 2 +- .../resources/TagCollectionToDtoMapper.java | 9 ++-- .../scm/api/v2/resources/TagRootResource.java | 27 ++++++++---- .../api/v2/resources/TagToTagDtoMapper.java | 14 +++---- .../v2/resources/TagToTagDtoMapperTest.java | 21 +++++----- 10 files changed, 49 insertions(+), 128 deletions(-) delete mode 100644 scm-core/src/main/java/sonia/scm/repository/TagCreatedEvent.java delete mode 100644 scm-core/src/main/java/sonia/scm/repository/TagDeletedEvent.java diff --git a/scm-core/src/main/java/sonia/scm/repository/TagCreatedEvent.java b/scm-core/src/main/java/sonia/scm/repository/TagCreatedEvent.java deleted file mode 100644 index d268394769..0000000000 --- a/scm-core/src/main/java/sonia/scm/repository/TagCreatedEvent.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020-present Cloudogu GmbH and Contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package sonia.scm.repository; - -import lombok.Value; -import sonia.scm.event.Event; - -/** - * This event is fired when a new tag was created by the SCM-Manager. - * Warning: This event will not be fired if a new tag was pushed. - * @since 2.10.0 - */ -@Event -@Value -public class TagCreatedEvent { - Repository repository; - String revision; - String tagName; -} diff --git a/scm-core/src/main/java/sonia/scm/repository/TagDeletedEvent.java b/scm-core/src/main/java/sonia/scm/repository/TagDeletedEvent.java deleted file mode 100644 index 13703c9223..0000000000 --- a/scm-core/src/main/java/sonia/scm/repository/TagDeletedEvent.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020-present Cloudogu GmbH and Contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package sonia.scm.repository; - -import lombok.Value; -import sonia.scm.event.Event; - -/** - * This event is fired when a tag was deleted by the SCM-Manager. - * Warning: This event will not be fired if a tag was removed by a push of a git client. - * @since 2.10.0 - */ -@Event -@Value -public class TagDeletedEvent { - Repository repository; - String tagName; -} diff --git a/scm-core/src/main/java/sonia/scm/repository/api/RepositoryService.java b/scm-core/src/main/java/sonia/scm/repository/api/RepositoryService.java index c1b1321419..ef4c048803 100644 --- a/scm-core/src/main/java/sonia/scm/repository/api/RepositoryService.java +++ b/scm-core/src/main/java/sonia/scm/repository/api/RepositoryService.java @@ -386,7 +386,7 @@ public final class RepositoryService implements Closeable { * by the implementation of the repository service provider. */ public TagCommandBuilder getTagCommand() { - return new TagCommandBuilder(repository, provider.getTagCommand()); + return new TagCommandBuilder(provider.getTagCommand()); } /** diff --git a/scm-core/src/main/java/sonia/scm/repository/api/TagCommandBuilder.java b/scm-core/src/main/java/sonia/scm/repository/api/TagCommandBuilder.java index ca2a0f176f..c58f550a5d 100644 --- a/scm-core/src/main/java/sonia/scm/repository/api/TagCommandBuilder.java +++ b/scm-core/src/main/java/sonia/scm/repository/api/TagCommandBuilder.java @@ -24,24 +24,16 @@ package sonia.scm.repository.api; -import sonia.scm.event.ScmEventBus; -import sonia.scm.repository.Repository; import sonia.scm.repository.Tag; -import sonia.scm.repository.TagCreatedEvent; -import sonia.scm.repository.TagDeletedEvent; import sonia.scm.repository.spi.TagCommand; import java.io.IOException; public class TagCommandBuilder { - private final Repository repository; private final TagCommand command; - private final ScmEventBus eventBus; - public TagCommandBuilder(Repository repository, TagCommand command) { - this.repository = repository; + public TagCommandBuilder(TagCommand command) { this.command = command; - this.eventBus = ScmEventBus.getInstance(); } public TagCreateCommandBuilder create() { @@ -53,7 +45,7 @@ public class TagCommandBuilder { } public class TagCreateCommandBuilder { - private TagCreateRequest request = new TagCreateRequest(); + private final TagCreateRequest request = new TagCreateRequest(); public TagCreateCommandBuilder setRevision(String revision) { request.setRevision(revision); @@ -66,14 +58,12 @@ public class TagCommandBuilder { } public Tag execute() throws IOException { - Tag tag = command.create(request); - eventBus.post(new TagCreatedEvent(repository, request.getRevision(), request.getName())); - return tag; + return command.create(request); } } public class TagDeleteCommandBuilder { - private TagDeleteRequest request = new TagDeleteRequest(); + private final TagDeleteRequest request = new TagDeleteRequest(); public TagDeleteCommandBuilder setName(String name) { request.setName(name); @@ -82,7 +72,6 @@ public class TagCommandBuilder { public void execute() throws IOException { command.delete(request); - eventBus.post(new TagDeletedEvent(repository, request.getName())); } } } diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceProvider.java b/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceProvider.java index 62548280e7..16754ef876 100644 --- a/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceProvider.java +++ b/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceProvider.java @@ -254,7 +254,7 @@ public abstract class RepositoryServiceProvider implements Closeable */ public TagCommand getTagCommand() { - throw new CommandNotSupportedException(Command.TAGS); + throw new CommandNotSupportedException(Command.TAG); } /** diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgTagsCommandTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgTagsCommandTest.java index 2d5f171b16..afe3fe885d 100644 --- a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgTagsCommandTest.java +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgTagsCommandTest.java @@ -64,7 +64,7 @@ public class HgTagsCommandTest extends AbstractHgCommandTestBase { @Test public void shouldNotDie() throws IOException { HgTagCommand hgTagCommand = new HgTagCommand(cmdContext, workingCopyFactory); - new TagCommandBuilder(cmdContext.get(), hgTagCommand).create().setRevision("79b6baf49711").setName("newtag").execute(); + new TagCommandBuilder(hgTagCommand).create().setRevision("79b6baf49711").setName("newtag").execute(); HgTagsCommand hgTagsCommand = new HgTagsCommand(cmdContext); final List tags = hgTagsCommand.getTags(); diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagCollectionToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagCollectionToDtoMapper.java index e2e5ac0027..99914ecc14 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagCollectionToDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagCollectionToDtoMapper.java @@ -52,13 +52,12 @@ public class TagCollectionToDtoMapper { this.tagToTagDtoMapper = tagToTagDtoMapper; } - public HalRepresentation map(String namespace, String name, Collection tags, Repository repository) { - return new HalRepresentation(createLinks(namespace, name), embedDtos(getTagDtoList(namespace, name, tags, repository))); + public HalRepresentation map(Collection tags, Repository repository) { + return new HalRepresentation(createLinks(repository.getNamespace(), repository.getName()), embedDtos(getTagDtoList(tags, repository))); } - public List getTagDtoList(String namespace, String name, Collection tags, Repository repository) { - final NamespaceAndName namespaceAndName = new NamespaceAndName(namespace, name); - return tags.stream().map(tag -> tagToTagDtoMapper.map(tag, namespaceAndName, repository)).collect(toList()); + public List getTagDtoList(Collection tags, Repository repository) { + return tags.stream().map(tag -> tagToTagDtoMapper.map(tag, repository)).collect(toList()); } public List getMinimalEmbeddedTagDtoList(String namespace, String name, Collection tags) { diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRootResource.java index 37760e070a..1d102a68b0 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRootResource.java @@ -27,7 +27,9 @@ package sonia.scm.api.v2.resources; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.headers.Header; import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import sonia.scm.NotFoundException; import sonia.scm.repository.Branch; @@ -100,7 +102,7 @@ public class TagRootResource { try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) { Tags tags = getTags(repositoryService); if (tags != null && tags.getTags() != null) { - return Response.ok(tagCollectionToDtoMapper.map(namespace, name, tags.getTags(), repositoryService.getRepository())).build(); + return Response.ok(tagCollectionToDtoMapper.map(tags.getTags(), repositoryService.getRepository())).build(); } else { return Response.status(Response.Status.INTERNAL_SERVER_ERROR) .entity("Error on getting tag from repository.") @@ -112,7 +114,20 @@ public class TagRootResource { @POST @Path("") @Produces(VndMediaType.TAG_REQUEST) - @Operation(summary = "Create tag", description = "Creates a new tag and returns it", tags = "Repository") + @Operation(summary = "Create tag", + description = "Creates a new tag.", + tags = "Repository", + requestBody = @RequestBody( + content = @Content( + mediaType = VndMediaType.TAG_REQUEST, + schema = @Schema(implementation = TagRequestDto.class), + examples = @ExampleObject( + name = "Create a new tag for a revision", + value = "{\n \"revision\":\"734713bc047d87bf7eac9674765ae793478c50d3\",\n \"name\":\"v1.1.0\"\n}", + summary = "Create a tag" + ) + ) + )) @ApiResponse( responseCode = "201", description = "create success", @@ -144,7 +159,7 @@ public class TagRootResource { String tagName = tagRequest.getName(); try (RepositoryService repositoryService = serviceFactory.create(namespaceAndName)) { if (tagExists(tagName, repositoryService)) { - throw alreadyExists(entity(Tag.class, tagName).in(Repository.class, namespace + "/" + name)); + throw alreadyExists(entity(Tag.class, tagName).in(repositoryService.getRepository())); } Repository repository = repositoryService.getRepository(); RepositoryPermissions.push(repository).check(); @@ -194,7 +209,7 @@ public class TagRootResource { .filter(t -> tagName.equals(t.getName())) .findFirst() .orElseThrow(() -> createNotFoundException(namespace, name, tagName)); - return Response.ok(tagToTagDtoMapper.map(tag, namespaceAndName, repositoryService.getRepository())).build(); + return Response.ok(tagToTagDtoMapper.map(tag, repositoryService.getRepository())).build(); } else { return Response.status(Response.Status.INTERNAL_SERVER_ERROR) .entity("Error on getting tag from repository.") @@ -227,7 +242,7 @@ public class TagRootResource { mediaType = VndMediaType.ERROR_TYPE, schema = @Schema(implementation = ErrorDto.class) )) - public Response delete(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("tagName") String tagName) { + public Response delete(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("tagName") String tagName) throws IOException { NamespaceAndName namespaceAndName = new NamespaceAndName(namespace, name); try (RepositoryService repositoryService = serviceFactory.create(namespaceAndName)) { RepositoryPermissions.push(repositoryService.getRepository()).check(); @@ -239,8 +254,6 @@ public class TagRootResource { } return Response.noContent().build(); - } catch (IOException e) { - return Response.serverError().build(); } } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java index fc59449f3d..74b70037c4 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java @@ -55,22 +55,22 @@ public abstract class TagToTagDtoMapper extends HalAppenderMapper { @Mapping(target = "date", source = "date", qualifiedByName = "mapDate") @Mapping(target = "attributes", ignore = true) // We do not map HAL attributes @Mapping(target = "signatures") - public abstract TagDto map(Tag tag, @Context NamespaceAndName namespaceAndName, @Context Repository repository); + public abstract TagDto map(Tag tag, @Context Repository repository); @ObjectFactory - TagDto createDto(@Context NamespaceAndName namespaceAndName, @Context Repository repository, Tag tag) { + TagDto createDto(@Context Repository repository, Tag tag) { Links.Builder linksBuilder = linkingTo() - .self(resourceLinks.tag().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), tag.getName())) - .single(link("sources", resourceLinks.source().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), tag.getRevision()))) - .single(link("changeset", resourceLinks.changeset().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), tag.getRevision()))); + .self(resourceLinks.tag().self(repository.getNamespace(), repository.getName(), tag.getName())) + .single(link("sources", resourceLinks.source().self(repository.getNamespace(), repository.getName(), tag.getRevision()))) + .single(link("changeset", resourceLinks.changeset().self(repository.getNamespace(), repository.getName(), tag.getRevision()))); if (tag.getDeletable() && RepositoryPermissions.push(repository).isPermitted()) { linksBuilder - .single(link("delete", resourceLinks.tag().delete(namespaceAndName.getNamespace(), namespaceAndName.getName(), tag.getName()))); + .single(link("delete", resourceLinks.tag().delete(repository.getNamespace(), repository.getName(), tag.getName()))); } Embedded.Builder embeddedBuilder = embeddedBuilder(); - applyEnrichers(new EdisonHalAppender(linksBuilder, embeddedBuilder), tag, namespaceAndName); + applyEnrichers(new EdisonHalAppender(linksBuilder, embeddedBuilder), tag, repository); return new TagDto(linksBuilder.build(), embeddedBuilder.build()); } diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/TagToTagDtoMapperTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/TagToTagDtoMapperTest.java index c0d1bb8289..3fea41860b 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/TagToTagDtoMapperTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/TagToTagDtoMapperTest.java @@ -74,26 +74,27 @@ class TagToTagDtoMapperTest { void shouldAppendLinks() { HalEnricherRegistry registry = new HalEnricherRegistry(); registry.register(Tag.class, (ctx, appender) -> { - NamespaceAndName repository = ctx.oneRequireByType(NamespaceAndName.class); + Repository repository = ctx.oneRequireByType(Repository.class); Tag tag = ctx.oneRequireByType(Tag.class); - appender.appendLink("yo", "http://" + repository.logString() + "/" + tag.getName()); + + appender.appendLink("yo", "http://" + repository.getNamespace() + "/" + repository.getName() + "/" + tag.getName()); }); mapper.setRegistry(registry); - TagDto dto = mapper.map(new Tag("1.0.0", "42"), new NamespaceAndName("hitchhiker", "hog"), RepositoryTestData.createHeartOfGold()); - assertThat(dto.getLinks().getLinkBy("yo").get().getHref()).isEqualTo("http://hitchhiker/hog/1.0.0"); + TagDto dto = mapper.map(new Tag("1.0.0", "42"), RepositoryTestData.createHeartOfGold()); + assertThat(dto.getLinks().getLinkBy("yo").get().getHref()).isEqualTo("http://hitchhiker/HeartOfGold/1.0.0"); } @Test void shouldMapDate() { final long now = Instant.now().getEpochSecond() * 1000; - TagDto dto = mapper.map(new Tag("1.0.0", "42", now), new NamespaceAndName("hitchhiker", "hog"), RepositoryTestData.createHeartOfGold()); + TagDto dto = mapper.map(new Tag("1.0.0", "42", now), RepositoryTestData.createHeartOfGold()); assertThat(dto.getDate()).isEqualTo(Instant.ofEpochMilli(now)); } @Test void shouldContainSignatureArray() { - TagDto dto = mapper.map(new Tag("1.0.0", "42"), new NamespaceAndName("hitchhiker", "hog"), RepositoryTestData.createHeartOfGold()); + TagDto dto = mapper.map(new Tag("1.0.0", "42"), RepositoryTestData.createHeartOfGold()); assertThat(dto.getSignatures()).isNotNull(); } @@ -101,7 +102,7 @@ class TagToTagDtoMapperTest { void shouldMapSignatures() { final Tag tag = new Tag("1.0.0", "42"); tag.addSignature(new Signature("29v391239v", "gpg", SignatureStatus.VERIFIED, "me", Collections.emptySet())); - TagDto dto = mapper.map(tag, new NamespaceAndName("hitchhiker", "hog"), RepositoryTestData.createHeartOfGold()); + TagDto dto = mapper.map(tag, RepositoryTestData.createHeartOfGold()); assertThat(dto.getSignatures()).isNotEmpty(); } @@ -110,21 +111,21 @@ class TagToTagDtoMapperTest { Repository repository = RepositoryTestData.createHeartOfGold(); when(subject.isPermitted("repository:push:" + repository.getId())).thenReturn(true); final Tag tag = new Tag("1.0.0", "42"); - TagDto dto = mapper.map(tag, new NamespaceAndName(repository.getNamespace(), repository.getName()), repository); + TagDto dto = mapper.map(tag, repository); assertThat(dto.getLinks().getLinkBy("delete")).isNotEmpty(); } @Test void shouldNotAddDeleteLinkIfPermissionsAreMissing() { final Tag tag = new Tag("1.0.0", "42"); - TagDto dto = mapper.map(tag, new NamespaceAndName("hitchhiker", "hog"), RepositoryTestData.createHeartOfGold()); + TagDto dto = mapper.map(tag, RepositoryTestData.createHeartOfGold()); assertThat(dto.getLinks().getLinkBy("delete")).isEmpty(); } @Test void shouldNotAddDeleteLinksForUndeletableTags() { final Tag tag = new Tag("1.0.0", "42", null, false); - TagDto dto = mapper.map(tag, new NamespaceAndName("hitchhiker", "hog"), RepositoryTestData.createHeartOfGold()); + TagDto dto = mapper.map(tag, RepositoryTestData.createHeartOfGold()); assertThat(dto.getLinks().getLinkBy("delete")).isEmpty(); } From 9ec8b4efac2d54cd44a91eb216df44114b510f54 Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Tue, 1 Dec 2020 15:16:55 +0100 Subject: [PATCH 29/35] fix review findings --- .../main/java/sonia/scm/repository/Tag.java | 4 + .../scm/repository/api/TagCommandBuilder.java | 32 ++++- .../spi/RepositoryServiceProvider.java | 6 +- .../java/sonia/scm/repository/GitUtil.java | 88 +----------- .../scm/repository/spi/GitTagCommand.java | 133 ++++++++++-------- .../scm/repository/spi/GitTagsCommand.java | 48 +++---- .../scm/repository/spi/GitTagCommandTest.java | 4 +- .../scm/repository/spi/HgTagCommand.java | 14 +- .../scm/repository/spi/HgTagsCommandTest.java | 30 ---- .../src/modals/CreateTagModal.tsx | 13 +- scm-ui/ui-types/src/Tags.ts | 2 +- scm-ui/ui-webapp/public/locales/en/repos.json | 2 +- .../changesets/ChangesetDetails.tsx | 2 +- .../src/repos/tags/components/TagRow.tsx | 1 + .../src/repos/tags/components/TagTable.tsx | 29 ++-- .../src/repos/tags/container/TagsOverview.tsx | 2 +- .../scm/api/v2/resources/TagRequestDto.java | 8 +- 17 files changed, 176 insertions(+), 242 deletions(-) diff --git a/scm-core/src/main/java/sonia/scm/repository/Tag.java b/scm-core/src/main/java/sonia/scm/repository/Tag.java index 7279f5e68e..933faa403d 100644 --- a/scm-core/src/main/java/sonia/scm/repository/Tag.java +++ b/scm-core/src/main/java/sonia/scm/repository/Tag.java @@ -31,6 +31,7 @@ import lombok.ToString; import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.regex.Pattern; /** * Represents a tag in a repository. @@ -43,6 +44,9 @@ import java.util.Optional; @Getter public final class Tag { + public static final String VALID_REV = "[0-9a-z]+"; + public static final Pattern VALID_REV_PATTERN = Pattern.compile(VALID_REV); + private final String name; private final String revision; private final Long date; diff --git a/scm-core/src/main/java/sonia/scm/repository/api/TagCommandBuilder.java b/scm-core/src/main/java/sonia/scm/repository/api/TagCommandBuilder.java index c58f550a5d..b64bc3ce97 100644 --- a/scm-core/src/main/java/sonia/scm/repository/api/TagCommandBuilder.java +++ b/scm-core/src/main/java/sonia/scm/repository/api/TagCommandBuilder.java @@ -29,29 +29,52 @@ import sonia.scm.repository.spi.TagCommand; import java.io.IOException; -public class TagCommandBuilder { +/** + * @since 2.11.0 + */ +public final class TagCommandBuilder { private final TagCommand command; public TagCommandBuilder(TagCommand command) { this.command = command; } + /** + * Initialize a command to tag a revision. + * + * Set parameters and call {@link TagCreateCommandBuilder#execute()}. + * + * @since 2.11.0 + */ public TagCreateCommandBuilder create() { return new TagCreateCommandBuilder(); } + /** + * Initialize a command to delete a tag. + * + * Set parameters and call {@link TagDeleteCommandBuilder#execute()}. + * + * @since 2.11.0 + */ public TagDeleteCommandBuilder delete() { return new TagDeleteCommandBuilder(); } - public class TagCreateCommandBuilder { + public final class TagCreateCommandBuilder { private final TagCreateRequest request = new TagCreateRequest(); + /** + * @param revision The revision identifier for which to create the tag + */ public TagCreateCommandBuilder setRevision(String revision) { request.setRevision(revision); return this; } + /** + * @param name The name of the tag + */ public TagCreateCommandBuilder setName(String name) { request.setName(name); return this; @@ -62,9 +85,12 @@ public class TagCommandBuilder { } } - public class TagDeleteCommandBuilder { + public final class TagDeleteCommandBuilder { private final TagDeleteRequest request = new TagDeleteRequest(); + /** + * @param name The name of the tag that should be deleted + */ public TagDeleteCommandBuilder setName(String name) { request.setName(name); return this; diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceProvider.java b/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceProvider.java index 16754ef876..4e56cc57f9 100644 --- a/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceProvider.java +++ b/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceProvider.java @@ -246,11 +246,9 @@ public abstract class RepositoryServiceProvider implements Closeable throw new CommandNotSupportedException(Command.TAGS); } + /** - * Method description - * - * - * @return + * @since 2.11.0 */ public TagCommand getTagCommand() { diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java index 72d74803d8..5c0b0315b7 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java @@ -82,60 +82,16 @@ import static java.util.Optional.of; public final class GitUtil { private static final GitUserAgentProvider GIT_USER_AGENT_PROVIDER = new GitUserAgentProvider(); - - /** - * Field description - */ public static final String REF_HEAD = "HEAD"; - - /** - * Field description - */ public static final String REF_HEAD_PREFIX = "refs/heads/"; - - /** - * Field description - */ public static final String REF_MASTER = "master"; - - /** - * Field description - */ private static final String DIRECTORY_DOTGIT = ".git"; - - /** - * Field description - */ private static final String DIRECTORY_OBJETCS = "objects"; - - /** - * Field description - */ private static final String DIRECTORY_REFS = "refs"; - - /** - * Field description - */ private static final String PREFIX_HEADS = "refs/heads/"; - - /** - * Field description - */ private static final String PREFIX_TAG = "refs/tags/"; - - /** - * Field description - */ private static final String REFSPEC = "+refs/heads/*:refs/remote/scm/%s/*"; - - /** - * Field description - */ private static final String REMOTE_REF = "refs/remote/scm/%s/%s"; - - /** - * Field description - */ private static final int TIMEOUT = 5; /** @@ -145,19 +101,11 @@ public final class GitUtil { //~--- constructors --------------------------------------------------------- - /** - * Constructs ... - */ private GitUtil() { } //~--- methods -------------------------------------------------------------- - /** - * Method description - * - * @param repo - */ public static void close(org.eclipse.jgit.lib.Repository repo) { if (repo != null) { repo.close(); @@ -186,7 +134,7 @@ public final class GitUtil { if (c != null) { tags.put(c.getId(), e.getKey()); - } else if (logger.isWarnEnabled()) { + } else { logger.warn("could not find commit for tag {}", e.getKey()); } @@ -214,13 +162,6 @@ public final class GitUtil { } } - /** - * Method description - * - * @param directory - * @return - * @throws IOException - */ public static org.eclipse.jgit.lib.Repository open(File directory) throws IOException { FS fs = FS.DETECTED; @@ -239,33 +180,18 @@ public final class GitUtil { return builder.build(); } - /** - * Method description - * - * @param formatter - */ public static void release(DiffFormatter formatter) { if (formatter != null) { formatter.close(); } } - /** - * Method description - * - * @param walk - */ public static void release(TreeWalk walk) { if (walk != null) { walk.close(); } } - /** - * Method description - * - * @param walk - */ public static void release(RevWalk walk) { if (walk != null) { walk.close(); @@ -274,12 +200,6 @@ public final class GitUtil { //~--- get methods ---------------------------------------------------------- - /** - * Method description - * - * @param ref - * @return - */ public static String getBranch(Ref ref) { String branch = null; @@ -290,12 +210,6 @@ public final class GitUtil { return branch; } - /** - * Method description - * - * @param name - * @return - */ public static String getBranch(String name) { String branch = null; diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java index 40805c881d..fda08d957b 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java @@ -25,6 +25,7 @@ package sonia.scm.repository.spi; import com.google.common.base.Strings; +import org.apache.shiro.SecurityUtils; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.lib.ObjectId; @@ -34,6 +35,7 @@ import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevObject; import org.eclipse.jgit.revwalk.RevWalk; +import sonia.scm.NotFoundException; import sonia.scm.event.ScmEventBus; import sonia.scm.repository.GitUtil; import sonia.scm.repository.InternalRepositoryException; @@ -41,7 +43,6 @@ import sonia.scm.repository.PostReceiveRepositoryHookEvent; import sonia.scm.repository.PreReceiveRepositoryHookEvent; import sonia.scm.repository.RepositoryHookEvent; import sonia.scm.repository.RepositoryHookType; -import sonia.scm.repository.Signature; import sonia.scm.repository.Tag; import sonia.scm.repository.api.HookContext; import sonia.scm.repository.api.HookContextFactory; @@ -50,6 +51,7 @@ import sonia.scm.repository.api.HookTagProvider; import sonia.scm.repository.api.TagCreateRequest; import sonia.scm.repository.api.TagDeleteRequest; import sonia.scm.security.GPG; +import sonia.scm.user.User; import javax.inject.Inject; import java.io.IOException; @@ -76,53 +78,72 @@ public class GitTagCommand extends AbstractGitCommand implements TagCommand { @Override public Tag create(TagCreateRequest request) { + final String name = request.getName(); + final String revision = request.getRevision(); + + if (Strings.isNullOrEmpty(revision)) { + throw new IllegalArgumentException("Revision is required"); + } + + if (Strings.isNullOrEmpty(name)) { + throw new IllegalArgumentException("Name is required"); + } + try (Git git = new Git(context.open())) { - String revision = request.getRevision(); RevObject revObject; Long tagTime; - if (Strings.isNullOrEmpty(revision)) { - throw new IllegalArgumentException("Revision is required"); - } - ObjectId taggedCommitObjectId = git.getRepository().resolve(revision); + if (taggedCommitObjectId == null) { + throw new NotFoundException("revision", revision); + } + try (RevWalk walk = new RevWalk(git.getRepository())) { revObject = walk.parseAny(taggedCommitObjectId); tagTime = GitUtil.getTagTime(walk, taggedCommitObjectId); } - Tag tag = new Tag(request.getName(), revision, tagTime); + Tag tag = new Tag(name, revision, tagTime); RepositoryHookEvent hookEvent = createTagHookEvent(TagHookContextProvider.createHookEvent(tag)); eventBus.post(new PreReceiveRepositoryHookEvent(hookEvent)); - Ref ref = - git.tag() - .setObjectId(revObject) - .setTagger(new PersonIdent("SCM-Manager", "noreply@scm-manager.org")) - .setName(request.getName()) - .call(); + User user = SecurityUtils.getSubject().getPrincipals().oneByType(User.class); + PersonIdent taggerIdent = new PersonIdent(user.getDisplayName(), user.getMail()); - try (RevWalk walk = new RevWalk(git.getRepository())) { - revObject = walk.parseTag(ref.getObjectId()); - final Optional tagSignature = GitUtil.getTagSignature(revObject, gpg, walk); - tagSignature.ifPresent(tag::addSignature); - } +// Ref ref = + git.tag() + .setObjectId(revObject) + .setTagger(taggerIdent) + .setName(name) + .call(); + +// Uncomment lines once jgit added support for signing tags +// try (RevWalk walk = new RevWalk(git.getRepository())) { +// revObject = walk.parseTag(ref.getObjectId()); +// final Optional tagSignature = GitUtil.getTagSignature(revObject, gpg, walk); +// tagSignature.ifPresent(tag::addSignature); +// } eventBus.post(new PostReceiveRepositoryHookEvent(hookEvent)); return tag; } catch (IOException | GitAPIException ex) { - throw new InternalRepositoryException(repository, "could not create tag " + request.getName(), ex); + throw new InternalRepositoryException(repository, "could not create tag " + name + " for revision " + revision, ex); } } @Override public void delete(TagDeleteRequest request) { + String name = request.getName(); + + if (Strings.isNullOrEmpty(name)) { + throw new IllegalArgumentException("Name is required"); + } + try (Git git = new Git(context.open())) { - String name = request.getName(); final Repository repository = git.getRepository(); Optional tagRef = findTagRef(git, name); Tag tag; @@ -135,7 +156,7 @@ public class GitTagCommand extends AbstractGitCommand implements TagCommand { try (RevWalk walk = new RevWalk(repository)) { final RevCommit commit = GitUtil.getCommit(repository, walk, tagRef.get()); - Long tagTime = GitUtil.getTagTime(walk, commit.toObjectId()); + Long tagTime = GitUtil.getTagTime(walk, tagRef.get().getObjectId()); tag = new Tag(name, commit.name(), tagTime); } @@ -144,7 +165,7 @@ public class GitTagCommand extends AbstractGitCommand implements TagCommand { git.tagDelete().setTags(name).call(); eventBus.post(new PostReceiveRepositoryHookEvent(hookEvent)); } catch (GitAPIException | IOException e) { - throw new InternalRepositoryException(repository, "could not delete tag", e); + throw new InternalRepositoryException(repository, "could not delete tag " + name, e); } } @@ -158,46 +179,46 @@ public class GitTagCommand extends AbstractGitCommand implements TagCommand { return new RepositoryHookEvent(context, this.context.getRepository(), RepositoryHookType.PRE_RECEIVE); } - private static class TagHookContextProvider extends HookContextProvider { - private final List newTags; - private final List deletedTags; +private static class TagHookContextProvider extends HookContextProvider { + private final List newTags; + private final List deletedTags; - private TagHookContextProvider(List newTags, List deletedTags) { - this.newTags = newTags; - this.deletedTags = deletedTags; - } + private TagHookContextProvider(List newTags, List deletedTags) { + this.newTags = newTags; + this.deletedTags = deletedTags; + } - static TagHookContextProvider createHookEvent(Tag newTag) { - return new TagHookContextProvider(singletonList(newTag), emptyList()); - } + static TagHookContextProvider createHookEvent(Tag newTag) { + return new TagHookContextProvider(singletonList(newTag), emptyList()); + } - static TagHookContextProvider deleteHookEvent(Tag deletedTag) { - return new TagHookContextProvider(emptyList(), singletonList(deletedTag)); - } + static TagHookContextProvider deleteHookEvent(Tag deletedTag) { + return new TagHookContextProvider(emptyList(), singletonList(deletedTag)); + } - @Override - public Set getSupportedFeatures() { - return singleton(HookFeature.BRANCH_PROVIDER); - } + @Override + public Set getSupportedFeatures() { + return singleton(HookFeature.TAG_PROVIDER); + } - @Override - public HookTagProvider getTagProvider() { - return new HookTagProvider() { - @Override - public List getCreatedTags() { - return newTags; - } + @Override + public HookTagProvider getTagProvider() { + return new HookTagProvider() { + @Override + public List getCreatedTags() { + return newTags; + } - @Override - public List getDeletedTags() { - return deletedTags; - } - }; - } + @Override + public List getDeletedTags() { + return deletedTags; + } + }; + } - @Override - public HookChangesetProvider getChangesetProvider() { - return r -> new HookChangesetResponse(emptyList()); - } + @Override + public HookChangesetProvider getChangesetProvider() { + return r -> new HookChangesetResponse(emptyList()); } } +} diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagsCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagsCommand.java index e73302cba6..e01e366ac6 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagsCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagsCommand.java @@ -31,7 +31,10 @@ import com.google.common.collect.Lists; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.errors.IncorrectObjectTypeException; +import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevObject; import org.eclipse.jgit.revwalk.RevTag; import org.eclipse.jgit.revwalk.RevWalk; @@ -76,15 +79,13 @@ public class GitTagsCommand extends AbstractGitCommand implements TagsCommand { RevWalk revWalk = null; - try { - final Git git = new Git(open()); - + try (Git git = new Git(open())) { revWalk = new RevWalk(git.getRepository()); List tagList = git.tagList().call(); tags = Lists.transform(tagList, - new TransformFunction(git.getRepository(), revWalk, gpg, git)); + new TransformFunction(git.getRepository(), revWalk, gpg)); } catch (GitAPIException ex) { throw new InternalRepositoryException(repository, "could not read tags from repository", ex); } finally { @@ -114,18 +115,15 @@ public class GitTagsCommand extends AbstractGitCommand implements TagsCommand { /** * Constructs ... - * - * @param repository + * @param repository * @param revWalk */ - public TransformFunction(org.eclipse.jgit.lib.Repository repository, + public TransformFunction(Repository repository, RevWalk revWalk, - GPG gpg, - Git git) { + GPG gpg) { this.repository = repository; this.revWalk = revWalk; this.gpg = gpg; - this.git = git; } //~--- methods ------------------------------------------------------------ @@ -141,26 +139,17 @@ public class GitTagsCommand extends AbstractGitCommand implements TagsCommand { Tag tag = null; try { - RevObject revObject = GitUtil.getCommit(repository, revWalk, ref); - - if (revObject != null) { + RevCommit revCommit = GitUtil.getCommit(repository, revWalk, ref); + if (revCommit != null) { String name = GitUtil.getTagName(ref); - - tag = new Tag(name, revObject.getId().name(), GitUtil.getTagTime(revWalk, ref.getObjectId())); - - try { - RevTag revTag = GitUtil.getTag(repository, revWalk, ref); - - final Optional tagSignature = GitUtil.getTagSignature(revTag, gpg, revWalk); - if (tagSignature.isPresent()) { - tag.addSignature(tagSignature.get()); - } - } catch (IncorrectObjectTypeException e) { - // Ignore because it is a lightweight tag which cannot have signatures + tag = new Tag(name, revCommit.getId().name(), GitUtil.getTagTime(revWalk, ref.getObjectId())); + RevObject revObject = revWalk.parseAny(ref.getObjectId()); + if (revObject.getType() == Constants.OBJ_TAG) { + RevTag revTag = (RevTag) revObject; + GitUtil.getTagSignature(revTag, gpg, revWalk) + .ifPresent(tag::addSignature); } - } - } catch (IOException ex) { logger.error("could not get commit for tag", ex); } @@ -173,13 +162,12 @@ public class GitTagsCommand extends AbstractGitCommand implements TagsCommand { /** * Field description */ - private org.eclipse.jgit.lib.Repository repository; + private final org.eclipse.jgit.lib.Repository repository; /** * Field description */ - private RevWalk revWalk; + private final RevWalk revWalk; private final GPG gpg; - private final Git git; } } diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagCommandTest.java index 12b02e3473..0225d40b5d 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagCommandTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagCommandTest.java @@ -134,8 +134,8 @@ public class GitTagCommandTest extends AbstractGitCommandTestBase { } private Optional findTag(GitContext context, String name) throws IOException { - List branches = readTags(context); - return branches.stream().filter(b -> name.equals(b.getName())).findFirst(); + List tags = readTags(context); + return tags.stream().filter(t -> name.equals(t.getName())).findFirst(); } private HookContext createMockedContext(InvocationOnMock invocation) { diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgTagCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgTagCommand.java index fe2fcd17c6..dc633bebf1 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgTagCommand.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgTagCommand.java @@ -27,6 +27,7 @@ package sonia.scm.repository.spi; import com.aragost.javahg.Repository; import com.aragost.javahg.commands.PullCommand; import com.google.common.base.Strings; +import org.apache.shiro.SecurityUtils; import sonia.scm.repository.InternalRepositoryException; import sonia.scm.repository.Tag; import sonia.scm.repository.api.TagCreateRequest; @@ -37,6 +38,7 @@ import java.io.IOException; public class HgTagCommand extends AbstractCommand implements TagCommand { + public static final String DEFAULT_BRANCH_NAME = "default"; private final HgWorkingCopyFactory workingCopyFactory; public HgTagCommand(HgCommandContext context, HgWorkingCopyFactory workingCopyFactory) { @@ -46,7 +48,7 @@ public class HgTagCommand extends AbstractCommand implements TagCommand { @Override public Tag create(TagCreateRequest request) { - try (WorkingCopy workingCopy = workingCopyFactory.createWorkingCopy(getContext(), "default")) { + try (WorkingCopy workingCopy = workingCopyFactory.createWorkingCopy(getContext(), DEFAULT_BRANCH_NAME)) { Repository repository = getContext().open(); String rev = request.getRevision(); if (Strings.isNullOrEmpty(rev)) { @@ -54,22 +56,22 @@ public class HgTagCommand extends AbstractCommand implements TagCommand { } com.aragost.javahg.commands.TagCommand.on(workingCopy.getWorkingRepository()) .rev(rev) - .user("SCM-Manager") + .user(SecurityUtils.getSubject().getPrincipal().toString()) .execute(request.getName()); - pullChangesIntoCentralRepository(workingCopy, "default"); + pullChangesIntoCentralRepository(workingCopy, DEFAULT_BRANCH_NAME); return new Tag(request.getName(), rev); } } @Override public void delete(TagDeleteRequest request) { - try (WorkingCopy workingCopy = workingCopyFactory.createWorkingCopy(getContext(), "default")) { + try (WorkingCopy workingCopy = workingCopyFactory.createWorkingCopy(getContext(), DEFAULT_BRANCH_NAME)) { com.aragost.javahg.commands.TagCommand.on(workingCopy.getWorkingRepository()) - .user("SCM-Manager") + .user(SecurityUtils.getSubject().getPrincipal().toString()) .remove() .execute(request.getName()); - pullChangesIntoCentralRepository(workingCopy, "default"); + pullChangesIntoCentralRepository(workingCopy, DEFAULT_BRANCH_NAME); } } diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgTagsCommandTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgTagsCommandTest.java index afe3fe885d..e9bb65bf89 100644 --- a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgTagsCommandTest.java +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgTagsCommandTest.java @@ -24,34 +24,15 @@ package sonia.scm.repository.spi; -import com.aragost.javahg.commands.PullCommand; -import org.junit.Before; import org.junit.Test; import sonia.scm.repository.Tag; -import sonia.scm.repository.api.TagCommandBuilder; -import sonia.scm.repository.work.NoneCachingWorkingCopyPool; -import sonia.scm.repository.work.WorkdirProvider; -import java.io.IOException; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; public class HgTagsCommandTest extends AbstractHgCommandTestBase { - private SimpleHgWorkingCopyFactory workingCopyFactory; - - @Before - public void initWorkingCopyFactory() { - - workingCopyFactory = new SimpleHgWorkingCopyFactory(new NoneCachingWorkingCopyPool(new WorkdirProvider())) { - @Override - public void configure(PullCommand pullCommand) { - // we do not want to configure http hooks in this unit test - } - }; - } - @Test public void shouldGetTagDatesCorrectly() { HgTagsCommand hgTagsCommand = new HgTagsCommand(cmdContext); @@ -61,15 +42,4 @@ public class HgTagsCommandTest extends AbstractHgCommandTestBase { assertThat(tags.get(0).getDate()).contains(1339586381000L); } - @Test - public void shouldNotDie() throws IOException { - HgTagCommand hgTagCommand = new HgTagCommand(cmdContext, workingCopyFactory); - new TagCommandBuilder(hgTagCommand).create().setRevision("79b6baf49711").setName("newtag").execute(); - - HgTagsCommand hgTagsCommand = new HgTagsCommand(cmdContext); - final List tags = hgTagsCommand.getTags(); - - assertThat(tags).isNotEmpty(); - } - } diff --git a/scm-ui/ui-components/src/modals/CreateTagModal.tsx b/scm-ui/ui-components/src/modals/CreateTagModal.tsx index 304bca75a1..f94c1ab714 100644 --- a/scm-ui/ui-components/src/modals/CreateTagModal.tsx +++ b/scm-ui/ui-components/src/modals/CreateTagModal.tsx @@ -22,11 +22,11 @@ * SOFTWARE. */ -import React, {FC, useEffect, useState} from "react"; +import React, { FC, useEffect, useState } from "react"; import { Modal, InputField, Button, apiClient } from "@scm-manager/ui-components"; import { WithTranslation, withTranslation } from "react-i18next"; -import {Tag} from "@scm-manager/ui-types"; -import {isBranchValid} from "../validation"; +import { Tag } from "@scm-manager/ui-types"; +import { isBranchValid } from "../validation"; type Props = WithTranslation & { existingTagsLink: string; @@ -91,7 +91,12 @@ const CreateTagModal: FC = ({ t, onClose, tagCreationLink, existingTagsLi footer={ <> - diff --git a/scm-ui/ui-types/src/Tags.ts b/scm-ui/ui-types/src/Tags.ts index 41e9bb0c6c..b59ac7ca1c 100644 --- a/scm-ui/ui-types/src/Tags.ts +++ b/scm-ui/ui-types/src/Tags.ts @@ -23,7 +23,7 @@ */ import { Links } from "./hal"; -import {Signature} from "./Signature"; +import { Signature } from "./Signature"; export type Tag = { name: string; diff --git a/scm-ui/ui-webapp/public/locales/en/repos.json b/scm-ui/ui-webapp/public/locales/en/repos.json index b02759112f..363a062904 100644 --- a/scm-ui/ui-webapp/public/locales/en/repos.json +++ b/scm-ui/ui-webapp/public/locales/en/repos.json @@ -86,7 +86,7 @@ "delete": { "button": "Delete branch", "subtitle": "Delete branch", - "description": "Deleted branches can not be restored.", + "description": "Deleted branches cannot be restored.", "confirmAlert": { "title": "Delete branch", "message": "Do you really want to delete the branch \"{{branch}}\"?", diff --git a/scm-ui/ui-webapp/src/repos/components/changesets/ChangesetDetails.tsx b/scm-ui/ui-webapp/src/repos/components/changesets/ChangesetDetails.tsx index e2bb6d7a12..dd5b52955f 100644 --- a/scm-ui/ui-webapp/src/repos/components/changesets/ChangesetDetails.tsx +++ b/scm-ui/ui-webapp/src/repos/components/changesets/ChangesetDetails.tsx @@ -26,7 +26,7 @@ import { Trans, useTranslation, WithTranslation, withTranslation } from "react-i import classNames from "classnames"; import styled from "styled-components"; import { ExtensionPoint } from "@scm-manager/ui-extensions"; -import {Changeset, Link, ParentChangeset, Repository, Tag} from "@scm-manager/ui-types"; +import { Changeset, Link, ParentChangeset, Repository, Tag } from "@scm-manager/ui-types"; import { AvatarImage, AvatarWrapper, diff --git a/scm-ui/ui-webapp/src/repos/tags/components/TagRow.tsx b/scm-ui/ui-webapp/src/repos/tags/components/TagRow.tsx index 9b45816231..f1b601be81 100644 --- a/scm-ui/ui-webapp/src/repos/tags/components/TagRow.tsx +++ b/scm-ui/ui-webapp/src/repos/tags/components/TagRow.tsx @@ -33,6 +33,7 @@ type Props = { tag: Tag; baseUrl: string; onDelete: (tag: Tag) => void; + // deleting: boolean; }; const Created = styled.span` diff --git a/scm-ui/ui-webapp/src/repos/tags/components/TagTable.tsx b/scm-ui/ui-webapp/src/repos/tags/components/TagTable.tsx index 5778b346a9..c15753e9b8 100644 --- a/scm-ui/ui-webapp/src/repos/tags/components/TagTable.tsx +++ b/scm-ui/ui-webapp/src/repos/tags/components/TagTable.tsx @@ -22,11 +22,11 @@ * SOFTWARE. */ -import React, {FC, useState} from "react"; -import {Link, Tag} from "@scm-manager/ui-types"; +import React, { FC, useState } from "react"; +import { Link, Tag } from "@scm-manager/ui-types"; import { useTranslation } from "react-i18next"; import TagRow from "./TagRow"; -import {apiClient, ConfirmAlert, ErrorNotification} from "@scm-manager/ui-components"; +import { apiClient, ConfirmAlert, ErrorNotification } from "@scm-manager/ui-components"; type Props = { baseUrl: string; @@ -88,17 +88,18 @@ const TagTable: FC = ({ baseUrl, tags, fetchTags }) => { return ( <> - {showConfirmAlert && confirmAlert} - {error && } - - - - - - - {renderRow()} -
{t("tags.table.tags")}
- ); + {showConfirmAlert && confirmAlert} + {error && } + + + + + + + {renderRow()} +
{t("tags.table.tags")}
+ + ); }; export default TagTable; diff --git a/scm-ui/ui-webapp/src/repos/tags/container/TagsOverview.tsx b/scm-ui/ui-webapp/src/repos/tags/container/TagsOverview.tsx index e449358c3b..13a5c1e2ff 100644 --- a/scm-ui/ui-webapp/src/repos/tags/container/TagsOverview.tsx +++ b/scm-ui/ui-webapp/src/repos/tags/container/TagsOverview.tsx @@ -60,7 +60,7 @@ const TagsOverview: FC = ({ repository, baseUrl }) => { const renderTagsTable = () => { if (!loading && tags?.length > 0) { orderTags(tags); - return fetchTags()} />; + return ; } return {t("tags.overview.noTags")}; }; diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRequestDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRequestDto.java index 5d43914552..03a6e26dfa 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRequestDto.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRequestDto.java @@ -29,16 +29,20 @@ import lombok.Setter; import org.hibernate.validator.constraints.Length; import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.Pattern; + +import static sonia.scm.repository.Branch.VALID_BRANCH_NAMES; +import static sonia.scm.repository.Tag.VALID_REV; @Getter @Setter public class TagRequestDto { - // TODO: Validate revision via regex + @Pattern(regexp = VALID_REV) @NotEmpty @Length(min = 1, max = 100) private String revision; - // TODO: Validate name via regex + @Pattern(regexp = VALID_BRANCH_NAMES) @NotEmpty @Length(min = 1, max = 100) private String name; From f5106e864df1a7167d61e85d59d0864dc3d1f48f Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Tue, 1 Dec 2020 15:28:10 +0100 Subject: [PATCH 30/35] split hg tag command tests --- .../scm/repository/spi/HgTagCommandTest.java | 15 +++++++++------ .../scm/repository/spi/scm-hg-spi-test.zip | Bin 6972 -> 11834 bytes 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgTagCommandTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgTagCommandTest.java index e15d54dcb6..51c8b51b86 100644 --- a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgTagCommandTest.java +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgTagCommandTest.java @@ -55,18 +55,21 @@ public class HgTagCommandTest extends AbstractHgCommandTestBase { } @Test - public void shouldCreateAndDeleteTagCorrectly() { + public void shouldCreateTagCorrectly() { // Create - new HgTagCommand(cmdContext, workingCopyFactory).create(new TagCreateRequest("79b6baf49711", "newtag")); + new HgTagCommand(cmdContext, workingCopyFactory).create(new TagCreateRequest("79b6baf49711", "tagtag")); List tags = new HgTagsCommand(cmdContext).getTags(); - assertThat(tags).hasSize(2); + assertThat(tags).hasSize(4); final Tag newTag = tags.get(1); - assertThat(newTag.getName()).isEqualTo("newtag"); + assertThat(newTag.getName()).isEqualTo("tagtag"); + } + @Test + public void shouldDeleteTagCorrectly() { // Delete new HgTagCommand(cmdContext, workingCopyFactory).delete(new TagDeleteRequest("newtag")); - tags = new HgTagsCommand(cmdContext).getTags(); - assertThat(tags).hasSize(1); + List tags = new HgTagsCommand(cmdContext).getTags(); + assertThat(tags).hasSize(2); } } diff --git a/scm-plugins/scm-hg-plugin/src/test/resources/sonia/scm/repository/spi/scm-hg-spi-test.zip b/scm-plugins/scm-hg-plugin/src/test/resources/sonia/scm/repository/spi/scm-hg-spi-test.zip index 4896adc9de0d6189f13702c02e5e48520861ed9a..bbd2636962762affa6c05a6b351dd34d5c6967b9 100644 GIT binary patch literal 11834 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 Date: Tue, 1 Dec 2020 18:10:38 +0100 Subject: [PATCH 31/35] Fix minor issues --- .../scm/repository/spi/GitTagCommand.java | 73 ++++++++++--------- .../scm/repository/spi/HgModifyCommand.java | 4 +- .../scm/repository/spi/HgTagCommand.java | 7 +- .../scm/repository/spi/UserFormatter.java | 41 +++++++++++ 4 files changed, 86 insertions(+), 39 deletions(-) create mode 100644 scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/UserFormatter.java diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java index fda08d957b..0dc42922d2 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java @@ -35,7 +35,6 @@ import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevObject; import org.eclipse.jgit.revwalk.RevWalk; -import sonia.scm.NotFoundException; import sonia.scm.event.ScmEventBus; import sonia.scm.repository.GitUtil; import sonia.scm.repository.InternalRepositoryException; @@ -62,6 +61,8 @@ import java.util.Set; import static java.util.Collections.emptyList; import static java.util.Collections.singleton; import static java.util.Collections.singletonList; +import static sonia.scm.ContextEntry.ContextBuilder.entity; +import static sonia.scm.NotFoundException.notFound; public class GitTagCommand extends AbstractGitCommand implements TagCommand { private final GPG gpg; @@ -97,7 +98,7 @@ public class GitTagCommand extends AbstractGitCommand implements TagCommand { ObjectId taggedCommitObjectId = git.getRepository().resolve(revision); if (taggedCommitObjectId == null) { - throw new NotFoundException("revision", revision); + throw notFound(entity("revision", revision).in(repository)); } try (RevWalk walk = new RevWalk(git.getRepository())) { @@ -179,46 +180,46 @@ public class GitTagCommand extends AbstractGitCommand implements TagCommand { return new RepositoryHookEvent(context, this.context.getRepository(), RepositoryHookType.PRE_RECEIVE); } -private static class TagHookContextProvider extends HookContextProvider { - private final List newTags; - private final List deletedTags; + private static class TagHookContextProvider extends HookContextProvider { + private final List newTags; + private final List deletedTags; - private TagHookContextProvider(List newTags, List deletedTags) { - this.newTags = newTags; - this.deletedTags = deletedTags; - } + private TagHookContextProvider(List newTags, List deletedTags) { + this.newTags = newTags; + this.deletedTags = deletedTags; + } - static TagHookContextProvider createHookEvent(Tag newTag) { - return new TagHookContextProvider(singletonList(newTag), emptyList()); - } + static TagHookContextProvider createHookEvent(Tag newTag) { + return new TagHookContextProvider(singletonList(newTag), emptyList()); + } - static TagHookContextProvider deleteHookEvent(Tag deletedTag) { - return new TagHookContextProvider(emptyList(), singletonList(deletedTag)); - } + static TagHookContextProvider deleteHookEvent(Tag deletedTag) { + return new TagHookContextProvider(emptyList(), singletonList(deletedTag)); + } - @Override - public Set getSupportedFeatures() { - return singleton(HookFeature.TAG_PROVIDER); - } + @Override + public Set getSupportedFeatures() { + return singleton(HookFeature.TAG_PROVIDER); + } - @Override - public HookTagProvider getTagProvider() { - return new HookTagProvider() { - @Override - public List getCreatedTags() { - return newTags; - } + @Override + public HookTagProvider getTagProvider() { + return new HookTagProvider() { + @Override + public List getCreatedTags() { + return newTags; + } - @Override - public List getDeletedTags() { - return deletedTags; - } - }; - } + @Override + public List getDeletedTags() { + return deletedTags; + } + }; + } - @Override - public HookChangesetProvider getChangesetProvider() { - return r -> new HookChangesetResponse(emptyList()); + @Override + public HookChangesetProvider getChangesetProvider() { + return r -> new HookChangesetResponse(emptyList()); + } } } -} diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgModifyCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgModifyCommand.java index aaea12eeac..bbebd0449f 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgModifyCommand.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgModifyCommand.java @@ -43,6 +43,8 @@ import java.nio.file.Path; import java.util.List; import java.util.regex.Pattern; +import static sonia.scm.repository.spi.UserFormatter.getUserStringFor; + @SuppressWarnings("java:S3252") // it is ok for javahg classes to access static method of subtype public class HgModifyCommand implements ModifyCommand { @@ -110,7 +112,7 @@ public class HgModifyCommand implements ModifyCommand { LOG.trace("commit changes in working copy"); CommitCommand.on(workingRepository) - .user(String.format("%s <%s>", request.getAuthor().getName(), request.getAuthor().getMail())) + .user(getUserStringFor(request.getAuthor())) .message(request.getCommitMessage()).execute(); List execute = pullModifyChangesToCentralRepository(request, workingCopy); diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgTagCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgTagCommand.java index dc633bebf1..2feadabacf 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgTagCommand.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgTagCommand.java @@ -33,9 +33,12 @@ import sonia.scm.repository.Tag; import sonia.scm.repository.api.TagCreateRequest; import sonia.scm.repository.api.TagDeleteRequest; import sonia.scm.repository.work.WorkingCopy; +import sonia.scm.user.User; import java.io.IOException; +import static sonia.scm.repository.spi.UserFormatter.getUserStringFor; + public class HgTagCommand extends AbstractCommand implements TagCommand { public static final String DEFAULT_BRANCH_NAME = "default"; @@ -56,7 +59,7 @@ public class HgTagCommand extends AbstractCommand implements TagCommand { } com.aragost.javahg.commands.TagCommand.on(workingCopy.getWorkingRepository()) .rev(rev) - .user(SecurityUtils.getSubject().getPrincipal().toString()) + .user(getUserStringFor(SecurityUtils.getSubject().getPrincipals().oneByType(User.class))) .execute(request.getName()); pullChangesIntoCentralRepository(workingCopy, DEFAULT_BRANCH_NAME); return new Tag(request.getName(), rev); @@ -67,7 +70,7 @@ public class HgTagCommand extends AbstractCommand implements TagCommand { public void delete(TagDeleteRequest request) { try (WorkingCopy workingCopy = workingCopyFactory.createWorkingCopy(getContext(), DEFAULT_BRANCH_NAME)) { com.aragost.javahg.commands.TagCommand.on(workingCopy.getWorkingRepository()) - .user(SecurityUtils.getSubject().getPrincipal().toString()) + .user(getUserStringFor(SecurityUtils.getSubject().getPrincipals().oneByType(User.class))) .remove() .execute(request.getName()); diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/UserFormatter.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/UserFormatter.java new file mode 100644 index 0000000000..e48a62f7e0 --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/UserFormatter.java @@ -0,0 +1,41 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package sonia.scm.repository.spi; + +import sonia.scm.repository.Person; +import sonia.scm.user.User; + +final class UserFormatter { + private UserFormatter() { + } + + static String getUserStringFor(User user) { + return getUserStringFor(new Person(user.getName(), user.getMail())); + } + + static String getUserStringFor(Person person) { + return String.format("%s <%s>", person.getName(), person.getMail()); + } +} From 8e19fc641da5d328778faa05005c58b126bb3489 Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Tue, 1 Dec 2020 18:39:50 +0100 Subject: [PATCH 32/35] rework hg commands --- .../scm/repository/spi/AbstractCommand.java | 38 +---------- .../spi/AbstractWorkingCopyCommand.java | 64 +++++++++++++++++++ .../scm/repository/spi/HgBranchCommand.java | 18 +----- .../scm/repository/spi/HgModifyCommand.java | 29 ++------- .../scm/repository/spi/HgTagCommand.java | 22 +------ .../repository/spi/HgModifyCommandTest.java | 4 +- 6 files changed, 77 insertions(+), 98 deletions(-) create mode 100644 scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/AbstractWorkingCopyCommand.java diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/AbstractCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/AbstractCommand.java index f7d33b8973..f252bf3184 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/AbstractCommand.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/AbstractCommand.java @@ -35,60 +35,28 @@ import sonia.scm.repository.Repository; public class AbstractCommand { - /** - * Constructs ... - * - * @param context - * - */ + protected final HgCommandContext context; + protected final Repository repository; + public AbstractCommand(HgCommandContext context) { this.context = context; this.repository = context.getScmRepository(); } - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @return - */ public com.aragost.javahg.Repository open() { return context.open(); } - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @return - */ public HgCommandContext getContext() { return context; } - - /** - * Method description - * - * - * @return - */ public Repository getRepository() { return repository; } - //~--- fields --------------------------------------------------------------- - /** Field description */ - private HgCommandContext context; - - /** Field description */ - private Repository repository; } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/AbstractWorkingCopyCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/AbstractWorkingCopyCommand.java new file mode 100644 index 0000000000..48bd3beb12 --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/AbstractWorkingCopyCommand.java @@ -0,0 +1,64 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package sonia.scm.repository.spi; + +import com.aragost.javahg.Changeset; +import com.aragost.javahg.Repository; +import com.aragost.javahg.commands.ExecutionException; +import com.aragost.javahg.commands.PullCommand; +import sonia.scm.repository.InternalRepositoryException; +import sonia.scm.repository.work.WorkingCopy; + +import java.io.IOException; +import java.util.List; +import java.util.regex.Pattern; + +public class AbstractWorkingCopyCommand extends AbstractCommand { + static final Pattern HG_MESSAGE_PATTERN = Pattern.compile(".*\\[SCM\\](?: Error:)? (.*)"); + + protected final HgWorkingCopyFactory workingCopyFactory; + + public AbstractWorkingCopyCommand(HgCommandContext context, HgWorkingCopyFactory workingCopyFactory) + { + super(context); + this.workingCopyFactory = workingCopyFactory; + } + + protected List pullChangesIntoCentralRepository(WorkingCopy workingCopy, String branch) { + try { + com.aragost.javahg.commands.PullCommand pullCommand = PullCommand.on(workingCopy.getCentralRepository()); + workingCopyFactory.configure(pullCommand); + return pullCommand.execute(workingCopy.getDirectory().getAbsolutePath()); + } catch (ExecutionException e) { + throw IntegrateChangesFromWorkdirException + .withPattern(HG_MESSAGE_PATTERN) + .forMessage(context.getScmRepository(), e.getMessage()); + } catch (IOException e) { + throw new InternalRepositoryException(getRepository(), + String.format("Could not pull changes '%s' into central repository", branch), + e); + } + } +} diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgBranchCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgBranchCommand.java index 7319a312ff..af2386c076 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgBranchCommand.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgBranchCommand.java @@ -43,15 +43,12 @@ import java.io.IOException; * Mercurial implementation of the {@link BranchCommand}. * Note that this creates an empty commit to "persist" the new branch. */ -public class HgBranchCommand extends AbstractCommand implements BranchCommand { +public class HgBranchCommand extends AbstractWorkingCopyCommand implements BranchCommand { private static final Logger LOG = LoggerFactory.getLogger(HgBranchCommand.class); - private final HgWorkingCopyFactory workingCopyFactory; - HgBranchCommand(HgCommandContext context, HgWorkingCopyFactory workingCopyFactory) { - super(context); - this.workingCopyFactory = workingCopyFactory; + super(context, workingCopyFactory); } @Override @@ -103,15 +100,4 @@ public class HgBranchCommand extends AbstractCommand implements BranchCommand { .execute(); } - private void pullChangesIntoCentralRepository(WorkingCopy workingCopy, String branch) { - try { - PullCommand pullCommand = PullCommand.on(workingCopy.getCentralRepository()); - workingCopyFactory.configure(pullCommand); - pullCommand.execute(workingCopy.getDirectory().getAbsolutePath()); - } catch (IOException e) { - throw new InternalRepositoryException(getRepository(), - String.format("Could not pull changes '%s' into central repository", branch), - e); - } - } } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgModifyCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgModifyCommand.java index bbebd0449f..ef8a25ed9f 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgModifyCommand.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgModifyCommand.java @@ -46,17 +46,13 @@ import java.util.regex.Pattern; import static sonia.scm.repository.spi.UserFormatter.getUserStringFor; @SuppressWarnings("java:S3252") // it is ok for javahg classes to access static method of subtype -public class HgModifyCommand implements ModifyCommand { +public class HgModifyCommand extends AbstractWorkingCopyCommand implements ModifyCommand { private static final Logger LOG = LoggerFactory.getLogger(HgModifyCommand.class); - static final Pattern HG_MESSAGE_PATTERN = Pattern.compile(".*\\[SCM\\](?: Error:)? (.*)"); - private final HgCommandContext context; - private final HgWorkingCopyFactory workingCopyFactory; public HgModifyCommand(HgCommandContext context, HgWorkingCopyFactory workingCopyFactory) { - this.context = context; - this.workingCopyFactory = workingCopyFactory; + super(context, workingCopyFactory); } @Override @@ -115,7 +111,7 @@ public class HgModifyCommand implements ModifyCommand { .user(getUserStringFor(request.getAuthor())) .message(request.getCommitMessage()).execute(); - List execute = pullModifyChangesToCentralRepository(request, workingCopy); + List execute = pullChangesIntoCentralRepository(workingCopy, request.getBranch()); String node = execute.get(0).getNode(); LOG.debug("successfully pulled changes from working copy, new node {}", node); @@ -126,24 +122,7 @@ public class HgModifyCommand implements ModifyCommand { } } - private List pullModifyChangesToCentralRepository(ModifyCommandRequest request, WorkingCopy workingCopy) { - LOG.trace("pull changes from working copy"); - try { - com.aragost.javahg.commands.PullCommand pullCommand = PullCommand.on(workingCopy.getCentralRepository()); - workingCopyFactory.configure(pullCommand); - return pullCommand.execute(workingCopy.getDirectory().getAbsolutePath()); - } catch (ExecutionException e) { - throw IntegrateChangesFromWorkdirException - .withPattern(HG_MESSAGE_PATTERN) - .forMessage(context.getScmRepository(), e.getMessage()); - } catch (IOException e) { - throw new InternalRepositoryException(context.getScmRepository(), - String.format("Could not pull modify changes from working copy to central repository for branch %s", request.getBranch()), - e); - } - } - - private String throwInternalRepositoryException(String message, Exception e) { + private void throwInternalRepositoryException(String message, Exception e) { throw new InternalRepositoryException(context.getScmRepository(), message, e); } } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgTagCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgTagCommand.java index 2feadabacf..13459356fd 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgTagCommand.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgTagCommand.java @@ -25,28 +25,22 @@ package sonia.scm.repository.spi; import com.aragost.javahg.Repository; -import com.aragost.javahg.commands.PullCommand; import com.google.common.base.Strings; import org.apache.shiro.SecurityUtils; -import sonia.scm.repository.InternalRepositoryException; import sonia.scm.repository.Tag; import sonia.scm.repository.api.TagCreateRequest; import sonia.scm.repository.api.TagDeleteRequest; import sonia.scm.repository.work.WorkingCopy; import sonia.scm.user.User; -import java.io.IOException; - import static sonia.scm.repository.spi.UserFormatter.getUserStringFor; -public class HgTagCommand extends AbstractCommand implements TagCommand { +public class HgTagCommand extends AbstractWorkingCopyCommand implements TagCommand { public static final String DEFAULT_BRANCH_NAME = "default"; - private final HgWorkingCopyFactory workingCopyFactory; public HgTagCommand(HgCommandContext context, HgWorkingCopyFactory workingCopyFactory) { - super(context); - this.workingCopyFactory = workingCopyFactory; + super(context, workingCopyFactory); } @Override @@ -77,16 +71,4 @@ public class HgTagCommand extends AbstractCommand implements TagCommand { pullChangesIntoCentralRepository(workingCopy, DEFAULT_BRANCH_NAME); } } - - private void pullChangesIntoCentralRepository(WorkingCopy workingCopy, String branch) { - try { - com.aragost.javahg.commands.PullCommand pullCommand = PullCommand.on(workingCopy.getCentralRepository()); - workingCopyFactory.configure(pullCommand); - pullCommand.execute(workingCopy.getDirectory().getAbsolutePath()); - } catch (IOException e) { - throw new InternalRepositoryException(getRepository(), - String.format("Could not pull changes '%s' into central repository", branch), - e); - } - } } diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgModifyCommandTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgModifyCommandTest.java index 168d741bcb..e517a5f4a9 100644 --- a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgModifyCommandTest.java +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgModifyCommandTest.java @@ -184,14 +184,14 @@ public class HgModifyCommandTest extends AbstractHgCommandTestBase { @Test public void shouldExtractSimpleMessage() { - Matcher matcher = HgModifyCommand.HG_MESSAGE_PATTERN.matcher("[SCM] This is a simple message"); + Matcher matcher = AbstractWorkingCopyCommand.HG_MESSAGE_PATTERN.matcher("[SCM] This is a simple message"); matcher.matches(); assertThat(matcher.group(1)).isEqualTo("This is a simple message"); } @Test public void shouldExtractErrorMessage() { - Matcher matcher = HgModifyCommand.HG_MESSAGE_PATTERN.matcher("[SCM] Error: This is an error message"); + Matcher matcher = AbstractWorkingCopyCommand.HG_MESSAGE_PATTERN.matcher("[SCM] Error: This is an error message"); matcher.matches(); assertThat(matcher.group(1)).isEqualTo("This is an error message"); } From 0dbea12a62969d14708e36553a2982d6b068c947 Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Wed, 2 Dec 2020 08:54:21 +0100 Subject: [PATCH 33/35] Revert "split hg tag command tests" This reverts commit f5106e86 --- .../scm/repository/spi/HgTagCommandTest.java | 21 ++++++++---------- .../scm/repository/spi/scm-hg-spi-test.zip | Bin 11834 -> 6972 bytes 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgTagCommandTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgTagCommandTest.java index 51c8b51b86..e15d54dcb6 100644 --- a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgTagCommandTest.java +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgTagCommandTest.java @@ -55,21 +55,18 @@ public class HgTagCommandTest extends AbstractHgCommandTestBase { } @Test - public void shouldCreateTagCorrectly() { + public void shouldCreateAndDeleteTagCorrectly() { // Create - new HgTagCommand(cmdContext, workingCopyFactory).create(new TagCreateRequest("79b6baf49711", "tagtag")); - List tags = new HgTagsCommand(cmdContext).getTags(); - assertThat(tags).hasSize(4); - final Tag newTag = tags.get(1); - assertThat(newTag.getName()).isEqualTo("tagtag"); - } - - @Test - public void shouldDeleteTagCorrectly() { - // Delete - new HgTagCommand(cmdContext, workingCopyFactory).delete(new TagDeleteRequest("newtag")); + new HgTagCommand(cmdContext, workingCopyFactory).create(new TagCreateRequest("79b6baf49711", "newtag")); List tags = new HgTagsCommand(cmdContext).getTags(); assertThat(tags).hasSize(2); + final Tag newTag = tags.get(1); + assertThat(newTag.getName()).isEqualTo("newtag"); + + // Delete + new HgTagCommand(cmdContext, workingCopyFactory).delete(new TagDeleteRequest("newtag")); + tags = new HgTagsCommand(cmdContext).getTags(); + assertThat(tags).hasSize(1); } } diff --git a/scm-plugins/scm-hg-plugin/src/test/resources/sonia/scm/repository/spi/scm-hg-spi-test.zip b/scm-plugins/scm-hg-plugin/src/test/resources/sonia/scm/repository/spi/scm-hg-spi-test.zip index bbd2636962762affa6c05a6b351dd34d5c6967b9..4896adc9de0d6189f13702c02e5e48520861ed9a 100644 GIT binary patch literal 6972 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 Date: Wed, 2 Dec 2020 09:39:17 +0100 Subject: [PATCH 34/35] fix git tag command unit test --- .../scm/repository/spi/GitTagCommand.java | 12 +------- .../scm/repository/spi/GitTagCommandTest.java | 30 +++++++++++++++++-- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java index 0dc42922d2..4cf65af3c6 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java @@ -65,14 +65,12 @@ import static sonia.scm.ContextEntry.ContextBuilder.entity; import static sonia.scm.NotFoundException.notFound; public class GitTagCommand extends AbstractGitCommand implements TagCommand { - private final GPG gpg; private final HookContextFactory hookContextFactory; private final ScmEventBus eventBus; @Inject - GitTagCommand(GitContext context, GPG gpg, HookContextFactory hookContextFactory, ScmEventBus eventBus) { + GitTagCommand(GitContext context, HookContextFactory hookContextFactory, ScmEventBus eventBus) { super(context); - this.gpg = gpg; this.hookContextFactory = hookContextFactory; this.eventBus = eventBus; } @@ -114,20 +112,12 @@ public class GitTagCommand extends AbstractGitCommand implements TagCommand { User user = SecurityUtils.getSubject().getPrincipals().oneByType(User.class); PersonIdent taggerIdent = new PersonIdent(user.getDisplayName(), user.getMail()); -// Ref ref = git.tag() .setObjectId(revObject) .setTagger(taggerIdent) .setName(name) .call(); -// Uncomment lines once jgit added support for signing tags -// try (RevWalk walk = new RevWalk(git.getRepository())) { -// revObject = walk.parseTag(ref.getObjectId()); -// final Optional tagSignature = GitUtil.getTagSignature(revObject, gpg, walk); -// tagSignature.ifPresent(tag::addSignature); -// } - eventBus.post(new PostReceiveRepositoryHookEvent(hookEvent)); return tag; diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagCommandTest.java index 0225d40b5d..77178a3e4b 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagCommandTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitTagCommandTest.java @@ -24,7 +24,12 @@ package sonia.scm.repository.spi; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.mgt.DefaultSecurityManager; +import org.apache.shiro.subject.Subject; +import org.apache.shiro.util.ThreadContext; import org.eclipse.jgit.lib.GpgSigner; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -42,6 +47,7 @@ import sonia.scm.repository.api.HookContextFactory; import sonia.scm.repository.api.TagDeleteRequest; import sonia.scm.repository.api.TagCreateRequest; import sonia.scm.security.GPG; +import sonia.scm.util.MockUtil; import java.io.IOException; import java.util.List; @@ -65,16 +71,34 @@ public class GitTagCommandTest extends AbstractGitCommandTestBase { @Mock private ScmEventBus eventBus; + private Subject subject; + @Before public void setSigner() { GpgSigner.setDefault(new GitTestHelper.SimpleGpgSigner()); } + @Before + public void bindThreadContext() { + SecurityUtils.setSecurityManager(new DefaultSecurityManager()); + subject = MockUtil.createUserSubject(SecurityUtils.getSecurityManager()); + ThreadContext.bind(subject); + } + + @After + public void unbindThreadContext() { + ThreadContext.unbindSubject(); + ThreadContext.unbindSecurityManager(); + } + @Test public void shouldCreateATag() throws IOException { createCommand().create(new TagCreateRequest("592d797cd36432e591416e8b2b98154f4f163411", "newtag")); - Optional tag = findTag(createContext(), "newtag"); - assertThat(tag).isNotEmpty(); + Optional optionalTag = findTag(createContext(), "newtag"); + assertThat(optionalTag).isNotEmpty(); + final Tag tag = optionalTag.get(); + assertThat(tag.getName()).isEqualTo("newtag"); + assertThat(tag.getRevision()).isEqualTo("592d797cd36432e591416e8b2b98154f4f163411"); } @Test @@ -126,7 +150,7 @@ public class GitTagCommandTest extends AbstractGitCommandTestBase { } private GitTagCommand createCommand() { - return new GitTagCommand(createContext(), gpg, hookContextFactory, eventBus); + return new GitTagCommand(createContext(), hookContextFactory, eventBus); } private List readTags(GitContext context) throws IOException { From 967de2160c625d761b53b9e0870910cec51d1bbe Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Wed, 2 Dec 2020 10:11:53 +0100 Subject: [PATCH 35/35] fix sonarqube warnings --- .../src/main/java/sonia/scm/repository/GitUtil.java | 1 - .../src/main/java/sonia/scm/repository/spi/GitTagCommand.java | 1 - .../src/main/java/sonia/scm/repository/spi/GitTagsCommand.java | 3 --- .../main/java/sonia/scm/repository/spi/HgBranchCommand.java | 3 --- .../main/java/sonia/scm/repository/spi/HgModifyCommand.java | 2 -- .../sonia/scm/api/v2/resources/TagCollectionToDtoMapper.java | 3 --- .../main/java/sonia/scm/api/v2/resources/TagRootResource.java | 1 - .../java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java | 2 -- 8 files changed, 16 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java index 5c0b0315b7..ba7733a5a4 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java @@ -65,7 +65,6 @@ import javax.servlet.http.HttpServletRequest; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.util.Arrays; import java.util.Collections; import java.util.Map; import java.util.Optional; diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java index 4cf65af3c6..8e462e463a 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagCommand.java @@ -49,7 +49,6 @@ import sonia.scm.repository.api.HookFeature; import sonia.scm.repository.api.HookTagProvider; import sonia.scm.repository.api.TagCreateRequest; import sonia.scm.repository.api.TagDeleteRequest; -import sonia.scm.security.GPG; import sonia.scm.user.User; import javax.inject.Inject; diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagsCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagsCommand.java index e01e366ac6..f4b9358265 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagsCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagsCommand.java @@ -30,7 +30,6 @@ import com.google.common.base.Function; import com.google.common.collect.Lists; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; -import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; @@ -42,14 +41,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sonia.scm.repository.GitUtil; import sonia.scm.repository.InternalRepositoryException; -import sonia.scm.repository.Signature; import sonia.scm.repository.Tag; import sonia.scm.security.GPG; import javax.inject.Inject; import java.io.IOException; import java.util.List; -import java.util.Optional; //~--- JDK imports ------------------------------------------------------------ diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgBranchCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgBranchCommand.java index af2386c076..ed50580b72 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgBranchCommand.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgBranchCommand.java @@ -26,7 +26,6 @@ package sonia.scm.repository.spi; import com.aragost.javahg.Changeset; import com.aragost.javahg.commands.CommitCommand; -import com.aragost.javahg.commands.PullCommand; import org.apache.shiro.SecurityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,8 +36,6 @@ import sonia.scm.repository.api.BranchRequest; import sonia.scm.repository.work.WorkingCopy; import sonia.scm.user.User; -import java.io.IOException; - /** * Mercurial implementation of the {@link BranchCommand}. * Note that this creates an empty commit to "persist" the new branch. diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgModifyCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgModifyCommand.java index ef8a25ed9f..5a34f341f8 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgModifyCommand.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgModifyCommand.java @@ -28,7 +28,6 @@ import com.aragost.javahg.Changeset; import com.aragost.javahg.Repository; import com.aragost.javahg.commands.CommitCommand; import com.aragost.javahg.commands.ExecutionException; -import com.aragost.javahg.commands.PullCommand; import com.aragost.javahg.commands.RemoveCommand; import com.aragost.javahg.commands.StatusCommand; import org.slf4j.Logger; @@ -41,7 +40,6 @@ import java.io.File; import java.io.IOException; import java.nio.file.Path; import java.util.List; -import java.util.regex.Pattern; import static sonia.scm.repository.spi.UserFormatter.getUserStringFor; diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagCollectionToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagCollectionToDtoMapper.java index 99914ecc14..eed2446533 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagCollectionToDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagCollectionToDtoMapper.java @@ -28,9 +28,7 @@ import com.google.inject.Inject; import de.otto.edison.hal.Embedded; import de.otto.edison.hal.HalRepresentation; import de.otto.edison.hal.Links; -import sonia.scm.repository.NamespaceAndName; import sonia.scm.repository.Repository; -import sonia.scm.repository.RepositoryManager; import sonia.scm.repository.Tag; import java.util.Collection; @@ -42,7 +40,6 @@ import static java.util.stream.Collectors.toList; public class TagCollectionToDtoMapper { - private final ResourceLinks resourceLinks; private final TagToTagDtoMapper tagToTagDtoMapper; diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRootResource.java index 1d102a68b0..0f8e40c639 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRootResource.java @@ -32,7 +32,6 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import sonia.scm.NotFoundException; -import sonia.scm.repository.Branch; import sonia.scm.repository.NamespaceAndName; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryPermissions; diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java index 74b70037c4..290ad757aa 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java @@ -31,14 +31,12 @@ import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Named; import org.mapstruct.ObjectFactory; -import sonia.scm.repository.NamespaceAndName; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryPermissions; import sonia.scm.repository.Tag; import sonia.scm.web.EdisonHalAppender; import javax.inject.Inject; - import java.time.Instant; import java.util.Optional;