Skip to content

Commit

Permalink
Merge latest OS
Browse files Browse the repository at this point in the history
  • Loading branch information
noah-paige committed Oct 1, 2024
2 parents 00633e3 + 0931949 commit 831df25
Show file tree
Hide file tree
Showing 16 changed files with 338 additions and 50 deletions.
1 change: 1 addition & 0 deletions .github/workflows/bandit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ jobs:
- name: Install
run: |
python -m pip install --upgrade pip
python -m pip install typing-extensions
python -m pip install bandit
- name: Bandit
run: bandit -r -lll -ii .
2 changes: 2 additions & 0 deletions backend/dataall/modules/vote/db/vote_repositories.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ def get_vote(session, targetUri, targetType) -> [models.Vote]:
.filter(
models.Vote.targetUri == targetUri,
models.Vote.targetType == targetType,
models.Vote.username == get_context().username,
)
.first()
)
Expand All @@ -24,6 +25,7 @@ def upvote(session, targetUri: str, targetType: str, upvote: bool) -> [models.Vo
vote: models.Vote = (
session.query(models.Vote)
.filter(
models.Vote.username == get_context().username,
models.Vote.targetUri == targetUri,
models.Vote.targetType == targetType,
)
Expand Down
86 changes: 49 additions & 37 deletions backend/migrations/versions/075d344ae2cc_mf_triggers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,106 +7,118 @@
"""

from alembic import op
import sqlalchemy as sa
import os

# revision identifiers, used by Alembic.
revision = '075d344ae2cc'
down_revision = '427db8f31999'
branch_labels = None
depends_on = None

ENVNAME = os.getenv('envname', 'local')


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.execute("""
SQL_ORG_TRIGGER_DEF = """
CREATE OR REPLACE FUNCTION org_delete_trigger_function()
RETURNS TRIGGER AS $$
BEGIN
-- Delete from attached_metadata_form
DELETE FROM attached_metadata_form
DELETE FROM {SCHEMA_NAME}.attached_metadata_form
WHERE "entityUri" = OLD."organizationUri"
AND "entityType" = 'Organization';
-- Delete from metadata_form
DELETE FROM metadata_form
DELETE FROM {SCHEMA_NAME}.metadata_form
WHERE "homeEntity" = OLD."organizationUri"
AND visibility = 'Organization-Wide';
RETURN OLD;
END;
$$ LANGUAGE plpgsql;
""".format(SCHEMA_NAME=ENVNAME)

-- Create the trigger for organization table
SQL_ORG_TRIGGER_CREATE = """
CREATE TRIGGER org_delete_trigger
BEFORE DELETE ON organization
BEFORE DELETE ON {SCHEMA_NAME}.organization
FOR EACH ROW
EXECUTE FUNCTION org_delete_trigger_function();
""")
""".format(SCHEMA_NAME=ENVNAME)

op.execute(SQL_ORG_TRIGGER_DEF) # nosemgrep
op.execute(SQL_ORG_TRIGGER_CREATE) # nosemgrep

op.execute("""
CREATE OR REPLACE FUNCTION env_delete_trigger_function()
SQL_ENV_TRIGGER_DEF = """CREATE OR REPLACE FUNCTION env_delete_trigger_function()
RETURNS TRIGGER AS $$
BEGIN
-- Delete from attached_metadata_form
DELETE FROM attached_metadata_form
DELETE FROM {SCHEMA_NAME}.attached_metadata_form
WHERE "entityUri" = OLD."environmentUri"
AND "entityType" = 'Environment';
-- Delete from metadata_form
DELETE FROM metadata_form
DELETE FROM {SCHEMA_NAME}.metadata_form
WHERE "homeEntity" = OLD."environmentUri"
AND visibility = 'Environment-Wide';
RETURN OLD;
END;
$$ LANGUAGE plpgsql;
$$ LANGUAGE plpgsql;""".format(SCHEMA_NAME=ENVNAME)

-- Create the trigger for environment table
SQL_ENV_TRIGGER_CREATE = """
CREATE TRIGGER env_delete_trigger
BEFORE DELETE ON environment
BEFORE DELETE ON {SCHEMA_NAME}.environment
FOR EACH ROW
EXECUTE FUNCTION env_delete_trigger_function();
""")
""".format(SCHEMA_NAME=ENVNAME)

op.execute(SQL_ENV_TRIGGER_DEF) # nosemgrep
op.execute(SQL_ENV_TRIGGER_CREATE) # nosemgrep

op.execute("""
CREATE OR REPLACE FUNCTION dataset_delete_trigger_function()
SQL_DATASET_TRIGGER_DEF = """
CREATE OR REPLACE FUNCTION dataset_delete_trigger_function()
RETURNS TRIGGER AS $$
BEGIN
-- Delete from attached_metadata_form
DELETE FROM attached_metadata_form
DELETE FROM {SCHEMA_NAME}.attached_metadata_form
WHERE "entityUri" = OLD."datasetUri"
AND "entityType" = 'Dataset';
RETURN OLD;
END;
$$ LANGUAGE plpgsql;
$$ LANGUAGE plpgsql;""".format(SCHEMA_NAME=ENVNAME)

