mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-07 22:15:45 +01:00
Merge with 2.0.0-m3
This commit is contained in:
@@ -77,7 +77,7 @@ public final class HookEventFacade
|
|||||||
Repository repository = repositoryManagerProvider.get().get(id);
|
Repository repository = repositoryManagerProvider.get().get(id);
|
||||||
if (repository == null)
|
if (repository == null)
|
||||||
{
|
{
|
||||||
throw notFound(entity("repository", id));
|
throw notFound(entity("Repository", id));
|
||||||
}
|
}
|
||||||
return handle(repository);
|
return handle(repository);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,6 @@
|
|||||||
"@scm-manager/ui-extensions": "^0.1.2"
|
"@scm-manager/ui-extensions": "^0.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@scm-manager/ui-bundler": "^0.0.25"
|
"@scm-manager/ui-bundler": "^0.0.26"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ public final class GitUtil
|
|||||||
}
|
}
|
||||||
catch (GitAPIException ex)
|
catch (GitAPIException ex)
|
||||||
{
|
{
|
||||||
throw new InternalRepositoryException(ContextEntry.ContextBuilder.entity("remote", directory.toString()).in(remoteRepository), "could not fetch", ex);
|
throw new InternalRepositoryException(ContextEntry.ContextBuilder.entity("Remote", directory.toString()).in(remoteRepository), "could not fetch", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ public class GitBlameCommand extends AbstractGitCommand implements BlameCommand
|
|||||||
|
|
||||||
if (gitBlameResult == null)
|
if (gitBlameResult == null)
|
||||||
{
|
{
|
||||||
throw new InternalRepositoryException(entity("path", request.getPath()).in(repository),
|
throw new InternalRepositoryException(entity("Path", request.getPath()).in(repository),
|
||||||
"could not create blame result for path");
|
"could not create blame result for path");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,9 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static sonia.scm.ContextEntry.ContextBuilder.entity;
|
||||||
|
import static sonia.scm.NotFoundException.notFound;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -128,10 +131,11 @@ public class GitBrowseCommand extends AbstractGitCommand
|
|||||||
if (Util.isNotEmpty(request.getRevision()))
|
if (Util.isNotEmpty(request.getRevision()))
|
||||||
{
|
{
|
||||||
logger.error("could not find revision {}", request.getRevision());
|
logger.error("could not find revision {}", request.getRevision());
|
||||||
|
throw notFound(entity("Revision", request.getRevision()).in(this.repository));
|
||||||
}
|
}
|
||||||
else if (logger.isWarnEnabled())
|
else if (logger.isWarnEnabled())
|
||||||
{
|
{
|
||||||
logger.warn("coul not find head of repository, empty?");
|
logger.warn("could not find head of repository, empty?");
|
||||||
}
|
}
|
||||||
|
|
||||||
result = new BrowserResult(Constants.HEAD, createEmtpyRoot());
|
result = new BrowserResult(Constants.HEAD, createEmtpyRoot());
|
||||||
@@ -354,7 +358,7 @@ public class GitBrowseCommand extends AbstractGitCommand
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new NotFoundException("file", request.getPath());
|
throw notFound(entity("File", request.getPath()).in("Revision", revId.getName()).in(this.repository));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ import org.eclipse.jgit.lib.Ref;
|
|||||||
import org.eclipse.jgit.lib.Repository;
|
import org.eclipse.jgit.lib.Repository;
|
||||||
import org.eclipse.jgit.revwalk.RevCommit;
|
import org.eclipse.jgit.revwalk.RevCommit;
|
||||||
import org.eclipse.jgit.revwalk.RevWalk;
|
import org.eclipse.jgit.revwalk.RevWalk;
|
||||||
import org.eclipse.jgit.revwalk.filter.RevFilter;
|
|
||||||
import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
|
import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
|
||||||
import org.eclipse.jgit.treewalk.filter.PathFilter;
|
import org.eclipse.jgit.treewalk.filter.PathFilter;
|
||||||
import org.eclipse.jgit.treewalk.filter.TreeFilter;
|
import org.eclipse.jgit.treewalk.filter.TreeFilter;
|
||||||
@@ -79,6 +78,7 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand
|
|||||||
*/
|
*/
|
||||||
private static final Logger logger =
|
private static final Logger logger =
|
||||||
LoggerFactory.getLogger(GitLogCommand.class);
|
LoggerFactory.getLogger(GitLogCommand.class);
|
||||||
|
public static final String REVISION = "Revision";
|
||||||
|
|
||||||
//~--- constructors ---------------------------------------------------------
|
//~--- constructors ---------------------------------------------------------
|
||||||
|
|
||||||
@@ -143,6 +143,10 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand
|
|||||||
{
|
{
|
||||||
logger.error("could not open repository", ex);
|
logger.error("could not open repository", ex);
|
||||||
}
|
}
|
||||||
|
catch (NullPointerException e)
|
||||||
|
{
|
||||||
|
throw notFound(entity(REVISION, revision).in(this.repository));
|
||||||
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
IOUtil.close(converter);
|
IOUtil.close(converter);
|
||||||
@@ -208,7 +212,7 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand
|
|||||||
if (!Strings.isNullOrEmpty(request.getAncestorChangeset())) {
|
if (!Strings.isNullOrEmpty(request.getAncestorChangeset())) {
|
||||||
ancestorId = repository.resolve(request.getAncestorChangeset());
|
ancestorId = repository.resolve(request.getAncestorChangeset());
|
||||||
if (ancestorId == null) {
|
if (ancestorId == null) {
|
||||||
throw notFound(entity("Revision", request.getAncestorChangeset()).in(this.repository));
|
throw notFound(entity(REVISION, request.getAncestorChangeset()).in(this.repository));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,7 +254,7 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (ancestorId != null) {
|
} else if (ancestorId != null) {
|
||||||
throw notFound(entity("Revision", request.getBranch()).in(this.repository));
|
throw notFound(entity(REVISION, request.getBranch()).in(this.repository));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (branch != null) {
|
if (branch != null) {
|
||||||
@@ -267,7 +271,7 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand
|
|||||||
}
|
}
|
||||||
catch (MissingObjectException e)
|
catch (MissingObjectException e)
|
||||||
{
|
{
|
||||||
throw notFound(entity("Revision", e.getObjectId().getName()).in(repository));
|
throw notFound(entity(REVISION, e.getObjectId().getName()).in(repository));
|
||||||
}
|
}
|
||||||
catch (NotFoundException e)
|
catch (NotFoundException e)
|
||||||
{
|
{
|
||||||
@@ -285,17 +289,4 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand
|
|||||||
|
|
||||||
return changesets;
|
return changesets;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ObjectId computeCommonAncestor(LogCommandRequest request, Repository repository, ObjectId startId, Ref branch) throws IOException {
|
|
||||||
try (RevWalk mergeBaseWalk = new RevWalk(repository)) {
|
|
||||||
mergeBaseWalk.setRevFilter(RevFilter.MERGE_BASE);
|
|
||||||
if (startId != null) {
|
|
||||||
mergeBaseWalk.markStart(mergeBaseWalk.lookupCommit(startId));
|
|
||||||
} else {
|
|
||||||
mergeBaseWalk.markStart(mergeBaseWalk.lookupCommit(branch.getObjectId()));
|
|
||||||
}
|
|
||||||
mergeBaseWalk.markStart(mergeBaseWalk.parseCommit(repository.resolve(request.getAncestorChangeset())));
|
|
||||||
return mergeBaseWalk.next().getId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ public class GitMergeCommand extends AbstractGitCommand implements MergeCommand
|
|||||||
private ObjectId resolveRevisionOrThrowNotFound(Repository repository, String revision) throws IOException {
|
private ObjectId resolveRevisionOrThrowNotFound(Repository repository, String revision) throws IOException {
|
||||||
ObjectId resolved = repository.resolve(revision);
|
ObjectId resolved = repository.resolve(revision);
|
||||||
if (resolved == null) {
|
if (resolved == null) {
|
||||||
throw notFound(entity("revision", revision).in(context.getRepository()));
|
throw notFound(entity("Revision", revision).in(context.getRepository()));
|
||||||
} else {
|
} else {
|
||||||
return resolved;
|
return resolved;
|
||||||
}
|
}
|
||||||
@@ -125,7 +125,7 @@ public class GitMergeCommand extends AbstractGitCommand implements MergeCommand
|
|||||||
clone.checkout().setStartPoint(targetRevision.getName()).setName(target).setCreateBranch(true).call();
|
clone.checkout().setStartPoint(targetRevision.getName()).setName(target).setCreateBranch(true).call();
|
||||||
} catch (RefNotFoundException e) {
|
} catch (RefNotFoundException e) {
|
||||||
logger.debug("could not checkout target branch {} for merge as local branch", target, e);
|
logger.debug("could not checkout target branch {} for merge as local branch", target, e);
|
||||||
throw notFound(entity("revision", target).in(context.getRepository()));
|
throw notFound(entity("Revision", target).in(context.getRepository()));
|
||||||
} catch (GitAPIException e) {
|
} catch (GitAPIException e) {
|
||||||
throw new InternalRepositoryException(context.getRepository(), "could not checkout target branch for merge as local branch: " + target, e);
|
throw new InternalRepositoryException(context.getRepository(), "could not checkout target branch for merge as local branch: " + target, e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -707,9 +707,9 @@
|
|||||||
version "0.0.2"
|
version "0.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85"
|
resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85"
|
||||||
|
|
||||||
"@scm-manager/ui-bundler@^0.0.25":
|
"@scm-manager/ui-bundler@^0.0.26":
|
||||||
version "0.0.25"
|
version "0.0.26"
|
||||||
resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.25.tgz#1f65b3ff0ae81559a114c6a8d8cf43856cc6e166"
|
resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.26.tgz#4676a7079b781b33fa1989c6643205c3559b1f66"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/core" "^7.0.0"
|
"@babel/core" "^7.0.0"
|
||||||
"@babel/plugin-proposal-class-properties" "^7.0.0"
|
"@babel/plugin-proposal-class-properties" "^7.0.0"
|
||||||
|
|||||||
@@ -9,6 +9,6 @@
|
|||||||
"@scm-manager/ui-extensions": "^0.1.2"
|
"@scm-manager/ui-extensions": "^0.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@scm-manager/ui-bundler": "^0.0.25"
|
"@scm-manager/ui-bundler": "^0.0.26"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -349,7 +349,7 @@ public class HgRepositoryHandler
|
|||||||
try {
|
try {
|
||||||
return new INIConfigurationReader().read(new File(directory, PATH_HGRC)).getSection(CONFIG_SECTION_SCMM).getParameter(CONFIG_KEY_REPOSITORY_ID);
|
return new INIConfigurationReader().read(new File(directory, PATH_HGRC)).getSection(CONFIG_SECTION_SCMM).getParameter(CONFIG_KEY_REPOSITORY_ID);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new InternalRepositoryException(ContextEntry.ContextBuilder.entity("directory", directory.toString()), "could not read scm configuration file", e);
|
throw new InternalRepositoryException(ContextEntry.ContextBuilder.entity("Directory", directory.toString()), "could not read scm configuration file", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -641,9 +641,9 @@
|
|||||||
version "0.0.2"
|
version "0.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85"
|
resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85"
|
||||||
|
|
||||||
"@scm-manager/ui-bundler@^0.0.25":
|
"@scm-manager/ui-bundler@^0.0.26":
|
||||||
version "0.0.25"
|
version "0.0.26"
|
||||||
resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.25.tgz#1f65b3ff0ae81559a114c6a8d8cf43856cc6e166"
|
resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.26.tgz#4676a7079b781b33fa1989c6643205c3559b1f66"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/core" "^7.0.0"
|
"@babel/core" "^7.0.0"
|
||||||
"@babel/plugin-proposal-class-properties" "^7.0.0"
|
"@babel/plugin-proposal-class-properties" "^7.0.0"
|
||||||
|
|||||||
@@ -9,6 +9,6 @@
|
|||||||
"@scm-manager/ui-extensions": "^0.1.2"
|
"@scm-manager/ui-extensions": "^0.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@scm-manager/ui-bundler": "^0.0.25"
|
"@scm-manager/ui-bundler": "^0.0.26"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ public class SvnRepositoryHandler
|
|||||||
try {
|
try {
|
||||||
return new INIConfigurationReader().read(new File(directory, CONFIG_FILE_NAME)).getSection(CONFIG_SECTION_SCMM).getParameter(CONFIG_KEY_REPOSITORY_ID);
|
return new INIConfigurationReader().read(new File(directory, CONFIG_FILE_NAME)).getSection(CONFIG_SECTION_SCMM).getParameter(CONFIG_KEY_REPOSITORY_ID);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new InternalRepositoryException(ContextEntry.ContextBuilder.entity("directory", directory.toString()), "could not read scm configuration file", e);
|
throw new InternalRepositoryException(ContextEntry.ContextBuilder.entity("Directory", directory.toString()), "could not read scm configuration file", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,10 @@ import sonia.scm.util.Util;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import static org.tmatesoft.svn.core.SVNErrorCode.FS_NO_SUCH_REVISION;
|
||||||
|
import static sonia.scm.ContextEntry.ContextBuilder.entity;
|
||||||
|
import static sonia.scm.NotFoundException.notFound;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -107,6 +111,9 @@ public class SvnBrowseCommand extends AbstractSvnCommand
|
|||||||
}
|
}
|
||||||
catch (SVNException ex)
|
catch (SVNException ex)
|
||||||
{
|
{
|
||||||
|
if (FS_NO_SUCH_REVISION.equals(ex.getErrorMessage().getErrorCode())) {
|
||||||
|
throw notFound(entity("Revision", Long.toString(revisionNumber)).in(this.repository));
|
||||||
|
}
|
||||||
logger.error("could not open repository", ex);
|
logger.error("could not open repository", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,6 +160,9 @@ public class SvnBrowseCommand extends AbstractSvnCommand
|
|||||||
private FileObject createFileObject(BrowseCommandRequest request,
|
private FileObject createFileObject(BrowseCommandRequest request,
|
||||||
SVNRepository repository, long revision, SVNDirEntry entry, String path)
|
SVNRepository repository, long revision, SVNDirEntry entry, String path)
|
||||||
{
|
{
|
||||||
|
if (entry == null) {
|
||||||
|
throw notFound(entity("Path", path).in("Revision", Long.toString(revision)).in(this.repository));
|
||||||
|
}
|
||||||
FileObject fileObject = new FileObject();
|
FileObject fileObject = new FileObject();
|
||||||
|
|
||||||
fileObject.setName(entry.getName());
|
fileObject.setName(entry.getName());
|
||||||
|
|||||||
@@ -641,9 +641,9 @@
|
|||||||
version "0.0.2"
|
version "0.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85"
|
resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85"
|
||||||
|
|
||||||
"@scm-manager/ui-bundler@^0.0.25":
|
"@scm-manager/ui-bundler@^0.0.26":
|
||||||
version "0.0.25"
|
version "0.0.26"
|
||||||
resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.25.tgz#1f65b3ff0ae81559a114c6a8d8cf43856cc6e166"
|
resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.26.tgz#4676a7079b781b33fa1989c6643205c3559b1f66"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/core" "^7.0.0"
|
"@babel/core" "^7.0.0"
|
||||||
"@babel/plugin-proposal-class-properties" "^7.0.0"
|
"@babel/plugin-proposal-class-properties" "^7.0.0"
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
"eslint-fix": "eslint src --fix"
|
"eslint-fix": "eslint src --fix"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@scm-manager/ui-bundler": "^0.0.25",
|
"@scm-manager/ui-bundler": "^0.0.26",
|
||||||
"create-index": "^2.3.0",
|
"create-index": "^2.3.0",
|
||||||
"enzyme": "^3.5.0",
|
"enzyme": "^3.5.0",
|
||||||
"enzyme-adapter-react-16": "^1.3.1",
|
"enzyme-adapter-react-16": "^1.3.1",
|
||||||
|
|||||||
@@ -4,6 +4,10 @@ import moment from "moment";
|
|||||||
import { translate } from "react-i18next";
|
import { translate } from "react-i18next";
|
||||||
import injectSheet from "react-jss";
|
import injectSheet from "react-jss";
|
||||||
|
|
||||||
|
// fix german locale
|
||||||
|
// https://momentjscom.readthedocs.io/en/latest/moment/00-use-it/07-browserify/
|
||||||
|
import "moment/locale/de";
|
||||||
|
|
||||||
const styles = {
|
const styles = {
|
||||||
date: {
|
date: {
|
||||||
borderBottom: "1px dotted rgba(219, 219, 219)",
|
borderBottom: "1px dotted rgba(219, 219, 219)",
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ import type { BackendErrorContent } from "./errors";
|
|||||||
const fetchOptions: RequestOptions = {
|
const fetchOptions: RequestOptions = {
|
||||||
credentials: "same-origin",
|
credentials: "same-origin",
|
||||||
headers: {
|
headers: {
|
||||||
Cache: "no-cache"
|
Cache: "no-cache",
|
||||||
|
// identify the request as ajax request
|
||||||
|
"X-Requested-With": "XMLHttpRequest"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -687,9 +687,9 @@
|
|||||||
version "0.0.2"
|
version "0.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85"
|
resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85"
|
||||||
|
|
||||||
"@scm-manager/ui-bundler@^0.0.25":
|
"@scm-manager/ui-bundler@^0.0.26":
|
||||||
version "0.0.25"
|
version "0.0.26"
|
||||||
resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.25.tgz#1f65b3ff0ae81559a114c6a8d8cf43856cc6e166"
|
resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.26.tgz#4676a7079b781b33fa1989c6643205c3559b1f66"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/core" "^7.0.0"
|
"@babel/core" "^7.0.0"
|
||||||
"@babel/plugin-proposal-class-properties" "^7.0.0"
|
"@babel/plugin-proposal-class-properties" "^7.0.0"
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
"check": "flow check"
|
"check": "flow check"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@scm-manager/ui-bundler": "^0.0.25"
|
"@scm-manager/ui-bundler": "^0.0.26"
|
||||||
},
|
},
|
||||||
"browserify": {
|
"browserify": {
|
||||||
"transform": [
|
"transform": [
|
||||||
|
|||||||
@@ -707,9 +707,9 @@
|
|||||||
version "0.0.2"
|
version "0.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85"
|
resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85"
|
||||||
|
|
||||||
"@scm-manager/ui-bundler@^0.0.25":
|
"@scm-manager/ui-bundler@^0.0.26":
|
||||||
version "0.0.25"
|
version "0.0.26"
|
||||||
resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.25.tgz#1f65b3ff0ae81559a114c6a8d8cf43856cc6e166"
|
resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.26.tgz#4676a7079b781b33fa1989c6643205c3559b1f66"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/core" "^7.0.0"
|
"@babel/core" "^7.0.0"
|
||||||
"@babel/plugin-proposal-class-properties" "^7.0.0"
|
"@babel/plugin-proposal-class-properties" "^7.0.0"
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
"pre-commit": "jest && flow && eslint src"
|
"pre-commit": "jest && flow && eslint src"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@scm-manager/ui-bundler": "^0.0.25",
|
"@scm-manager/ui-bundler": "^0.0.26",
|
||||||
"concat": "^1.0.3",
|
"concat": "^1.0.3",
|
||||||
"copyfiles": "^2.0.0",
|
"copyfiles": "^2.0.0",
|
||||||
"enzyme": "^3.3.0",
|
"enzyme": "^3.3.0",
|
||||||
|
|||||||
@@ -698,9 +698,9 @@
|
|||||||
version "0.0.2"
|
version "0.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85"
|
resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85"
|
||||||
|
|
||||||
"@scm-manager/ui-bundler@^0.0.25":
|
"@scm-manager/ui-bundler@^0.0.26":
|
||||||
version "0.0.25"
|
version "0.0.26"
|
||||||
resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.25.tgz#1f65b3ff0ae81559a114c6a8d8cf43856cc6e166"
|
resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.26.tgz#4676a7079b781b33fa1989c6643205c3559b1f66"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/core" "^7.0.0"
|
"@babel/core" "^7.0.0"
|
||||||
"@babel/plugin-proposal-class-properties" "^7.0.0"
|
"@babel/plugin-proposal-class-properties" "^7.0.0"
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ public class FileHistoryRootResource {
|
|||||||
} else {
|
} else {
|
||||||
String message = String.format("for the revision %s and the file %s there are no changesets", revision, path);
|
String message = String.format("for the revision %s and the file %s there are no changesets", revision, path);
|
||||||
log.error(message);
|
log.error(message);
|
||||||
throw notFound(entity("path", path).in("revision", revision).in(namespaceAndName));
|
throw notFound(entity("Path", path).in("revision", revision).in(namespaceAndName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -258,7 +258,7 @@ public class RepositoryPermissionRootResource {
|
|||||||
*/
|
*/
|
||||||
private void checkPermissionAlreadyExists(RepositoryPermissionDto permission, Repository repository) {
|
private void checkPermissionAlreadyExists(RepositoryPermissionDto permission, Repository repository) {
|
||||||
if (isPermissionExist(permission, repository)) {
|
if (isPermissionExist(permission, repository)) {
|
||||||
throw alreadyExists(entity("permission", permission.getName()).in(repository));
|
throw alreadyExists(entity("Permission", permission.getName()).in(repository));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ import javax.ws.rs.Produces;
|
|||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static sonia.scm.ContextEntry.ContextBuilder.entity;
|
||||||
|
import static sonia.scm.NotFoundException.notFound;
|
||||||
|
|
||||||
public class SourceRootResource {
|
public class SourceRootResource {
|
||||||
|
|
||||||
private final RepositoryServiceFactory serviceFactory;
|
private final RepositoryServiceFactory serviceFactory;
|
||||||
@@ -62,7 +65,7 @@ public class SourceRootResource {
|
|||||||
if (browserResult != null) {
|
if (browserResult != null) {
|
||||||
return Response.ok(browserResultToFileObjectDtoMapper.map(browserResult, namespaceAndName)).build();
|
return Response.ok(browserResultToFileObjectDtoMapper.map(browserResult, namespaceAndName)).build();
|
||||||
} else {
|
} else {
|
||||||
return Response.status(Response.Status.NOT_FOUND).build();
|
throw notFound(entity("Source", path).in("Revision", revision).in(namespaceAndName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ public class PermissionAssigner {
|
|||||||
private Predicate<PermissionDescriptor> permissionExists(Collection<PermissionDescriptor> availablePermissions, Collection<AssignedPermission> existingPermissions) {
|
private Predicate<PermissionDescriptor> permissionExists(Collection<PermissionDescriptor> availablePermissions, Collection<AssignedPermission> existingPermissions) {
|
||||||
return p -> {
|
return p -> {
|
||||||
if (!availablePermissions.contains(p) && existingPermissions.stream().map(AssignedPermission::getPermission).noneMatch(e -> e.equals(p))) {
|
if (!availablePermissions.contains(p) && existingPermissions.stream().map(AssignedPermission::getPermission).noneMatch(e -> e.equals(p))) {
|
||||||
throw NotFoundException.notFound(ContextEntry.ContextBuilder.entity("permission", p.getValue()));
|
throw NotFoundException.notFound(ContextEntry.ContextBuilder.entity("Permission", p.getValue()));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -403,7 +403,7 @@ public class DefaultUserManager extends AbstractUserManager
|
|||||||
User user = get((String) SecurityUtils.getSubject().getPrincipals().getPrimaryPrincipal());
|
User user = get((String) SecurityUtils.getSubject().getPrincipals().getPrimaryPrincipal());
|
||||||
|
|
||||||
if (!user.getPassword().equals(oldPassword)) {
|
if (!user.getPassword().equals(oldPassword)) {
|
||||||
throw new InvalidPasswordException(ContextEntry.ContextBuilder.entity("passwordChange", "-").in(User.class, user.getName()));
|
throw new InvalidPasswordException(ContextEntry.ContextBuilder.entity("PasswordChange", "-").in(User.class, user.getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
user.setPassword(newPassword);
|
user.setPassword(newPassword);
|
||||||
@@ -422,7 +422,7 @@ public class DefaultUserManager extends AbstractUserManager
|
|||||||
throw new NotFoundException(User.class, userId);
|
throw new NotFoundException(User.class, userId);
|
||||||
}
|
}
|
||||||
if (!isTypeDefault(user)) {
|
if (!isTypeDefault(user)) {
|
||||||
throw new ChangePasswordNotAllowedException(ContextEntry.ContextBuilder.entity("passwordChange", "-").in(User.class, user.getName()), user.getType());
|
throw new ChangePasswordNotAllowedException(ContextEntry.ContextBuilder.entity("PasswordChange", "-").in(User.class, user.getName()), user.getType());
|
||||||
}
|
}
|
||||||
user.setPassword(newPassword);
|
user.setPassword(newPassword);
|
||||||
this.modify(user);
|
this.modify(user);
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package sonia.scm.web.filter;
|
package sonia.scm.web.filter;
|
||||||
|
|
||||||
import sonia.scm.Priority;
|
import sonia.scm.Priority;
|
||||||
import sonia.scm.PushStateDispatcher;
|
|
||||||
import sonia.scm.config.ScmConfiguration;
|
import sonia.scm.config.ScmConfiguration;
|
||||||
import sonia.scm.filter.Filters;
|
import sonia.scm.filter.Filters;
|
||||||
import sonia.scm.filter.WebElement;
|
import sonia.scm.filter.WebElement;
|
||||||
@@ -12,6 +11,8 @@ import sonia.scm.web.WebTokenGenerator;
|
|||||||
import sonia.scm.web.protocol.HttpProtocolServlet;
|
import sonia.scm.web.protocol.HttpProtocolServlet;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -21,25 +22,23 @@ import java.util.Set;
|
|||||||
@WebElement(value = HttpProtocolServlet.PATTERN)
|
@WebElement(value = HttpProtocolServlet.PATTERN)
|
||||||
public class HttpProtocolServletAuthenticationFilter extends AuthenticationFilter {
|
public class HttpProtocolServletAuthenticationFilter extends AuthenticationFilter {
|
||||||
|
|
||||||
private final PushStateDispatcher dispatcher;
|
|
||||||
private final UserAgentParser userAgentParser;
|
private final UserAgentParser userAgentParser;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public HttpProtocolServletAuthenticationFilter(
|
public HttpProtocolServletAuthenticationFilter(
|
||||||
ScmConfiguration configuration,
|
ScmConfiguration configuration,
|
||||||
Set<WebTokenGenerator> tokenGenerators,
|
Set<WebTokenGenerator> tokenGenerators,
|
||||||
PushStateDispatcher dispatcher,
|
|
||||||
UserAgentParser userAgentParser) {
|
UserAgentParser userAgentParser) {
|
||||||
super(configuration, tokenGenerators);
|
super(configuration, tokenGenerators);
|
||||||
this.dispatcher = dispatcher;
|
|
||||||
this.userAgentParser = userAgentParser;
|
this.userAgentParser = userAgentParser;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void sendUnauthorizedError(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
protected void handleUnauthorized(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||||
UserAgent userAgent = userAgentParser.parse(request);
|
UserAgent userAgent = userAgentParser.parse(request);
|
||||||
if (userAgent.isBrowser()) {
|
if (userAgent.isBrowser()) {
|
||||||
dispatcher.dispatch(request, response, request.getRequestURI());
|
// we can proceed the filter chain because the HttpProtocolServlet will render the ui if the client is a browser
|
||||||
|
chain.doFilter(request, response);
|
||||||
} else {
|
} else {
|
||||||
HttpUtil.sendUnauthorized(request, response);
|
HttpUtil.sendUnauthorized(request, response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package sonia.scm.web.filter;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
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.config.ScmConfiguration;
|
||||||
|
import sonia.scm.util.HttpUtil;
|
||||||
|
import sonia.scm.web.UserAgent;
|
||||||
|
import sonia.scm.web.UserAgentParser;
|
||||||
|
import sonia.scm.web.WebTokenGenerator;
|
||||||
|
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class HttpProtocolServletAuthenticationFilterTest {
|
||||||
|
|
||||||
|
private ScmConfiguration configuration = new ScmConfiguration();
|
||||||
|
|
||||||
|
private Set<WebTokenGenerator> tokenGenerators = Collections.emptySet();
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private UserAgentParser userAgentParser;
|
||||||
|
|
||||||
|
private HttpProtocolServletAuthenticationFilter authenticationFilter;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private HttpServletRequest request;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private HttpServletResponse response;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private FilterChain filterChain;
|
||||||
|
|
||||||
|
private UserAgent nonBrowser = UserAgent.builder("i'm not a browser").browser(false).build();
|
||||||
|
private UserAgent browser = UserAgent.builder("i am a browser").browser(true).build();
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUpObjectUnderTest() {
|
||||||
|
authenticationFilter = new HttpProtocolServletAuthenticationFilter(configuration, tokenGenerators, userAgentParser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldSendUnauthorized() throws IOException, ServletException {
|
||||||
|
when(userAgentParser.parse(request)).thenReturn(nonBrowser);
|
||||||
|
|
||||||
|
authenticationFilter.handleUnauthorized(request, response, filterChain);
|
||||||
|
|
||||||
|
verify(response).sendError(HttpServletResponse.SC_UNAUTHORIZED, HttpUtil.STATUS_UNAUTHORIZED_MESSAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldCallFilterChain() throws IOException, ServletException {
|
||||||
|
when(userAgentParser.parse(request)).thenReturn(browser);
|
||||||
|
|
||||||
|
authenticationFilter.handleUnauthorized(request, response, filterChain);
|
||||||
|
|
||||||
|
verify(filterChain).doFilter(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user