Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add complexity checks #1358

Merged
merged 3 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion apps/api/lib/api_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ defmodule ApiWeb.Router do

forward "/", Absinthe.Plug,
schema: GraphQl,
document_providers: [GraphQl.APQ, Absinthe.Plug.DocumentProvider.Default]
document_providers: [GraphQl.APQ, Absinthe.Plug.DocumentProvider.Default],
analyze_complexity: true,
max_complexity: 500,
token_limit: 5_000
end

scope "/", ApiWeb do
Expand Down
2 changes: 2 additions & 0 deletions apps/core/lib/core/schema/user.ex
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ defmodule Core.Schema.User do
timestamps()
end

def intercom_id(%__MODULE__{id: id}), do: Core.sha("#{id}:#{Core.conf(:intercom_salt)}")

def service_account(query \\ __MODULE__, is_svc \\ :yes)

def service_account(query, :yes) do
Expand Down
6 changes: 6 additions & 0 deletions apps/graphql/lib/graphql/schema/user.ex
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,12 @@ defmodule GraphQl.Schema.User do
_, _, _ -> {:error, "forbidden"}
end

field :intercom_id, :string, resolve: fn
%{id: id} = user, _, %{context: %{current_user: %{id: id}}} ->
{:ok, Schema.User.intercom_id(user)}
_, _, _ -> {:error, "you can only read your own intercom id"}
end

field :has_installations, :boolean, resolve: fn
user, _, _ -> {:ok, Core.Services.Users.has_installations?(user)}
end
Expand Down
19 changes: 19 additions & 0 deletions apps/graphql/test/queries/user_queries_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,25 @@ defmodule GraphQl.UserQueriesTest do
assert length(me["boundRoles"]) == 1
end

test "it can fetch an intercom id" do
user = insert(:user)
insert(:role_binding, user: user, group_id: nil)

{:ok, %{data: %{"me" => me}}} = run_query("""
query {
me {
id
name
intercomId
}
}
""", %{}, %{current_user: Core.Services.Rbac.preload(user)})

assert me["id"] == user.id
assert me["name"] == user.name
assert me["intercomId"] && me["intercomId"] != user.id
end

test "It will mark user as demoed if demo_count reaches the limit" do
user = insert(:user, demo_count: 3)

Expand Down
1 change: 1 addition & 0 deletions config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ config :core,
mgmt_repo: "https://github.com/pluralsh/plural.git",
cockroach_parameters: [],
bootstrap_ssl: true,
intercom_salt: "intercomsalt",
cloud_domain: "cloud.plural.sh"

