Skip to content

Commit

Permalink
Merge branch 'master' into PRWLR-5496-review-behavior-of-kubernetes-c…
Browse files Browse the repository at this point in the history
…redentials
  • Loading branch information
MrCloudSec committed Nov 29, 2024
2 parents 11e0082 + 6dea923 commit 2fbea43
Show file tree
Hide file tree
Showing 22 changed files with 469 additions and 97 deletions.
16 changes: 8 additions & 8 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 0 additions & 13 deletions prowler/lib/check/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -556,19 +556,6 @@ def execute_checks(
bar()
bar.title = f"-> {Fore.GREEN}Scan completed!{Style.RESET_ALL}"

# Custom report interface
if os.environ.get("PROWLER_REPORT_LIB_PATH"):
try:
logger.info("Using custom report interface ...")
lib = os.environ["PROWLER_REPORT_LIB_PATH"]
outputs_module = importlib.import_module(lib)
custom_report_interface = getattr(outputs_module, "report")

# TODO: review this call and see if we can remove the global_provider.output_options since it is contained in the global_provider
custom_report_interface(check_findings, output_options, global_provider)
except Exception:
sys.exit(1)

return all_findings


Expand Down
5 changes: 1 addition & 4 deletions prowler/providers/aws/aws_regions_by_service.json
Original file line number Diff line number Diff line change
Expand Up @@ -9265,10 +9265,7 @@
"us-west-2"
],
"aws-cn": [],
"aws-us-gov": [
"us-gov-east-1",
"us-gov-west-1"
]
"aws-us-gov": []
}
},
"sagemaker-runtime": {
Expand Down
4 changes: 3 additions & 1 deletion prowler/providers/gcp/lib/service/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ def __is_api_active__(self, audited_project_ids):
project_ids = []
for project_id in audited_project_ids:
try:
client = discovery.build("serviceusage", "v1")
client = discovery.build(
"serviceusage", "v1", credentials=self.credentials
)
request = client.services().get(
name=f"projects/{project_id}/services/{self.service}.googleapis.com"
)
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ azure-mgmt-subscription = "3.1.1"
azure-mgmt-web = "7.3.1"
azure-storage-blob = "12.24.0"
boto3 = "1.35.70"
botocore = "1.35.70"
botocore = "1.35.71"
colorama = "0.4.6"
cryptography = "43.0.1"
dash = "2.18.2"
Expand All @@ -75,7 +75,7 @@ tabulate = "0.9.0"
tzlocal = "5.2"

[tool.poetry.group.dev.dependencies]
bandit = "1.7.10"
bandit = "1.8.0"
black = "24.10.0"
coverage = "7.6.8"
docker = "7.1.0"
Expand Down
37 changes: 25 additions & 12 deletions ui/actions/auth/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ export async function authenticate(
credentials: "Incorrect email or password",
},
};
case "CallbackRouteError":
return {
message: error.cause?.err?.message,
};
default:
return {
message: "Unknown error",
Expand Down Expand Up @@ -152,22 +156,31 @@ export const getUserByMe = async (accessToken: string) => {
},
});

if (!response.ok) throw new Error("Error in trying to get user by me");

const parsedResponse = await response.json();
if (!response.ok) {
// Handle different HTTP error codes
switch (response.status) {
case 401:
throw new Error("Invalid or expired token");
case 403:
throw new Error(parsedResponse.errors?.[0]?.detail);
case 404:
throw new Error("User not found");
default:
throw new Error(
parsedResponse.errors?.[0]?.detail || "Unknown error",
);
}
}

const name = parsedResponse.data.attributes.name;
const email = parsedResponse.data.attributes.email;
const company = parsedResponse.data.attributes.company_name;
const dateJoined = parsedResponse.data.attributes.date_joined;
return {
name,
email,
company,
dateJoined,
name: parsedResponse.data.attributes.name,
email: parsedResponse.data.attributes.email,
company: parsedResponse.data.attributes.company_name,
dateJoined: parsedResponse.data.attributes.date_joined,
};
} catch (error) {
throw new Error("Error in trying to get user by me");
} catch (error: any) {
throw new Error(error.message || "Network error or server unreachable");
}
};

Expand Down
28 changes: 28 additions & 0 deletions ui/actions/users/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,31 @@ export const deleteUser = async (formData: FormData) => {
};
}
};