-- Create the trigger for dataset table
CREATE TRIGGER dataset_delete_trigger
BEFORE DELETE ON dataset
SQL_DATASET_TRIGGER_CREATE = """
CREATE TRIGGER dataset_delete_trigger
BEFORE DELETE ON {SCHEMA_NAME}.dataset
FOR EACH ROW
EXECUTE FUNCTION dataset_delete_trigger_function();
""")
EXECUTE FUNCTION dataset_delete_trigger_function();""".format(SCHEMA_NAME=ENVNAME)

op.execute(SQL_DATASET_TRIGGER_DEF) # nosemgrep
op.execute(SQL_DATASET_TRIGGER_CREATE) # nosemgrep

op.execute("""
SQL_RESOURCE_TRIGGER_DEF = """
CREATE OR REPLACE FUNCTION metadata_form_delete_trigger_function()
RETURNS TRIGGER AS $$
BEGIN
-- Delete from resource_permission_policy
DELETE FROM resource_policy_permission
WHERE "sid" in (SELECT sid from resource_policy where "resourceUri"=OLD.uri and "resourceType"='MetadataForm');
DELETE FROM resource_policy where "resourceUri"=OLD.uri;
DELETE FROM {SCHEMA_NAME}.resource_policy_permission
WHERE "sid" in (SELECT sid from {SCHEMA_NAME}.resource_policy where "resourceUri"=OLD.uri and "resourceType"='MetadataForm');
DELETE FROM {SCHEMA_NAME}.resource_policy where "resourceUri"=OLD.uri;
RETURN OLD;
END;
$$ LANGUAGE plpgsql;
$$ LANGUAGE plpgsql;""".format(SCHEMA_NAME=ENVNAME)

