Skip to content

Commit

Permalink
238: Implement keys endpoints to list access keys
Browse files Browse the repository at this point in the history
  • Loading branch information
Dávid Csákvári committed Sep 28, 2020
1 parent d81423b commit e111f99
Show file tree
Hide file tree
Showing 16 changed files with 910 additions and 6 deletions.
4 changes: 4 additions & 0 deletions src/main/java/com/cdancy/bitbucket/rest/BitbucketApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import com.cdancy.bitbucket.rest.features.RepositoryApi;
import com.cdancy.bitbucket.rest.features.SyncApi;
import com.cdancy.bitbucket.rest.features.SystemApi;
import com.cdancy.bitbucket.rest.features.KeysApi;
import com.cdancy.bitbucket.rest.features.TagApi;
import com.cdancy.bitbucket.rest.features.TasksApi;
import com.cdancy.bitbucket.rest.features.WebHookApi;
Expand Down Expand Up @@ -90,4 +91,7 @@ public interface BitbucketApi extends Closeable {

@Delegate
InsightsApi insightsApi();

@Delegate
KeysApi keysApi();
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,46 @@

package com.cdancy.bitbucket.rest.domain.sshkey;

import java.util.List;

import com.google.auto.value.AutoValue;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.json.SerializedNames;

import com.cdancy.bitbucket.rest.domain.common.Error;
import com.cdancy.bitbucket.rest.domain.common.ErrorsHolder;
import com.cdancy.bitbucket.rest.domain.repository.Repository;
import com.cdancy.bitbucket.rest.domain.project.Project;
import com.cdancy.bitbucket.rest.BitbucketUtils;

@AutoValue
public abstract class AccessKey {
public abstract class AccessKey implements ErrorsHolder {

public enum PermissionType {
REPO_WRITE,
REPO_READ,
PROJECT_WRITE,
PROJECT_READ
}

@Nullable
public abstract Key key();

@SerializedNames({"key"})
public static AccessKey create(final Key key) {
return new AutoValue_AccessKey(key);
@Nullable
public abstract Repository repository();

@Nullable
public abstract Project project();

@Nullable
public abstract PermissionType permission();

@SerializedNames({"key", "repository", "project", "permission", "errors"})
public static AccessKey create(final Key key,
final Repository repository,
final Project project,
final PermissionType permission,
final List<Error> errors) {
return new AutoValue_AccessKey(BitbucketUtils.nullToEmpty(errors), key, repository, project, permission);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.cdancy.bitbucket.rest.domain.sshkey;

import java.util.List;

import org.jclouds.javax.annotation.Nullable;
import org.jclouds.json.SerializedNames;

import com.cdancy.bitbucket.rest.domain.common.Error;
import com.cdancy.bitbucket.rest.domain.common.ErrorsHolder;
import com.cdancy.bitbucket.rest.domain.common.Page;
import com.cdancy.bitbucket.rest.BitbucketUtils;
import com.google.auto.value.AutoValue;

@AutoValue
public abstract class AccessKeyPage implements Page<AccessKey>, ErrorsHolder {

@SerializedNames({ "start", "limit", "size",
"nextPageStart", "isLastPage", "values", "errors" })
public static AccessKeyPage create(final int start,
final int limit,
final int size,
final int nextPageStart,
final boolean isLastPage,
@Nullable final List<AccessKey> values,
@Nullable final List<Error> errors) {

return new AutoValue_AccessKeyPage(start,
limit,
size,
nextPageStart,
isLastPage,
BitbucketUtils.nullToEmpty(values),
BitbucketUtils.nullToEmpty(errors));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ public abstract class Key {
public abstract String label();

@SerializedNames({"id", "text", "label"})
public static Key create(@Nullable final Long id,
final String text,
public static Key create(@Nullable final Long id,
final String text,
final String label) {
return new AutoValue_Key(id, text, label);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@
import com.cdancy.bitbucket.rest.domain.repository.WebHookPage;
import com.cdancy.bitbucket.rest.domain.sync.SyncState;
import com.cdancy.bitbucket.rest.domain.sync.SyncStatus;
import com.cdancy.bitbucket.rest.domain.sshkey.AccessKey;
import com.cdancy.bitbucket.rest.domain.sshkey.AccessKeyPage;
import com.cdancy.bitbucket.rest.domain.tags.Tag;
import com.cdancy.bitbucket.rest.domain.tags.TagPage;
import com.google.common.collect.Lists;
Expand Down Expand Up @@ -565,6 +567,26 @@ public Object createOrPropagate(final Throwable throwable) throws Exception {
}
}

public static final class AccessKeyOnError implements Fallback<Object> {
@Override
public Object createOrPropagate(final Throwable throwable) throws Exception {
if (checkNotNull(throwable, "throwable") != null) {
return createAccessKeyFromErrors(getErrors(throwable.getMessage()));
}
throw propagate(throwable);
}
}

public static final class AccessKeyPageOnError implements Fallback<Object> {
@Override
public Object createOrPropagate(final Throwable throwable) throws Exception {
if (checkNotNull(throwable, "throwable") != null) {
return createAccessKeyPageFromErrors(getErrors(throwable.getMessage()));
}
throw propagate(throwable);
}
}

public static RequestStatus createRequestStatusFromErrors(final List<Error> errors) {
return RequestStatus.create(false, errors);
}
Expand Down Expand Up @@ -748,6 +770,13 @@ public static WebHook createWebHookFromErrors(final List<Error> errors) {
return WebHook.create(null, null, -1, -1, null , null, null, false, errors);
}

public static AccessKey createAccessKeyFromErrors(final List<Error> errors) {
return AccessKey.create(null, null, null, null, errors);
}

public static AccessKeyPage createAccessKeyPageFromErrors(final List<Error> errors) {
return AccessKeyPage.create(0, 0, 0, 0, false, null, errors);
}

/**
* Parse list of Error's from output.
Expand Down
133 changes: 133 additions & 0 deletions src/main/java/com/cdancy/bitbucket/rest/features/KeysApi.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.cdancy.bitbucket.rest.features;

import com.cdancy.bitbucket.rest.annotations.Documentation;
import javax.inject.Named;
import javax.ws.rs.Consumes;
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.MediaType;
import javax.ws.rs.QueryParam;

import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.binders.BindToJsonPayload;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.annotations.Fallback;

import com.cdancy.bitbucket.rest.options.CreateAccessKey;
import com.cdancy.bitbucket.rest.domain.common.RequestStatus;
import com.cdancy.bitbucket.rest.fallbacks.BitbucketFallbacks;
import com.cdancy.bitbucket.rest.filters.BitbucketAuthenticationFilter;
import com.cdancy.bitbucket.rest.parsers.RequestStatusParser;
import com.cdancy.bitbucket.rest.domain.sshkey.AccessKey;
import com.cdancy.bitbucket.rest.domain.sshkey.AccessKeyPage;

@Produces(MediaType.APPLICATION_JSON)
@RequestFilters(BitbucketAuthenticationFilter.class)
@Path("/rest/keys/{jclouds.api-version}")
@SuppressWarnings("PMD.AvoidDuplicateLiterals")
public interface KeysApi {

@Named("keys:list-by-repo")
@Documentation({"https://docs.atlassian.com/bitbucket-server/rest/latest/bitbucket-ssh-rest.html#idp9"})
@Consumes(MediaType.APPLICATION_JSON)
@Path("/projects/{project}/repos/{repo}/ssh")
@Fallback(BitbucketFallbacks.AccessKeyPageOnError.class)
@GET
AccessKeyPage listByRepo(@PathParam("project") String project,
@PathParam("repo") String repo,
@Nullable @QueryParam("start") Integer start,
@Nullable @QueryParam("limit") Integer limit);

@Named("keys:create-for-repo")
@Documentation({"https://docs.atlassian.com/bitbucket-server/rest/latest/bitbucket-ssh-rest.html#idp10"})
@Consumes(MediaType.APPLICATION_JSON)
@Path("/projects/{project}/repos/{repo}/ssh")
@Fallback(BitbucketFallbacks.AccessKeyOnError.class)
@POST
AccessKey createForRepo(@PathParam("project") String project,
@PathParam("repo") String repo,
@BinderParam(BindToJsonPayload.class) CreateAccessKey createAccessKey);

@Named("keys:get-for-repo")
@Documentation({"https://docs.atlassian.com/bitbucket-server/rest/latest/bitbucket-ssh-rest.html#idp12"})
@Consumes(MediaType.APPLICATION_JSON)
@Path("/projects/{project}/repos/{repo}/ssh/{id}")
@Fallback(BitbucketFallbacks.AccessKeyOnError.class)
@GET
AccessKey getForRepo(@PathParam("project") String project,
@PathParam("repo") String repo,
@PathParam("id") long id);

@Named("keys:delete-from-repo")
@Documentation({"https://docs.atlassian.com/bitbucket-server/rest/latest/bitbucket-ssh-rest.html#idp13"})
@Consumes(MediaType.APPLICATION_JSON)
@Path("/projects/{project}/repos/{repo}/ssh/{id}")
@Fallback(BitbucketFallbacks.RequestStatusOnError.class)
@ResponseParser(RequestStatusParser.class)
@DELETE
RequestStatus deleteFromRepo(@PathParam("project") String project,
@PathParam("repo") String repo,
@PathParam("id") long id);

@Named("keys:list-by-project")
@Documentation({"https://docs.atlassian.com/bitbucket-server/rest/latest/bitbucket-ssh-rest.html#idp17"})
@Consumes(MediaType.APPLICATION_JSON)
@Path("/projects/{project}/ssh")
@Fallback(BitbucketFallbacks.AccessKeyPageOnError.class)
@GET
AccessKeyPage listByProject(@PathParam("project") String project,
@Nullable @QueryParam("start") Integer start,
@Nullable @QueryParam("limit") Integer limit);

@Named("keys:create-for-project")
@Documentation({"https://docs.atlassian.com/bitbucket-server/rest/latest/bitbucket-ssh-rest.html#idp18"})
@Consumes(MediaType.APPLICATION_JSON)
@Path("/projects/{project}/ssh")
@Fallback(BitbucketFallbacks.AccessKeyOnError.class)
@POST
AccessKey createForProject(@PathParam("project") String project,
@BinderParam(BindToJsonPayload.class) CreateAccessKey createAccessKey);

@Named("keys:get-for-project")
@Documentation({"https://docs.atlassian.com/bitbucket-server/rest/latest/bitbucket-ssh-rest.html#idp20"})
@Consumes(MediaType.APPLICATION_JSON)
@Path("/projects/{project}/ssh/{id}")
@Fallback(BitbucketFallbacks.AccessKeyOnError.class)
@GET
AccessKey getForProject(@PathParam("project") String project,
@PathParam("id") long id);

@Named("keys:delete-from-project")
@Documentation({"https://docs.atlassian.com/bitbucket-server/rest/latest/bitbucket-ssh-rest.html#idp21"})
@Consumes(MediaType.APPLICATION_JSON)
@Path("/projects/{project}/ssh/{id}")
@Fallback(BitbucketFallbacks.RequestStatusOnError.class)
@ResponseParser(RequestStatusParser.class)
@DELETE
RequestStatus deleteFromProject(@PathParam("project") String project,
@PathParam("id") long id);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.cdancy.bitbucket.rest.options;

import com.cdancy.bitbucket.rest.domain.sshkey.AccessKey.PermissionType;

import com.google.auto.value.AutoValue;
import org.jclouds.json.SerializedNames;

@AutoValue
public abstract class CreateAccessKey {

public abstract CreateKey key();

public abstract PermissionType permission();

CreateAccessKey() {
}

@SerializedNames({ "key", "permission" })
public static CreateAccessKey create(final CreateKey key, final PermissionType permission) {
return new AutoValue_CreateAccessKey(key, permission);
}
}
35 changes: 35 additions & 0 deletions src/main/java/com/cdancy/bitbucket/rest/options/CreateKey.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.cdancy.bitbucket.rest.options;

import com.google.auto.value.AutoValue;
import org.jclouds.json.SerializedNames;

@AutoValue
public abstract class CreateKey {

public abstract String text();

CreateKey() {
}

@SerializedNames({ "text" })
public static CreateKey create(final String text) {
return new AutoValue_CreateKey(text);
}
}
Loading

0 comments on commit e111f99

Please sign in to comment.