Search in sources :

Example 31 with BadRequestException

use of com.google.gerrit.extensions.restapi.BadRequestException in project gerrit by GerritCodeReview.

the class RestApiServlet method service.

@Override
protected final void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
    final long startNanos = System.nanoTime();
    long auditStartTs = TimeUtil.nowMs();
    res.setHeader("Content-Disposition", "attachment");
    res.setHeader("X-Content-Type-Options", "nosniff");
    int status = SC_OK;
    long responseBytes = -1;
    Object result = null;
    ListMultimap<String, String> params = MultimapBuilder.hashKeys().arrayListValues().build();
    ListMultimap<String, String> config = MultimapBuilder.hashKeys().arrayListValues().build();
    Object inputRequestBody = null;
    RestResource rsrc = TopLevelResource.INSTANCE;
    ViewData viewData = null;
    try {
        if (isCorsPreflight(req)) {
            doCorsPreflight(req, res);
            return;
        }
        checkCors(req, res);
        checkUserSession(req);
        ParameterParser.splitQueryString(req.getQueryString(), config, params);
        List<IdString> path = splitPath(req);
        RestCollection<RestResource, RestResource> rc = members.get();
        globals.permissionBackend.user(globals.currentUser).checkAny(GlobalPermission.fromAnnotation(rc.getClass()));
        viewData = new ViewData(null, null);
        if (path.isEmpty()) {
            if (rc instanceof NeedsParams) {
                ((NeedsParams) rc).setParams(params);
            }
            if (isRead(req)) {
                viewData = new ViewData(null, rc.list());
            } else if (rc instanceof AcceptsPost && "POST".equals(req.getMethod())) {
                @SuppressWarnings("unchecked") AcceptsPost<RestResource> ac = (AcceptsPost<RestResource>) rc;
                viewData = new ViewData(null, ac.post(rsrc));
            } else {
                throw new MethodNotAllowedException();
            }
        } else {
            IdString id = path.remove(0);
            try {
                rsrc = rc.parse(rsrc, id);
                if (path.isEmpty()) {
                    checkPreconditions(req);
                }
            } catch (ResourceNotFoundException e) {
                if (rc instanceof AcceptsCreate && path.isEmpty() && ("POST".equals(req.getMethod()) || "PUT".equals(req.getMethod()))) {
                    @SuppressWarnings("unchecked") AcceptsCreate<RestResource> ac = (AcceptsCreate<RestResource>) rc;
                    viewData = new ViewData(null, ac.create(rsrc, id));
                    status = SC_CREATED;
                } else {
                    throw e;
                }
            }
            if (viewData.view == null) {
                viewData = view(rsrc, rc, req.getMethod(), path);
            }
        }
        checkRequiresCapability(viewData);
        while (viewData.view instanceof RestCollection<?, ?>) {
            @SuppressWarnings("unchecked") RestCollection<RestResource, RestResource> c = (RestCollection<RestResource, RestResource>) viewData.view;
            if (path.isEmpty()) {
                if (isRead(req)) {
                    viewData = new ViewData(null, c.list());
                } else if (c instanceof AcceptsPost && "POST".equals(req.getMethod())) {
                    @SuppressWarnings("unchecked") AcceptsPost<RestResource> ac = (AcceptsPost<RestResource>) c;
                    viewData = new ViewData(null, ac.post(rsrc));
                } else if (c instanceof AcceptsDelete && "DELETE".equals(req.getMethod())) {
                    @SuppressWarnings("unchecked") AcceptsDelete<RestResource> ac = (AcceptsDelete<RestResource>) c;
                    viewData = new ViewData(null, ac.delete(rsrc, null));
                } else {
                    throw new MethodNotAllowedException();
                }
                break;
            }
            IdString id = path.remove(0);
            try {
                rsrc = c.parse(rsrc, id);
                checkPreconditions(req);
                viewData = new ViewData(null, null);
            } catch (ResourceNotFoundException e) {
                if (c instanceof AcceptsCreate && path.isEmpty() && ("POST".equals(req.getMethod()) || "PUT".equals(req.getMethod()))) {
                    @SuppressWarnings("unchecked") AcceptsCreate<RestResource> ac = (AcceptsCreate<RestResource>) c;
                    viewData = new ViewData(viewData.pluginName, ac.create(rsrc, id));
                    status = SC_CREATED;
                } else if (c instanceof AcceptsDelete && path.isEmpty() && "DELETE".equals(req.getMethod())) {
                    @SuppressWarnings("unchecked") AcceptsDelete<RestResource> ac = (AcceptsDelete<RestResource>) c;
                    viewData = new ViewData(viewData.pluginName, ac.delete(rsrc, id));
                    status = SC_NO_CONTENT;
                } else {
                    throw e;
                }
            }
            if (viewData.view == null) {
                viewData = view(rsrc, c, req.getMethod(), path);
            }
            checkRequiresCapability(viewData);
        }
        if (notModified(req, rsrc, viewData.view)) {
            res.sendError(SC_NOT_MODIFIED);
            return;
        }
        if (!globals.paramParser.get().parse(viewData.view, params, req, res)) {
            return;
        }
        if (viewData.view instanceof RestReadView<?> && isRead(req)) {
            result = ((RestReadView<RestResource>) viewData.view).apply(rsrc);
        } else if (viewData.view instanceof RestModifyView<?, ?>) {
            @SuppressWarnings("unchecked") RestModifyView<RestResource, Object> m = (RestModifyView<RestResource, Object>) viewData.view;
            Type type = inputType(m);
            inputRequestBody = parseRequest(req, type);
            result = m.apply(rsrc, inputRequestBody);
            consumeRawInputRequestBody(req, type);
        } else {
            throw new ResourceNotFoundException();
        }
        if (result instanceof Response) {
            @SuppressWarnings("rawtypes") Response<?> r = (Response) result;
            status = r.statusCode();
            configureCaching(req, res, rsrc, viewData.view, r.caching());
        } else if (result instanceof Response.Redirect) {
            CacheHeaders.setNotCacheable(res);
            res.sendRedirect(((Response.Redirect) result).location());
            return;
        } else if (result instanceof Response.Accepted) {
            CacheHeaders.setNotCacheable(res);
            res.setStatus(SC_ACCEPTED);
            res.setHeader(HttpHeaders.LOCATION, ((Response.Accepted) result).location());
            return;
        } else {
            CacheHeaders.setNotCacheable(res);
        }
        res.setStatus(status);
        if (result != Response.none()) {
            result = Response.unwrap(result);
            if (result instanceof BinaryResult) {
                responseBytes = replyBinaryResult(req, res, (BinaryResult) result);
            } else {
                responseBytes = replyJson(req, res, config, result);
            }
        }
    } catch (MalformedJsonException e) {
        responseBytes = replyError(req, res, status = SC_BAD_REQUEST, "Invalid " + JSON_TYPE + " in request", e);
    } catch (JsonParseException e) {
        responseBytes = replyError(req, res, status = SC_BAD_REQUEST, "Invalid " + JSON_TYPE + " in request", e);
    } catch (BadRequestException e) {
        responseBytes = replyError(req, res, status = SC_BAD_REQUEST, messageOr(e, "Bad Request"), e.caching(), e);
    } catch (AuthException e) {
        responseBytes = replyError(req, res, status = SC_FORBIDDEN, messageOr(e, "Forbidden"), e.caching(), e);
    } catch (AmbiguousViewException e) {
        responseBytes = replyError(req, res, status = SC_NOT_FOUND, messageOr(e, "Ambiguous"), e);
    } catch (ResourceNotFoundException e) {
        responseBytes = replyError(req, res, status = SC_NOT_FOUND, messageOr(e, "Not Found"), e.caching(), e);
    } catch (MethodNotAllowedException e) {
        responseBytes = replyError(req, res, status = SC_METHOD_NOT_ALLOWED, messageOr(e, "Method Not Allowed"), e.caching(), e);
    } catch (ResourceConflictException e) {
        responseBytes = replyError(req, res, status = SC_CONFLICT, messageOr(e, "Conflict"), e.caching(), e);
    } catch (PreconditionFailedException e) {
        responseBytes = replyError(req, res, status = SC_PRECONDITION_FAILED, messageOr(e, "Precondition Failed"), e.caching(), e);
    } catch (UnprocessableEntityException e) {
        responseBytes = replyError(req, res, status = SC_UNPROCESSABLE_ENTITY, messageOr(e, "Unprocessable Entity"), e.caching(), e);
    } catch (NotImplementedException e) {
        responseBytes = replyError(req, res, status = SC_NOT_IMPLEMENTED, messageOr(e, "Not Implemented"), e);
    } catch (Exception e) {
        status = SC_INTERNAL_SERVER_ERROR;
        responseBytes = handleException(e, req, res);
    } finally {
        String metric = viewData != null && viewData.view != null ? globals.metrics.view(viewData) : "_unknown";
        globals.metrics.count.increment(metric);
        if (status >= SC_BAD_REQUEST) {
            globals.metrics.errorCount.increment(metric, status);
        }
        if (responseBytes != -1) {
            globals.metrics.responseBytes.record(metric, responseBytes);
        }
        globals.metrics.serverLatency.record(metric, System.nanoTime() - startNanos, TimeUnit.NANOSECONDS);
        globals.auditService.dispatch(new ExtendedHttpAuditEvent(globals.webSession.get().getSessionId(), globals.currentUser.get(), req, auditStartTs, params, inputRequestBody, status, result, rsrc, viewData == null ? null : viewData.view));
    }
}
Also used : RestCollection(com.google.gerrit.extensions.restapi.RestCollection) RestResource(com.google.gerrit.extensions.restapi.RestResource) AcceptsDelete(com.google.gerrit.extensions.restapi.AcceptsDelete) NotImplementedException(com.google.gerrit.extensions.restapi.NotImplementedException) AuthException(com.google.gerrit.extensions.restapi.AuthException) ExtendedHttpAuditEvent(com.google.gerrit.audit.ExtendedHttpAuditEvent) IdString(com.google.gerrit.extensions.restapi.IdString) JsonParseException(com.google.gson.JsonParseException) PreconditionFailedException(com.google.gerrit.extensions.restapi.PreconditionFailedException) ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) MalformedJsonException(com.google.gson.stream.MalformedJsonException) UnprocessableEntityException(com.google.gerrit.extensions.restapi.UnprocessableEntityException) RestModifyView(com.google.gerrit.extensions.restapi.RestModifyView) MethodNotAllowedException(com.google.gerrit.extensions.restapi.MethodNotAllowedException) AcceptsPost(com.google.gerrit.extensions.restapi.AcceptsPost) ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) InvocationTargetException(java.lang.reflect.InvocationTargetException) PermissionBackendException(com.google.gerrit.server.permissions.PermissionBackendException) UnprocessableEntityException(com.google.gerrit.extensions.restapi.UnprocessableEntityException) RestApiException(com.google.gerrit.extensions.restapi.RestApiException) PreconditionFailedException(com.google.gerrit.extensions.restapi.PreconditionFailedException) IOException(java.io.IOException) MalformedJsonException(com.google.gson.stream.MalformedJsonException) ServletException(javax.servlet.ServletException) AuthException(com.google.gerrit.extensions.restapi.AuthException) MethodNotAllowedException(com.google.gerrit.extensions.restapi.MethodNotAllowedException) EOFException(java.io.EOFException) JsonParseException(com.google.gson.JsonParseException) NotImplementedException(com.google.gerrit.extensions.restapi.NotImplementedException) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) Response(com.google.gerrit.extensions.restapi.Response) HttpServletResponse(javax.servlet.http.HttpServletResponse) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) IdString(com.google.gerrit.extensions.restapi.IdString) AcceptsCreate(com.google.gerrit.extensions.restapi.AcceptsCreate) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) NeedsParams(com.google.gerrit.extensions.restapi.NeedsParams) BinaryResult(com.google.gerrit.extensions.restapi.BinaryResult)