config :briefly,
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ defmodule Plural.MixProject do
{:shards, "~> 1.0"},
{:ecto, "~> 3.9.0", override: true},
{:hackney, "~> 1.18.1", override: true},
{:absinthe_plug, "~> 1.5.8"},
{:absinthe_plug, "~> 1.5.8", git: "https://github.com/absinthe-graphql/absinthe_plug.git", commit: "3a984cc341ebb32c79e7ae58b4ebd116d5c62f9e", override: true},
{:credo, "~> 1.6", only: [:dev, :test], runtime: false},
{:sobelow, "~> 0.8", only: :dev},
{:excoveralls, "~> 0.10", only: :test},
Expand Down
6 changes: 3 additions & 3 deletions mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"absinthe": {:hex, :absinthe, "1.7.8", "43443d12ad2b4fcce60e257ac71caf3081f3d5c4ddd5eac63a02628bcaf5b556", [:mix], [{:dataloader, "~> 1.0.0 or ~> 2.0", [hex: :dataloader, repo: "hexpm", optional: true]}, {:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:opentelemetry_process_propagator, "~> 0.2.1 or ~> 0.3", [hex: :opentelemetry_process_propagator, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c4085df201892a498384f997649aedb37a4ce8a726c170d5b5617ed3bf45d40b"},
"absinthe_client": {:hex, :absinthe_client, "0.1.1", "1e778d587a27b85ecc35e4a5fedc64c85d9fdfd05395745c7af5345564dff54e", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:req, "~> 0.4", [hex: :req, repo: "hexpm", optional: false]}, {:slipstream, "~> 1.0", [hex: :slipstream, repo: "hexpm", optional: false]}], "hexpm", "e75a28c5bb647f485e9c03bbc3a47e7783742794bd4c10f3307a495a9e7273b6"},
"absinthe_phoenix": {:hex, :absinthe_phoenix, "2.0.2", "e607b438db900049b9b3760f8ecd0591017a46122fffed7057bf6989020992b5", [:mix], [{:absinthe, "~> 1.5", [hex: :absinthe, repo: "hexpm", optional: false]}, {:absinthe_plug, "~> 1.5", [hex: :absinthe_plug, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.5", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.13 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}], "hexpm", "d36918925c380dc7d2ed7d039c9a3b4182ec36723f7417a68745ade5aab22f8d"},
"absinthe_plug": {:hex, :absinthe_plug, "1.5.8", "38d230641ba9dca8f72f1fed2dfc8abd53b3907d1996363da32434ab6ee5d6ab", [:mix], [{:absinthe, "~> 1.5", [hex: :absinthe, repo: "hexpm", optional: false]}, {:plug, "~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bbb04176647b735828861e7b2705465e53e2cf54ccf5a73ddd1ebd855f996e5a"},
"absinthe_plug": {:git, "https://github.com/absinthe-graphql/absinthe_plug.git", "3a984cc341ebb32c79e7ae58b4ebd116d5c62f9e", []},
"absinthe_relay": {:hex, :absinthe_relay, "1.5.2", "cfb8aed70f4e4c7718d3f1c212332d2ea728f17c7fc0f68f1e461f0f5f0c4b9a", [:mix], [{:absinthe, "~> 1.5.0 or ~> 1.6.0 or ~> 1.7.0", [hex: :absinthe, repo: "hexpm", optional: false]}, {:ecto, "~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "0587ee913afa31512e1457a5064ee88427f8fe7bcfbeeecd41c71d9cff0b62b6"},
"accept": {:hex, :accept, "0.3.5", "b33b127abca7cc948bbe6caa4c263369abf1347cfa9d8e699c6d214660f10cd1", [:rebar3], [], "hexpm", "11b18c220bcc2eab63b5470c038ef10eb6783bcb1fcdb11aa4137defa5ac1bb8"},
"amqp": {:hex, :amqp, "3.2.0", "51e85e06e4d283d98f21dce95906e42cb181fc7ceeb967b33b3be73d6ea41aa5", [:mix], [{:amqp_client, "~> 3.9.1", [hex: :amqp_client, repo: "hexpm", optional: false]}], "hexpm", "1439570336df6e79000239938fb055a0944dc9a768b4dec0af1375404508a014"},
Expand Down Expand Up @@ -121,9 +121,9 @@
"phoenix_template": {:hex, :phoenix_template, "1.0.0", "c57bc5044f25f007dc86ab21895688c098a9f846a8dda6bc40e2d0ddc146e38f", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "1b066f99a26fd22064c12b2600a9a6e56700f591bf7b20b418054ea38b4d4357"},
"phoenix_view": {:hex, :phoenix_view, "2.0.2", "6bd4d2fd595ef80d33b439ede6a19326b78f0f1d8d62b9a318e3d9c1af351098", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}], "hexpm", "a929e7230ea5c7ee0e149ffcf44ce7cf7f4b6d2bfe1752dd7c084cdff152d36f"},
"piazza_core": {:git, "https://github.com/michaeljguarino/piazza_core", "ebbda3cff4f49f5ec647a28c03a3dd3ce03766db", []},
"plug": {:hex, :plug, "1.14.0", "ba4f558468f69cbd9f6b356d25443d0b796fbdc887e03fa89001384a9cac638f", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "bf020432c7d4feb7b3af16a0c2701455cbbbb95e5b6866132cb09eb0c29adc14"},
"plug": {:hex, :plug, "1.16.1", "40c74619c12f82736d2214557dedec2e9762029b2438d6d175c5074c933edc9d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a13ff6b9006b03d7e33874945b2755253841b238c34071ed85b0e86057f8cddc"},
"plug_cowboy": {:hex, :plug_cowboy, "2.6.0", "d1cf12ff96a1ca4f52207c5271a6c351a4733f413803488d75b70ccf44aebec2", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "073cf20b753ce6682ed72905cd62a2d4bd9bad1bf9f7feb02a1b8e525bd94fa6"},
"plug_crypto": {:hex, :plug_crypto, "1.2.3", "8f77d13aeb32bfd9e654cb68f0af517b371fb34c56c9f2b58fe3df1235c1251a", [:mix], [], "hexpm", "b5672099c6ad5c202c45f5a403f21a3411247f164e4a8fab056e5cd8a290f4a2"},
"plug_crypto": {:hex, :plug_crypto, "1.2.5", "918772575e48e81e455818229bf719d4ab4181fcbf7f85b68a35620f78d89ced", [:mix], [], "hexpm", "26549a1d6345e2172eb1c233866756ae44a9609bd33ee6f99147ab3fd87fd842"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm", "fec8660eb7733ee4117b85f55799fd3833eb769a6df71ccf8903e8dc5447cfce"},
"poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"},
"porcelain": {:hex, :porcelain, "2.0.3", "2d77b17d1f21fed875b8c5ecba72a01533db2013bd2e5e62c6d286c029150fdc", [:mix], [], "hexpm", "dc996ab8fadbc09912c787c7ab8673065e50ea1a6245177b0c24569013d23620"},
Expand Down
4 changes: 4 additions & 0 deletions rel/config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ if get_env("SYSBOX_WHITELIST") do
config :core, :sysbox_emails, String.split(get_env("SYSBOX_WHITELIST"), ",")
end

if get_env("INTERCOM_SALT") do
config :core, intercom_salt: get_env("INTERCOM_SALT")
end

config :workos,
client_id: get_env("WORKOS_CLIENT_ID"),
api_key: get_env("WORKOS_API_KEY")
Expand Down
2 changes: 2 additions & 0 deletions schema/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -3358,6 +3358,8 @@ type User {

jwt: String

intercomId: String

hasInstallations: Boolean

demoing: Boolean
Expand Down
29 changes: 1 addition & 28 deletions www/src/components/Plural.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { Suspense, lazy, useEffect, useState } from 'react'
import { Suspense, lazy } from 'react'
import { Navigate, Outlet, Route, Routes, useMatch } from 'react-router-dom'
import { Toast } from '@pluralsh/design-system'

import { growthbook } from '../helpers/growthbook'
import { useHistory } from '../router'

import { WrapStripe } from './WrapStripe'
Expand Down Expand Up @@ -288,30 +286,6 @@ function OAuthOrFallback() {
)
}

function TestBanner() {
const [enable, setEnable] = useState(true)

useEffect(() => {
const timeout = setTimeout(() => setEnable(false), 5000)

return () => clearTimeout(timeout)
}, [])

if (growthbook.isOn('growthbook-test') && enable) {
return (
<Toast
severity="success"
marginBottom="medium"
marginRight="xxxxlarge"
>
Growthbook Test!
</Toast>
)
}

return null
}

export function PluralInner() {
return (
<WrapStripe>
Expand All @@ -322,7 +296,6 @@ export function PluralInner() {
<LegacyExpirationNotice />
<VerifyEmailConfirmed />
<DeviceLoginNotif />
<TestBanner />
<Routes>
{/* --- OAUTH --- */}
{/* TODO: Enable if route will be used by the app */}
Expand Down
8 changes: 1 addition & 7 deletions www/src/components/login/CurrentUser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
setToken,
wipeToken,
} from '../../helpers/authentication'
import { growthbook } from '../../helpers/growthbook'
import { useNotificationSubscription } from '../../hooks/useNotificationSubscription'
import BillingPlatformPlansProvider from '../account/billing/BillingPlatformPlansProvider'
import BillingSubscriptionProvider from '../account/billing/BillingSubscriptionProvider'
Expand Down Expand Up @@ -66,12 +65,7 @@ export function PluralProvider({ children }: any) {
if (!data?.me) return
const { me } = data

boot({ name: me.name, email: me.email, userId: me.id })
growthbook.setAttributes({
company: me.account.name,
id: me.id,
email: me.email,
})
boot({ name: me.name, email: me.email, userId: me.intercomId || me.id })
}, [data, boot])

useEffect(() => {
Expand Down
4 changes: 1 addition & 3 deletions www/src/components/marketplace/MarketplaceRepositories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ import orderBy from 'lodash/orderBy'

import { upperFirst } from 'lodash'

import { growthbook } from '../../helpers/growthbook'

import { ResponsiveLayoutSidecarContainer } from '../utils/layout/ResponsiveLayoutSidecarContainer'
import { ResponsiveLayoutSpacer } from '../utils/layout/ResponsiveLayoutSpacer'

Expand Down Expand Up @@ -109,7 +107,7 @@ function MarketplaceRepositories({ publisher }: { publisher?: any }) {

const isFiltered = !isEmpty(categories) || !isEmpty(tags)
const isFilteredOrSearched = isFiltered || search
const shouldRenderStacks = growthbook.isOn('stacks') && !isFilteredOrSearched
const shouldRenderStacks = !isFilteredOrSearched

useEffect(() => {
const { current } = scrollRef
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ import { useContext, useEffect, useState } from 'react'

import { FormField, ListBoxItem, Select } from '@pluralsh/design-system'

import { growthbook } from '../../../../../helpers/growthbook'
import { CloudProvider, CloudProviderDisplayName } from '../../context/types'
import { OnboardingContext } from '../../context/onboarding'

import Provider from './provider/Provider'

const CLOUDS = Object.values(CloudProvider)
const GROWTHBOOK_AZURE_CLOUD_KEY = 'azure-cloud-shell'

interface ProviderItem {
key: string
Expand All @@ -21,11 +19,7 @@ function CloudCredentials() {
const [provider, setProvider] = useState<CloudProvider>(
cloud?.provider || CloudProvider.AWS
)
const providers = (
growthbook.isOn(GROWTHBOOK_AZURE_CLOUD_KEY)
? CLOUDS
: CLOUDS.filter((c) => c !== CloudProvider.Azure)
).map<ProviderItem>((c) => ({
const providers = CLOUDS.map<ProviderItem>((c) => ({
key: c,
label: CloudProviderDisplayName[c],
}))
Expand Down
Loading
Loading