-- Create the trigger for dataset table
SQL_RESOURCE_TRIGGER_CREATE = """
CREATE TRIGGER metadata_form_delete_trigger
BEFORE DELETE ON metadata_form
BEFORE DELETE ON {SCHEMA_NAME}.metadata_form
FOR EACH ROW
EXECUTE FUNCTION metadata_form_delete_trigger_function();
""")
# ### end Alembic commands ###
EXECUTE FUNCTION metadata_form_delete_trigger_function();""".format(SCHEMA_NAME=ENVNAME)

op.execute(SQL_RESOURCE_TRIGGER_DEF) # nosemgrep
op.execute(SQL_RESOURCE_TRIGGER_CREATE) # nosemgrep
# # ### end Alembic commands ###


def downgrade():
Expand Down
12 changes: 10 additions & 2 deletions frontend/src/design/components/ObjectBrief.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ import {
CardHeader,
Chip,
Typography,
Divider
Divider,
useTheme
} from '@mui/material';
import { Label } from './Label';
import { createLinkMarkup } from 'utils';
import { SanitizedHTML } from 'design';

export const ObjectBrief = (props) => {
const {
Expand All @@ -24,6 +27,9 @@ export const ObjectBrief = (props) => {
...other
} = props;

const theme = useTheme();
const linkColor = theme.palette.primary.main;

return (
<Card {...other}>
{title && (
Expand Down Expand Up @@ -136,7 +142,9 @@ export const ObjectBrief = (props) => {
variant="subtitle2"
style={{ whiteSpace: 'pre-line' }}
>
{description}
<SanitizedHTML
dirtyHTML={createLinkMarkup(description, linkColor)}
/>
</Typography>
</Box>
)}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/design/components/SanitizedHTML.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import DOMPurify from 'dompurify';
export const SanitizedHTML = ({ dirtyHTML }) => {
const defaultOptions = {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a'],
ALLOWED_ATTR: ['href']
ALLOWED_ATTR: ['href', 'target', 'rel', 'style']
};

const sanitizedHtml = DOMPurify.sanitize(dirtyHTML, defaultOptions);
Expand Down
17 changes: 12 additions & 5 deletions frontend/src/modules/Shares/views/ShareView.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ import {
ShareHealthStatus,
TextAvatar,
useSettings,
Label
Label,
SanitizedHTML
} from 'design';
import { SET_ERROR, useDispatch } from 'globalErrors';
import { useClient } from 'services';
Expand All @@ -75,9 +76,10 @@ import {
UpdateRequestReason,
ShareItemFilterModal
} from '../components';
import { generateShareItemLabel } from 'utils';
import { generateShareItemLabel, createLinkMarkup } from 'utils';
import { ShareLogs } from '../components/ShareLogs';
import { ShareSubmitModal } from '../components/ShareSubmitModal';
import { useTheme } from '@mui/styles';
import { UpdateExtensionReason } from '../components/ShareUpdateExtension';
import CancelIcon from '@mui/icons-material/Close';

Expand Down Expand Up @@ -747,6 +749,8 @@ const ShareView = () => {
const dispatch = useDispatch();
const params = useParams();
const client = useClient();
const theme = useTheme();
const linkColor = theme.palette.primary.main;
const [loading, setLoading] = useState(true);
const [loadingShareItems, setLoadingShareItems] = useState(false);
const [isAddItemModalOpen, setIsAddItemModalOpen] = useState(false);
Expand Down Expand Up @@ -962,9 +966,12 @@ const ShareView = () => {
WebkitBoxOrient: 'vertical'
}}
>
{share.dataset.description.trim().length !== 0
? share.dataset.description
: 'No dataset description'}
<SanitizedHTML
dirtyHTML={createLinkMarkup(
share?.dataset?.description || '',
linkColor
)}
/>
</Typography>
</Box>
<Box sx={{ mt: 3 }}>
Expand Down
1 change: 1 addition & 0 deletions frontend/src/utils/helpers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './bytesToSize';
export * from './dayjs';
export * from './listToTree';
export * from './moduleUtils';
export * from './linkMarkup';
33 changes: 33 additions & 0 deletions frontend/src/utils/helpers/linkMarkup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
export const createLinkMarkup = (text, color) => {
// Define the components of the regex pattern

// Matches optional protocol (http:// or https://)
const protocol = '(https?://)?';

// Matches any domain or subdomain
const domain = '([a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}';

// Matches paths and query strings, excluding certain special characters
const pathAndQuery = '(\\/[^\\s()$@]*)?(\\?[\\w=&-]*)?(#[\\w\\-]*)?';

// Combine all parts into the final regex pattern
const urlRegex = new RegExp(
`(${protocol})?(${domain})(?=\\s|\\/|$)${pathAndQuery}(?=\\s|$)`,
'gi'
);

return text.replace(urlRegex, (fullMatch) => {
const decodedUrl = decodeURIComponent(fullMatch);

// Determine the correct href value for the anchor tag
let href = '';
if (decodedUrl.startsWith('https://') || decodedUrl.startsWith('http://')) {
href = decodedUrl;
} else {
href = `https://${decodedUrl}`;
}

// Return the HTML string for the anchor tag with the correct href and style
return `<a href="${href}" style="color: ${color};" target="_blank" rel="noopener noreferrer">${fullMatch}</a>`;
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ def test_get_organization_organization_with_admin_team(client1, org1):
assert_that(response.owner).is_equal_to(organization.owner)
assert_that(response.SamlGroupName).is_equal_to(organization.SamlGroupName)
assert_that(response.userRoleInOrganization).is_equal_to('Owner')
assert_that(response.stats.groups).is_equal_to(0)


def test_get_organization_with_invited_team(client2, org2):
Expand Down
64 changes: 64 additions & 0 deletions tests_new/integration_tests/modules/feed/queries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# TODO: This file will be replaced by using the SDK directly


def post_feed_message(client, target_uri, target_type, content):
query = {
'operationName': 'PostFeedMessage',
'variables': {
'targetUri': target_uri,
'targetType': target_type,
'input': {'content': content},
},
'query': """
mutation PostFeedMessage(
$targetUri: String!
$targetType: String!
$input: FeedMessageInput!
) {
postFeedMessage(
targetUri: $targetUri
targetType: $targetType
input: $input
) {
feedMessageUri
content
created
creator
}
}
""",
}
response = client.query(query=query)
return response.data.postFeedMessage


def get_feed(client, target_uri, target_type, filter={}):
query = {
'operationName': 'GetFeed',
'variables': {'targetUri': target_uri, 'targetType': target_type, 'filter': filter},
'query': """
query GetFeed(
$targetUri: String!
$targetType: String!
$filter: FeedMessageFilter
) {
getFeed(targetUri: $targetUri, targetType: $targetType) {
messages(filter: $filter) {
count
hasNext
hasPrevious
page
pages
nodes {
content
feedMessageUri
creator
created
}
}
}
}
""",
}
response = client.query(query=query)
return response.data.getFeed
Loading

0 comments on commit 831df25

Please sign in to comment.