Example 32 with BadRequestException

use of com.google.gerrit.extensions.restapi.BadRequestException in project gerrit by GerritCodeReview.

the class RestApiServlet method parseString.

private Object parseString(String value, Type type) throws BadRequestException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InstantiationException, InvocationTargetException {
    if (type == String.class) {
        return value;
    }
    Object obj = createInstance(type);
    Field[] fields = obj.getClass().getDeclaredFields();
    if (fields.length == 0 && Strings.isNullOrEmpty(value)) {
        return obj;
    }
    for (Field f : fields) {
        if (f.getAnnotation(DefaultInput.class) != null && f.getType() == String.class) {
            f.setAccessible(true);
            f.set(obj, value);
            return obj;
        }
    }
    throw new BadRequestException("Expected JSON object");
}
Also used : Field(java.lang.reflect.Field) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) IdString(com.google.gerrit.extensions.restapi.IdString)

Example 33 with BadRequestException

use of com.google.gerrit.extensions.restapi.BadRequestException in project gerrit by GerritCodeReview.

the class RestApiServlet method parseRequest.

private Object parseRequest(HttpServletRequest req, Type type) throws IOException, BadRequestException, SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException, MethodNotAllowedException {
    // 400). Consume the request body for all but raw input request types here.
    if (isType(JSON_TYPE, req.getContentType())) {
        try (BufferedReader br = req.getReader();
            JsonReader json = new JsonReader(br)) {
            try {
                json.setLenient(true);
                JsonToken first;
                try {
                    first = json.peek();
                } catch (EOFException e) {
                    throw new BadRequestException("Expected JSON object");
                }
                if (first == JsonToken.STRING) {
                    return parseString(json.nextString(), type);
                }
                return OutputFormat.JSON.newGson().fromJson(json, type);
            } finally {
                // Reader.close won't consume the rest of the input. Explicitly consume the request body.
                br.skip(Long.MAX_VALUE);
            }
        }
    } else if (rawInputRequest(req, type)) {
        return parseRawInput(req, type);
    } else if ("DELETE".equals(req.getMethod()) && hasNoBody(req)) {
        return null;
    } else if (hasNoBody(req)) {
        return createInstance(type);
    } else if (isType("text/plain", req.getContentType())) {
        try (BufferedReader br = req.getReader()) {
            char[] tmp = new char[256];
            StringBuilder sb = new StringBuilder();
            int n;
            while (0 < (n = br.read(tmp))) {
                sb.append(tmp, 0, n);
            }
            return parseString(sb.toString(), type);
        }
    } else if ("POST".equals(req.getMethod()) && isType(FORM_TYPE, req.getContentType())) {
        return OutputFormat.JSON.newGson().fromJson(ParameterParser.formToJson(req), type);
    } else {
        throw new BadRequestException("Expected Content-Type: " + JSON_TYPE);
    }
}
Also used : BufferedReader(java.io.BufferedReader) EOFException(java.io.EOFException) JsonReader(com.google.gson.stream.JsonReader) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) JsonToken(com.google.gson.stream.JsonToken)

