Skip to content

Commit

Permalink
[ZEPPELIN-5769] Roles in API-Request (apache#4407)
Browse files Browse the repository at this point in the history
* Add user roles to API Requests

* Polish RestAPI

* Use Boolean instead of boolean

* Rename paragraphJobStatusList to paragraphs
  • Loading branch information
Reamer authored Jul 22, 2022
1 parent 4d9cc83 commit fb80aa9
Show file tree
Hide file tree
Showing 30 changed files with 242 additions and 283 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,21 @@
import org.apache.zeppelin.service.SimpleServiceCallback;
import org.apache.zeppelin.user.AuthenticationInfo;

import com.google.gson.Gson;

public class AbstractRestApi {

protected AuthenticationService authenticationService;

protected static final Gson GSON = new Gson();

protected AbstractRestApi(AuthenticationService authenticationService) {
this.authenticationService = authenticationService;
}

protected ServiceContext getServiceContext() {
AuthenticationInfo authInfo = new AuthenticationInfo(authenticationService.getPrincipal());
authInfo.setRoles(authenticationService.getAssociatedRoles());
Set<String> userAndRoles = new HashSet<>();
userAndRoles.add(authenticationService.getPrincipal());
userAndRoles.addAll(authenticationService.getAssociatedRoles());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
Expand Down Expand Up @@ -54,8 +55,8 @@ public class ClusterRestApi {
// Do not modify, Use by `zeppelin-web/src/app/cluster/cluster.html`
private static String PROPERTIES = "properties";

public ClusterRestApi() {
ZeppelinConfiguration zConf = ZeppelinConfiguration.create();
@Inject
public ClusterRestApi(ZeppelinConfiguration zConf) {
if (zConf.isClusterMode()) {
clusterManagerServer = ClusterManagerServer.getInstance(zConf);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@

package org.apache.zeppelin.rest;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.IOException;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.ws.rs.DELETE;
Expand All @@ -33,6 +30,7 @@
import javax.ws.rs.core.Response.Status;

import org.apache.commons.lang3.StringUtils;
import org.apache.zeppelin.rest.message.CredentialRequest;
import org.apache.zeppelin.server.JsonResponse;
import org.apache.zeppelin.service.AuthenticationService;
import org.apache.zeppelin.user.Credentials;
Expand All @@ -45,16 +43,14 @@
@Path("/credential")
@Produces("application/json")
@Singleton
public class CredentialRestApi {
public class CredentialRestApi extends AbstractRestApi {
private static final Logger LOGGER = LoggerFactory.getLogger(CredentialRestApi.class);
private final Credentials credentials;
private final AuthenticationService authenticationService;
private final Gson gson = new Gson();

@Inject
public CredentialRestApi(Credentials credentials, AuthenticationService authenticationService) {
super(authenticationService);
this.credentials = credentials;
this.authenticationService = authenticationService;
}

/**
Expand All @@ -65,24 +61,17 @@ public CredentialRestApi(Credentials credentials, AuthenticationService authenti
*/
@PUT
public Response putCredentials(String message) {
Map<String, String> messageMap =
gson.fromJson(message, new TypeToken<Map<String, String>>() {}.getType());
String entity = messageMap.get("entity");
String username = messageMap.get("username");
String password = messageMap.get("password");

if (StringUtils.isEmpty(entity)
|| StringUtils.isEmpty(username)
|| StringUtils.isEmpty(password)) {
CredentialRequest request = GSON.fromJson(message, CredentialRequest.class);
if (StringUtils.isAnyBlank(request.getEntity(), request.getUsername(), request.getPassword())) {
return new JsonResponse<>(Status.BAD_REQUEST).build();
}

String user = authenticationService.getPrincipal();
LOGGER.info("Update credentials for user {} entity {}", user, entity);
LOGGER.info("Update credentials for user {} entity {}", user, request.getEntity());
UserCredentials uc;
try {
uc = credentials.getUserCredentials(user);
uc.putUsernamePassword(entity, new UsernamePassword(username, password));
uc.putUsernamePassword(request.getEntity(), new UsernamePassword(request.getUsername(), request.getPassword()));
credentials.putUserCredentials(user, uc);
return new JsonResponse<>(Status.OK).build();
} catch (IOException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,10 @@
@Path("/interpreter")
@Produces("application/json")
@Singleton
public class InterpreterRestApi {
public class InterpreterRestApi extends AbstractRestApi {

private static final Logger LOGGER = LoggerFactory.getLogger(InterpreterRestApi.class);

private final AuthenticationService authenticationService;
private final AuthorizationService authorizationService;
private final InterpreterService interpreterService;
private final InterpreterSettingManager interpreterSettingManager;
Expand All @@ -84,7 +83,7 @@ public InterpreterRestApi(
InterpreterService interpreterService,
InterpreterSettingManager interpreterSettingManager,
NotebookServer notebookWsServer) {
this.authenticationService = authenticationService;
super(authenticationService);
this.authorizationService = authorizationService;
this.interpreterService = interpreterService;
this.interpreterSettingManager = interpreterSettingManager;
Expand Down Expand Up @@ -132,8 +131,7 @@ public Response getSetting(@PathParam("settingId") String settingId) {
@ZeppelinApi
public Response newSettings(String message) {
try {
NewInterpreterSettingRequest request =
NewInterpreterSettingRequest.fromJson(message);
NewInterpreterSettingRequest request = GSON.fromJson(message, NewInterpreterSettingRequest.class);
if (request == null) {
return new JsonResponse<>(Status.BAD_REQUEST).build();
}
Expand All @@ -157,8 +155,7 @@ public Response updateSetting(String message, @PathParam("settingId") String set
LOGGER.info("Update interpreterSetting {}", settingId);

try {
UpdateInterpreterSettingRequest request =
UpdateInterpreterSettingRequest.fromJson(message);
UpdateInterpreterSettingRequest request = GSON.fromJson(message, UpdateInterpreterSettingRequest.class);
interpreterSettingManager
.setPropertyAndRestart(settingId, request.getOption(), request.getProperties(),
request.getDependencies());
Expand Down Expand Up @@ -201,7 +198,7 @@ public Response restartSetting(String message, @PathParam("settingId") String se

InterpreterSetting setting = interpreterSettingManager.get(settingId);
try {
RestartInterpreterRequest request = RestartInterpreterRequest.fromJson(message);
RestartInterpreterRequest request = GSON.fromJson(message, RestartInterpreterRequest.class);

String noteId = request == null ? null : request.getNoteId();
if (null == noteId) {
Expand Down Expand Up @@ -308,8 +305,7 @@ public Response listInterpreterPropertyTypes() {
@ZeppelinApi
public Response installInterpreter(@NotNull String message) {
LOGGER.info("Install interpreter: {}", message);
InterpreterInstallationRequest request = InterpreterInstallationRequest.fromJson(message);

InterpreterInstallationRequest request = GSON.fromJson(message, InterpreterInstallationRequest.class);
try {
interpreterService.installInterpreter(
request,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import com.google.gson.Gson;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
Expand All @@ -44,7 +43,6 @@
import org.apache.zeppelin.annotation.ZeppelinApi;
import org.apache.zeppelin.conf.ZeppelinConfiguration;
import org.apache.zeppelin.notebook.AuthorizationService;
import org.apache.zeppelin.notebook.Notebook;
import org.apache.zeppelin.realm.jwt.JWTAuthenticationToken;
import org.apache.zeppelin.realm.jwt.KnoxJwtRealm;
import org.apache.zeppelin.realm.kerberos.KerberosRealm;
Expand All @@ -61,20 +59,18 @@
@Path("/login")
@Produces("application/json")
@Singleton
public class LoginRestApi {
public class LoginRestApi extends AbstractRestApi {
private static final Logger LOG = LoggerFactory.getLogger(LoginRestApi.class);
private static final Gson GSON = new Gson();
private final ZeppelinConfiguration zConf;

private final AuthenticationService authenticationService;
private final AuthorizationService authorizationService;

@Inject
public LoginRestApi(Notebook notebook,
public LoginRestApi(ZeppelinConfiguration zConf,
AuthenticationService authenticationService,
AuthorizationService authorizationService) {
this.zConf = notebook.getConf();
this.authenticationService = authenticationService;
super(authenticationService);
this.zConf = zConf;
this.authorizationService = authorizationService;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,12 @@
import javax.inject.Singleton;
import org.apache.commons.lang3.StringUtils;
import org.apache.zeppelin.service.AuthenticationService;
import org.apache.zeppelin.service.ServiceContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
Expand All @@ -55,16 +51,16 @@
@Path("/notebook-repositories")
@Produces("application/json")
@Singleton
public class NotebookRepoRestApi {
public class NotebookRepoRestApi extends AbstractRestApi {
private static final Logger LOG = LoggerFactory.getLogger(NotebookRepoRestApi.class);

private final NotebookRepoSync noteRepos;
private final NotebookServer notebookWsServer;
private final AuthenticationService authenticationService;

@Inject
public NotebookRepoRestApi(NotebookRepoSync noteRepos, NotebookServer notebookWsServer,
AuthenticationService authenticationService) {
super(authenticationService);
this.noteRepos = noteRepos;
this.notebookWsServer = notebookWsServer;
this.authenticationService = authenticationService;
Expand Down Expand Up @@ -99,14 +95,6 @@ public Response refreshRepo(){
return new JsonResponse<>(Status.OK, "", null).build();
}

private ServiceContext getServiceContext() {
AuthenticationInfo authInfo = new AuthenticationInfo(authenticationService.getPrincipal());
Set<String> userAndRoles = new HashSet<>();
userAndRoles.add(authenticationService.getPrincipal());
userAndRoles.addAll(authenticationService.getAssociatedRoles());
return new ServiceContext(authInfo, userAndRoles);
}

/**
* Update a specific note repo.
*
Expand All @@ -122,7 +110,7 @@ public Response updateRepoSetting(String payload) {
AuthenticationInfo subject = new AuthenticationInfo(authenticationService.getPrincipal());
NotebookRepoSettingsRequest newSettings;
try {
newSettings = NotebookRepoSettingsRequest.fromJson(payload);
newSettings = GSON.fromJson(payload, NotebookRepoSettingsRequest.class);
} catch (JsonSyntaxException e) {
LOG.error("Cannot update notebook repo settings", e);
return new JsonResponse<>(Status.NOT_ACCEPTABLE, "",
Expand All @@ -136,7 +124,7 @@ public Response updateRepoSetting(String payload) {
}
LOG.info("User {} is going to change repo setting", subject.getUser());
NotebookRepoWithSettings updatedSettings =
noteRepos.updateNotebookRepo(newSettings.name, newSettings.settings, subject);
noteRepos.updateNotebookRepo(newSettings.getName(), newSettings.getSettings(), subject);
if (!updatedSettings.isEmpty()) {
LOG.info("Broadcasting note list to user {}", subject.getUser());
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@

package org.apache.zeppelin.rest;

import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
Expand Down Expand Up @@ -77,7 +75,6 @@
@Singleton
public class NotebookRestApi extends AbstractRestApi {
private static final Logger LOGGER = LoggerFactory.getLogger(NotebookRestApi.class);
private static final Gson GSON = new Gson();

private final ZeppelinConfiguration zConf;
private final Notebook notebook;
Expand All @@ -86,7 +83,6 @@ public class NotebookRestApi extends AbstractRestApi {
private final AuthorizationService authorizationService;
private final NotebookService notebookService;
private final JobManagerService jobManagerService;
private final AuthenticationService authenticationService;
private final SchedulerService schedulerService;

@Inject
Expand All @@ -108,7 +104,6 @@ public NotebookRestApi(
this.noteSearchService = search;
this.authorizationService = authorizationService;
this.zConf = zConf;
this.authenticationService = authenticationService;
this.schedulerService = schedulerService;
}

Expand Down Expand Up @@ -245,16 +240,14 @@ public Response putNotePermissions(@PathParam("noteId") String noteId, String re
checkIfUserIsOwner(noteId,
ownerPermissionError(userAndRoles, authorizationService.getOwners(noteId)));

HashMap<String, HashSet<String>> permMap =
GSON.fromJson(req, new TypeToken<HashMap<String, HashSet<String>>>() {
}.getType());
PermissionRequest permMap = GSON.fromJson(req, PermissionRequest.class);
return notebook.processNote(noteId,
note -> {
checkIfNoteIsNotNull(note, noteId);
HashSet<String> readers = permMap.get("readers");
HashSet<String> runners = permMap.get("runners");
HashSet<String> owners = permMap.get("owners");
HashSet<String> writers = permMap.get("writers");
Set<String> readers = permMap.getReaders();
Set<String> runners = permMap.getRunners();
Set<String> owners = permMap.getOwners();
Set<String> writers = permMap.getWriters();

LOGGER.info("Set permissions to note: {} with current user:{}, owners:{}, readers:{}, runners:{}, writers:{}",
noteId, principal, owners, readers, runners, writers);
Expand Down Expand Up @@ -488,7 +481,7 @@ public Response importNote(@QueryParam("notePath") String notePath, String noteJ
public Response createNote(String message) throws IOException {
String user = authenticationService.getPrincipal();
LOGGER.info("Creating new note by JSON {}", message);
NewNoteRequest request = NewNoteRequest.fromJson(message);
NewNoteRequest request = GSON.fromJson(message, NewNoteRequest.class);
String defaultInterpreterGroup = request.getDefaultInterpreterGroup();
if (StringUtils.isBlank(defaultInterpreterGroup)) {
defaultInterpreterGroup = zConf.getString(ZeppelinConfiguration.ConfVars.ZEPPELIN_INTERPRETER_GROUP_DEFAULT);
Expand Down Expand Up @@ -553,7 +546,7 @@ public Response cloneNote(@PathParam("noteId") String noteId, String message)

LOGGER.info("Clone note by JSON {}", message);
checkIfUserCanWrite(noteId, "Insufficient privileges you cannot clone this note");
NewNoteRequest request = NewNoteRequest.fromJson(message);
NewNoteRequest request = GSON.fromJson(message, NewNoteRequest.class);
String newNoteName = null;
String revisionId = null;
if (request != null) {
Expand Down Expand Up @@ -623,7 +616,7 @@ public Response insertParagraph(@PathParam("noteId") String noteId, String messa
note -> {
checkIfNoteIsNotNull(note, noteId);
checkIfUserCanWrite(noteId, "Insufficient privileges you cannot add paragraph to this note");
NewParagraphRequest request = NewParagraphRequest.fromJson(message);
NewParagraphRequest request = GSON.fromJson(message, NewParagraphRequest.class);
Paragraph p;
Double indexDouble = request.getIndex();
if (indexDouble == null) {
Expand Down Expand Up @@ -832,8 +825,7 @@ public Response runNoteJobs(@PathParam("noteId") String noteId,

Map<String, Object> params = new HashMap<>();
if (!StringUtils.isEmpty(message)) {
ParametersRequest request =
ParametersRequest.fromJson(message);
ParametersRequest request = GSON.fromJson(message, ParametersRequest.class);
params.putAll(request.getParams());
}

Expand Down Expand Up @@ -962,8 +954,7 @@ public Response runParagraph(@PathParam("noteId") String noteId,

Map<String, Object> params = new HashMap<>();
if (!StringUtils.isEmpty(message)) {
ParametersRequest request =
ParametersRequest.fromJson(message);
ParametersRequest request = GSON.fromJson(message, ParametersRequest.class);
params = request.getParams();
}
notebookService.runParagraph(note, paragraphId, paragraph.getTitle(),
Expand Down Expand Up @@ -1002,8 +993,7 @@ public Response runParagraphSynchronously(@PathParam("noteId") String noteId,

Map<String, Object> params = new HashMap<>();
if (!StringUtils.isEmpty(message)) {
ParametersRequest request =
ParametersRequest.fromJson(message);
ParametersRequest request = GSON.fromJson(message, ParametersRequest.class);
params = request.getParams();
}

Expand Down Expand Up @@ -1059,7 +1049,7 @@ public Response registerCronJob(@PathParam("noteId") String noteId, String messa

LOGGER.info("Register cron job note={} request cron msg={}", noteId, message);

CronRequest request = CronRequest.fromJson(message);
CronRequest request = GSON.fromJson(message, CronRequest.class);

// use write lock, because config is overwritten
return notebook.processNote(noteId,
Expand Down
Loading

0 comments on commit fb80aa9

Please sign in to comment.