export const getProfileInfo = async () => {
const session = await auth();
const keyServer = process.env.API_BASE_URL;
const url = new URL(`${keyServer}/users/me`);

try {
const response = await fetch(url.toString(), {
method: "GET",
headers: {
Accept: "application/vnd.api+json",
Authorization: `Bearer ${session?.accessToken}`,
},
});

if (!response.ok) {
throw new Error(`Failed to fetch user data: ${response.statusText}`);
}

const data = await response.json();
const parsedData = parseStringify(data);
revalidatePath("/profile");
return parsedData;
} catch (error) {
console.error("Error fetching profile:", error);
return undefined;
}
};
2 changes: 2 additions & 0 deletions ui/app/(prowler)/compliance/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,15 @@ const SSRComplianceGrid = async ({
const { attributes } = compliance;
const {
framework,
version,
requirements_status: { passed, total },
} = attributes;

return (
<ComplianceCard
key={compliance.id}
title={framework}
version={version}
passingRequirements={passed}
totalRequirements={total}
prevPassingRequirements={passed}
Expand Down
45 changes: 27 additions & 18 deletions ui/app/(prowler)/profile/page.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,39 @@
import { Spacer } from "@nextui-org/react";
import { redirect } from "next/navigation";
import React from "react";
import React, { Suspense } from "react";

// import { getUserByMe } from "@/actions/auth/auth";
import { auth } from "@/auth.config";
import { getProfileInfo } from "@/actions/users/users";
import { Header } from "@/components/ui";
import { SkeletonUserInfo } from "@/components/users/profile";
import { UserInfo } from "@/components/users/profile/user-info";
import { UserProfileProps } from "@/types";

export default async function Profile() {
const session = await auth();

if (!session?.user) {
// redirect("/sign-in?returnTo=/profile");
redirect("/sign-in");
}

// const user = await getUserByMe();

return (
<>
<Header title="User Profile" icon="ci:users" />
<Spacer y={4} />
<Spacer y={6} />
<pre>{JSON.stringify(session.user, null, 2)}</pre>
<pre>{JSON.stringify(session.userId, null, 2)}</pre>
<pre>{JSON.stringify(session.tenantId, null, 2)}</pre>
<pre>{JSON.stringify(session, null, 2)}</pre>
<div className="min-h-screen">
<div className="container mx-auto space-y-8 px-0 py-6">
<div className="grid grid-cols-12 gap-6">
<div className="col-span-12 lg:col-span-3">
<Suspense fallback={<SkeletonUserInfo />}>
<SSRDataUser />
</Suspense>
</div>
</div>
</div>
</div>
</>
);
}

const SSRDataUser = async () => {
const userProfile: UserProfileProps = await getProfileInfo();

return (
<>
<h3 className="mb-4 text-sm font-bold">User Info</h3>
<UserInfo user={userProfile?.data} />
</>
);
};
1 change: 1 addition & 0 deletions ui/auth.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export const authConfig = {
const isLoggedIn = !!auth?.user;
const isOnDashboard = nextUrl.pathname.startsWith("/");
const isSignUpPage = nextUrl.pathname === "/sign-up";
//CLOUD API CHANGES

// Allow access to sign-up page
if (isSignUpPage) return true;
Expand Down
12 changes: 10 additions & 2 deletions ui/components/auth/oss/auth-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ import { ApiError, authFormSchema } from "@/types";
export const AuthForm = ({
type,
invitationToken,
isCloudEnv,
}: {
type: string;
invitationToken?: string | null;
isCloudEnv?: boolean;
}) => {
const formSchema = authFormSchema(type);
const router = useRouter();
Expand Down Expand Up @@ -47,14 +49,15 @@ export const AuthForm = ({
email: data.email.toLowerCase(),
password: data.password,
});

if (result?.message === "Success") {
router.push("/");
} else if (result?.errors && "credentials" in result.errors) {
form.setError("email", {
type: "server",
message: result.errors.credentials ?? "Incorrect email or password",
});
} else if (result?.message === "User email is not verified") {
router.push("/email-verification");
} else {
toast({
variant: "destructive",
Expand All @@ -73,7 +76,12 @@ export const AuthForm = ({
description: "The user was registered successfully.",
});
form.reset();
router.push("/sign-in");

if (isCloudEnv) {
router.push("/email-verification");
} else {
router.push("/sign-in");
}
} else {
newUser.errors.forEach((error: ApiError) => {
const errorMessage = error.detail;
Expand Down
13 changes: 11 additions & 2 deletions ui/components/compliance/compliance-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { getComplianceIcon } from "../icons";

interface ComplianceCardProps {
title: string;
version: string;
passingRequirements: number;
totalRequirements: number;
prevPassingRequirements: number;
Expand All @@ -14,9 +15,14 @@ interface ComplianceCardProps {

export const ComplianceCard: React.FC<ComplianceCardProps> = ({
title,
version,
passingRequirements,
totalRequirements,
}) => {
const formatTitle = (title: string) => {
return title.split("-").join(" ");
};

const ratingPercentage = Math.floor(
(passingRequirements / totalRequirements) * 100,
);
Expand Down Expand Up @@ -47,7 +53,7 @@ export const ComplianceCard: React.FC<ComplianceCardProps> = ({
};

return (
<Card fullWidth isPressable isHoverable shadow="sm">
<Card fullWidth isHoverable shadow="sm">
<CardBody className="flex flex-row items-center justify-between space-x-4 dark:bg-prowler-blue-800">
<div className="flex w-full items-center space-x-4">
<Image
Expand All @@ -56,7 +62,10 @@ export const ComplianceCard: React.FC<ComplianceCardProps> = ({
className="h-10 w-10 min-w-10 rounded-md border-1 border-gray-300 bg-white object-contain p-1"
/>
<div className="flex w-full flex-col">
<h4 className="text-md font-bold leading-5 3xl:text-lg">{title}</h4>
<h4 className="text-md font-bold leading-5 3xl:text-lg">
{formatTitle(title)}
{version ? ` - ${version}` : ""}
</h4>
<Progress
label="Your Rating:"
size="sm"
Expand Down
10 changes: 9 additions & 1 deletion ui/components/compliance/data-compliance/data-compliance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,15 @@ export const DataCompliance = ({ scans, regions }: DataComplianceProps) => {
const searchParams = useSearchParams();
const [showClearButton, setShowClearButton] = useState(false);
const scanIdParam = searchParams.get("scanId");
const selectedScanId = scanIdParam || scans[0]?.id;
const selectedScanId = scanIdParam || (scans.length > 0 ? scans[0].id : "");

useEffect(() => {
if (!scanIdParam && scans.length > 0) {
const params = new URLSearchParams(searchParams);
params.set("scanId", scans[0].id);
router.push(`?${params.toString()}`);
}
}, [scans, scanIdParam, searchParams, router]);

useEffect(() => {
const hasFilters = Array.from(searchParams.keys()).some(
Expand Down
Loading

0 comments on commit 2fbea43

Please sign in to comment.