Example 34 with BadRequestException

use of com.google.gerrit.extensions.restapi.BadRequestException in project gerrit by GerritCodeReview.

the class AccountIT method addInvalidEmail.

@Test
public void addInvalidEmail() throws Exception {
    List<String> emails = ImmutableList.of(// Missing domain part
    "new.email", // Missing domain part
    "new.email@", // Missing user part
    "@example.com", // Non-supported TLD  (see tlds-alpha-by-domain.txt)
    "new.email@example.africa");
    for (String email : emails) {
        EmailInput input = new EmailInput();
        input.email = email;
        input.noConfirmation = true;
        try {
            gApi.accounts().self().addEmail(input);
            fail("Expected BadRequestException for invalid email address: " + email);
        } catch (BadRequestException e) {
            assertThat(e).hasMessageThat().isEqualTo("invalid email address");
        }
    }
    accountIndexedCounter.assertNoReindex();
}
Also used : BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) PublicKeyStore.keyToString(com.google.gerrit.gpg.PublicKeyStore.keyToString) EmailInput(com.google.gerrit.extensions.api.accounts.EmailInput) AbstractDaemonTest(com.google.gerrit.acceptance.AbstractDaemonTest) Test(org.junit.Test)

Example 35 with BadRequestException

use of com.google.gerrit.extensions.restapi.BadRequestException in project gerrit by GerritCodeReview.

