Skip to content

Commit

Permalink
refactor(Added auth checks): Auth checks and added notes and org id t…
Browse files Browse the repository at this point in the history
…o feed source summary
  • Loading branch information
br648 committed Oct 13, 2023
1 parent b22b422 commit 69a9b65
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import static com.conveyal.datatools.common.utils.SparkUtils.getPOJOFromRequestBody;
import static com.conveyal.datatools.common.utils.SparkUtils.logMessageAndHalt;
import static com.conveyal.datatools.manager.models.ExternalFeedSourceProperty.constructId;
import static com.conveyal.datatools.manager.models.FeedSourceSummary.cleanFeedSourceSummaryForNonAdmins;
import static com.conveyal.datatools.manager.models.transform.NormalizeFieldTransformation.getInvalidSubstitutionMessage;
import static com.conveyal.datatools.manager.models.transform.NormalizeFieldTransformation.getInvalidSubstitutionPatterns;
import static com.mongodb.client.model.Filters.in;
Expand Down Expand Up @@ -103,6 +104,31 @@ private static Collection<FeedSource> getProjectFeedSources(Request req, Respons
return feedSourcesToReturn;
}

private static Collection<FeedSourceSummary> getAllFeedSourceSummaries(Request req, Response res) {
Collection<FeedSourceSummary> feedSourcesToReturn = new ArrayList<>();
Auth0UserProfile user = req.attribute("user");
String projectId = req.queryParams("projectId");

Project project = Persistence.projects.getById(projectId);

if (project == null) {
logMessageAndHalt(req, 400, "Must provide valid projectId value.");
} else {
boolean isAdmin = user.canAdministerProject(project);
Collection<FeedSourceSummary> feedSourceSummaries = project.retrieveFeedSourceSummaries();
for (FeedSourceSummary feedSourceSummary : feedSourceSummaries) {
// If user can view or manage feed, add to list of feeds to return. NOTE: By default most users with access
// to a project should be able to view all feed sources. Custom privileges would need to be provided to
// override this behavior.
if (user.canManageOrViewFeed(project.organizationId, feedSourceSummary.projectId, feedSourceSummary.id)) {
// Remove labels user can't view, then add to list of feeds to return.
feedSourcesToReturn.add(cleanFeedSourceSummaryForNonAdmins(feedSourceSummary, isAdmin));
}
}
}
return feedSourcesToReturn;
}

/**
* HTTP endpoint to create a new feed source.
*/
Expand Down Expand Up @@ -397,20 +423,6 @@ protected static FeedSource cleanFeedSourceForNonAdmins(FeedSource feedSource, b
return feedSource;
}

private static Collection<FeedSourceSummary> getAllFeedSourceSummaries(Request req, Response res) {
Auth0UserProfile userProfile = req.attribute("user");
String projectId = req.queryParams("projectId");
Project project = Persistence.projects.getById(projectId);
if (project == null) {
logMessageAndHalt(req, 400, "Must provide valid projectId value.");
}
if (!userProfile.canAdministerProject(project)) {
logMessageAndHalt(req, 401, "User not authorized to view project feed sources.");
}
return project.retrieveFeedSourceSummaries();
}