the class PostGpgKeys method apply.

@Override
public Map<String, GpgKeyInfo> apply(AccountResource rsrc, Input input) throws ResourceNotFoundException, BadRequestException, ResourceConflictException, PGPException, OrmException, IOException, ConfigInvalidException {
    GpgKeys.checkVisible(self, rsrc);
    Collection<ExternalId> existingExtIds = externalIds.byAccount(rsrc.getUser().getAccountId(), SCHEME_GPGKEY);
    try (PublicKeyStore store = storeProvider.get()) {
        Set<Fingerprint> toRemove = readKeysToRemove(input, existingExtIds);
        List<PGPPublicKeyRing> newKeys = readKeysToAdd(input, toRemove);
        List<ExternalId> newExtIds = new ArrayList<>(existingExtIds.size());
        for (PGPPublicKeyRing keyRing : newKeys) {
            PGPPublicKey key = keyRing.getPublicKey();
            ExternalId.Key extIdKey = toExtIdKey(key.getFingerprint());
            Account account = getAccountByExternalId(extIdKey);
            if (account != null) {
                if (!account.getId().equals(rsrc.getUser().getAccountId())) {
                    throw new ResourceConflictException("GPG key already associated with another account");
                }
            } else {
                newExtIds.add(ExternalId.create(extIdKey, rsrc.getUser().getAccountId()));
            }
        }
        storeKeys(rsrc, newKeys, toRemove);
        List<ExternalId.Key> extIdKeysToRemove = toRemove.stream().map(fp -> toExtIdKey(fp.get())).collect(toList());
        externalIdsUpdateFactory.create().replace(rsrc.getUser().getAccountId(), extIdKeysToRemove, newExtIds);
        accountCache.evict(rsrc.getUser().getAccountId());
        return toJson(newKeys, toRemove, store, rsrc.getUser());
    }
}
Also used : ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) OrmException(com.google.gwtorm.server.OrmException) PublicKeyStore.keyToString(com.google.gerrit.gpg.PublicKeyStore.keyToString) Inject(com.google.inject.Inject) LoggerFactory(org.slf4j.LoggerFactory) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) RestModifyView(com.google.gerrit.extensions.restapi.RestModifyView) ByteArrayInputStream(java.io.ByteArrayInputStream) GpgKeyInfo(com.google.gerrit.extensions.common.GpgKeyInfo) Map(java.util.Map) PGPPublicKeyRing(org.bouncycastle.openpgp.PGPPublicKeyRing) PGPException(org.bouncycastle.openpgp.PGPException) ImmutableSet(com.google.common.collect.ImmutableSet) Collection(java.util.Collection) Set(java.util.Set) RefUpdate(org.eclipse.jgit.lib.RefUpdate) PGPPublicKey(org.bouncycastle.openpgp.PGPPublicKey) SCHEME_GPGKEY(com.google.gerrit.server.account.externalids.ExternalId.SCHEME_GPGKEY) Sets(com.google.common.collect.Sets) ExternalIds(com.google.gerrit.server.account.externalids.ExternalIds) PersonIdent(org.eclipse.jgit.lib.PersonIdent) List(java.util.List) ExternalIdsUpdate(com.google.gerrit.server.account.externalids.ExternalIdsUpdate) Joiner(com.google.common.base.Joiner) Singleton(com.google.inject.Singleton) AccountCache(com.google.gerrit.server.account.AccountCache) ConfigInvalidException(org.eclipse.jgit.errors.ConfigInvalidException) PublicKeyStore(com.google.gerrit.gpg.PublicKeyStore) InternalAccountQuery(com.google.gerrit.server.query.account.InternalAccountQuery) GerritPublicKeyChecker(com.google.gerrit.gpg.GerritPublicKeyChecker) Fingerprint(com.google.gerrit.gpg.Fingerprint) ArrayList(java.util.ArrayList) Lists(com.google.common.collect.Lists) ImmutableList(com.google.common.collect.ImmutableList) Account(com.google.gerrit.reviewdb.client.Account) CommitBuilder(org.eclipse.jgit.lib.CommitBuilder) ArmoredInputStream(org.bouncycastle.bcpg.ArmoredInputStream) CheckResult(com.google.gerrit.gpg.CheckResult) Input(com.google.gerrit.gpg.server.PostGpgKeys.Input) CurrentUser(com.google.gerrit.server.CurrentUser) Logger(org.slf4j.Logger) BaseEncoding(com.google.common.io.BaseEncoding) UTF_8(java.nio.charset.StandardCharsets.UTF_8) AccountResource(com.google.gerrit.server.account.AccountResource) EmailException(com.google.gerrit.common.errors.EmailException) PublicKeyChecker(com.google.gerrit.gpg.PublicKeyChecker) IOException(java.io.IOException) Maps(com.google.common.collect.Maps) PublicKeyStore.keyIdToString(com.google.gerrit.gpg.PublicKeyStore.keyIdToString) Collectors.toList(java.util.stream.Collectors.toList) Provider(com.google.inject.Provider) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) IdentifiedUser(com.google.gerrit.server.IdentifiedUser) AddKeySender(com.google.gerrit.server.mail.send.AddKeySender) ExternalId(com.google.gerrit.server.account.externalids.ExternalId) AccountState(com.google.gerrit.server.account.AccountState) BcPGPObjectFactory(org.bouncycastle.openpgp.bc.BcPGPObjectFactory) GerritPersonIdent(com.google.gerrit.server.GerritPersonIdent) InputStream(java.io.InputStream) PGPPublicKeyRing(org.bouncycastle.openpgp.PGPPublicKeyRing) Account(com.google.gerrit.reviewdb.client.Account) Fingerprint(com.google.gerrit.gpg.Fingerprint) ExternalId(com.google.gerrit.server.account.externalids.ExternalId) ArrayList(java.util.ArrayList) PGPPublicKey(org.bouncycastle.openpgp.PGPPublicKey) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) PublicKeyStore(com.google.gerrit.gpg.PublicKeyStore) PGPPublicKey(org.bouncycastle.openpgp.PGPPublicKey)

Aggregations

BadRequestException (com.google.gerrit.extensions.restapi.BadRequestException)65 AuthException (com.google.gerrit.extensions.restapi.AuthException)22 ResourceConflictException (com.google.gerrit.extensions.restapi.ResourceConflictException)21 MethodNotAllowedException (com.google.gerrit.extensions.restapi.MethodNotAllowedException)15 ResourceNotFoundException (com.google.gerrit.extensions.restapi.ResourceNotFoundException)13 Repository (org.eclipse.jgit.lib.Repository)13 Project (com.google.gerrit.reviewdb.client.Project)12 UnprocessableEntityException (com.google.gerrit.extensions.restapi.UnprocessableEntityException)11 ArrayList (java.util.ArrayList)11 IOException (java.io.IOException)10 RevCommit (org.eclipse.jgit.revwalk.RevCommit)10 Account (com.google.gerrit.reviewdb.client.Account)9 Change (com.google.gerrit.reviewdb.client.Change)8 IdentifiedUser (com.google.gerrit.server.IdentifiedUser)8 BatchUpdate (com.google.gerrit.server.update.BatchUpdate)8 Map (java.util.Map)8 AccountGroup (com.google.gerrit.reviewdb.client.AccountGroup)7 ConfigInvalidException (org.eclipse.jgit.errors.ConfigInvalidException)7 RevWalk (org.eclipse.jgit.revwalk.RevWalk)7 RestApiException (com.google.gerrit.extensions.restapi.RestApiException)6