// FIXME: use generic API controller and return JSON documents via BSON/Mongo
public static void register (String apiPrefix) {
get(apiPrefix + "secure/feedsource/:id", FeedSourceController::getFeedSource, json::write);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.conveyal.datatools.editor.utils.JacksonSerializers;
import com.conveyal.datatools.manager.persistence.Persistence;
import com.conveyal.datatools.manager.utils.PersistenceUtils;
import com.conveyal.gtfs.validator.ValidationResult;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
Expand All @@ -20,6 +21,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.mongodb.client.model.Aggregates.group;
import static com.mongodb.client.model.Aggregates.limit;
Expand Down Expand Up @@ -64,11 +66,16 @@ public class FeedSourceSummary {

public String url;

public List<String> noteIds = new ArrayList<>();

public String organizationId;

public FeedSourceSummary() {
}

public FeedSourceSummary(String projectId, Document feedSourceDocument) {
public FeedSourceSummary(String projectId, String organizationId, Document feedSourceDocument) {
this.projectId = projectId;
this.organizationId = organizationId;
this.id = feedSourceDocument.getString("_id");
this.name = feedSourceDocument.getString("name");
this.deployable = feedSourceDocument.getBoolean("deployable");
Expand All @@ -77,11 +84,35 @@ public FeedSourceSummary(String projectId, Document feedSourceDocument) {
if (documentLabelIds != null) {
this.labelIds = documentLabelIds;
}
List<String> documentNoteIds = feedSourceDocument.getList("noteIds", String.class);
if (documentNoteIds != null) {
this.noteIds = documentNoteIds;
}
// Convert to local date type for consistency.
this.lastUpdated = getLocalDateFromDate(feedSourceDocument.getDate("lastUpdated"));
this.url = feedSourceDocument.getString("url");
}

/**
* Removes labels and notes from a feed that a user is not allowed to view. Returns cleaned feed source.
* @param feedSourceSummary The feed source to clean
* @param isAdmin Is the user an admin? Changes what is returned.
* @return A feed source containing only labels/notes the user is allowed to see
*/
public static FeedSourceSummary cleanFeedSourceSummaryForNonAdmins(FeedSourceSummary feedSourceSummary, boolean isAdmin) {
// Admin can view all feed labels, but a non-admin should only see those with adminOnly=false
feedSourceSummary.labelIds = Persistence.labels
.getFiltered(PersistenceUtils.applyAdminFilter(in("_id", feedSourceSummary.labelIds), isAdmin)).stream()
.map(label -> label.id)
.collect(Collectors.toList());
feedSourceSummary.noteIds = Persistence.notes
.getFiltered(PersistenceUtils.applyAdminFilter(in("_id", feedSourceSummary.noteIds), isAdmin)).stream()
.map(note -> note.id)
.collect(Collectors.toList());
return feedSourceSummary;
}


/**
* Set the appropriate feed version. For consistency, if no error count is available set the related number of
* issues to null.
Expand All @@ -104,7 +135,7 @@ public void setFeedVersion(FeedVersionSummary feedVersionSummary, boolean isDepl
/**
* Get all feed source summaries matching the project id.
*/
public static List<FeedSourceSummary> getFeedSourceSummaries(String projectId) {
public static List<FeedSourceSummary> getFeedSourceSummaries(String projectId, String organizationId) {
/*
db.getCollection('FeedSource').aggregate([
{
Expand All @@ -121,7 +152,8 @@ public static List<FeedSourceSummary> getFeedSourceSummaries(String projectId) {
"isPublic": 1,
"lastUpdated": 1,
"labelIds": 1,
"url": 1
"url": 1,
"noteIds": 1
}
},
{
Expand All @@ -143,12 +175,13 @@ public static List<FeedSourceSummary> getFeedSourceSummaries(String projectId) {
"isPublic",
"lastUpdated",
"labelIds",
"url")
"url",
"noteIds")
)
),
sort(Sorts.ascending("name"))
);
return extractFeedSourceSummaries(projectId, stages);
return extractFeedSourceSummaries(projectId, organizationId, stages);
}

/**
Expand Down Expand Up @@ -423,10 +456,10 @@ public static Map<String, FeedVersionSummary> getFeedVersionsFromPinnedDeploymen
/**
* Produce a list of all feed source summaries for a project.
*/
private static List<FeedSourceSummary> extractFeedSourceSummaries(String projectId, List<Bson> stages) {
private static List<FeedSourceSummary> extractFeedSourceSummaries(String projectId, String organizationId, List<Bson> stages) {
List<FeedSourceSummary> feedSourceSummaries = new ArrayList<>();
for (Document feedSourceDocument : Persistence.getDocuments("FeedSource", stages)) {
feedSourceSummaries.add(new FeedSourceSummary(projectId, feedSourceDocument));
feedSourceSummaries.add(new FeedSourceSummary(projectId, organizationId, feedSourceDocument));
}
return feedSourceSummaries;
}
Expand Down
13 changes: 11 additions & 2 deletions src/main/java/com/conveyal/datatools/manager/models/Label.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,24 @@ public String organizationId () {
public Auth0UserProfile user;

/**
* Create a new label
* Create a new label with auto-gen id.
*/
public Label (String name, String description, String color, boolean adminOnly, String projectId) {
this(null, name, description, color, adminOnly, projectId);
}

/**
* Create a new label with provided id.
*/
public Label (String id, String name, String description, String color, boolean adminOnly, String projectId) {
super();
if (id != null) {
this.id = id;
}
this.name = name;
this.description = description != null ? description : "";
this.color = color != null ? color : "#000000";
this.adminOnly = adminOnly;

this.projectId = projectId;
}

Expand Down
15 changes: 15 additions & 0 deletions src/main/java/com/conveyal/datatools/manager/models/Note.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,21 @@ public class Note extends Model implements Serializable {
/** Whether the note should be visible to project admins only */
public boolean adminOnly;

/**
* Create a new note with provided id.
*/
public Note(String id, String body, boolean adminOnly) {
super();
if (id != null) {
this.id = id;
}
this.body = body;
this.adminOnly = adminOnly;
}

public Note() {
}

/**
* The types of object that can have notes recorded on them.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ public Collection<DeploymentSummary> retrieveDeploymentSummaries() {
* Get all feed source summaries for this project.
*/
public Collection<FeedSourceSummary> retrieveFeedSourceSummaries() {
List<FeedSourceSummary> feedSourceSummaries = FeedSourceSummary.getFeedSourceSummaries(id);
List<FeedSourceSummary> feedSourceSummaries = FeedSourceSummary.getFeedSourceSummaries(id, organizationId);
Map<String, FeedVersionSummary> latestFeedVersionForFeedSources = FeedSourceSummary.getLatestFeedVersionForFeedSources(id);
Map<String, FeedVersionSummary> deployedFeedVersions = FeedSourceSummary.getFeedVersionsFromPinnedDeployment(id);
if (deployedFeedVersions.isEmpty()) {
Expand Down
Loading

0 comments on commit 69a9b65

Please sign in to comment.