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

Auth appended to the routing, no_auth + database_auth injected #5789

Closed
wants to merge 33 commits into from

Conversation

matborowczyk
Copy link
Collaborator

Description

Auth appended to the routing, no_auth injected, database_auth partially injected.

Request for the review as proposed to just verify if the approach is correct with what was agreed

closes #5759

Self Check:

Strike through any lines that are not applicable (~~line~~) then check the box

  • Attached issue to pull request
  • Changelog entry
  • Code is clear and sufficiently documented
  • Sufficient test cases (reproduces the bug/tests the requested feature)
  • Correct, in line with design
  • End user documentation is included or an issue is created for end-user documentation (add ref to issue here: )

children: React.ReactNode;
}

const DatabaseAuthProvider = ({ children }: AuthProviderProps) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why use the context and provider indirection? If the provider has the same interface you only construct this one and the context is the same for all of them?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We create context in the AuthContext.ts file, which then is accessed in the application through provider, where we also create distinction in the logic between each implementation. I don't know if I explained it clearly enough.

Copy link
Collaborator

@LukasStordeur LukasStordeur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see you're mixing the namings of the files and the folders.
image

Copy link
Collaborator

@LukasStordeur LukasStordeur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't focus on missing docstrings for now :)

value={{
...defaultAuthContext,
getToken: () => {
return "No token";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you have refactored the file with the interface, you'll see that you won't need the override of the value here and can simply either return the <GetAuthContext.Provider>{children}</GetAuthContext.Provider>
or do that in the switch case and remove this file; choice is yours on that. I don't mind having it in a separate file for matter of cleaner cut.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I know it's not possible to remove assignment of the "value" property. the interface assigned to the context is correct, but still errors is there:
Property 'value' is missing in type '{ children: ReactNode; }' but required in type 'ProviderProps<AuthContextInterface>'

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get why you need to override the defaults for no auth when no auth is the default. You can use the context as is in that case.

  const authContext= useContext(AuthContext);
  // rest of code
  return (
     <AuthContext.Provider value={authContext}>
         {children}
     </AuthContext.Provider>
  )

@@ -87,6 +94,7 @@ export const DependencyProvider: React.FC<{
authHelper: authHelper || new DummyAuthHelper(),
archiveHelper: archiveHelper || new DummyArchiveHelper(),
authController: authController || new DummyAuthController(),
useAuth: useAuth || defaultAuthContext,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defaultAuthContext not needed anymore if it's for free in the initialization in the authContext.ts file

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dependencies: Partial<Dependencies> indicates that any of dependencies properties can be undefined so it's required for the sake of the typescript(I think also tests would react differently, but that I didn't check, and I'm not 100% sure)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you update authContext.ts based on the example I gave you, useAuth will never be undefined because it has a default initialization, which is technically the noAuth one.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but undefined that is addressed here doesn't come from the useAuth itself but from the Partial<Dependencies> . authContext file got correct type

/**
* AuthProvider component renders the appropriate authentication provider based on the provided config
*
* @param config - The authentication configuration.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This "interface" should be 100% generic. I see config which makes me assume that this is the configuration provided by the backend but then there is still a keycloak specific parameter. This should not be the case:

  1. It should be clear what config is and I cannot deduce that from the code, the naming or the comments
  2. We should not have any authentication method specific parameters in here anymore.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed, and removed url parameter

/**
* Interface for the authentication context properties.
*/
export interface GetAuthProvider {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why an interface can have an action verb (get) in it's name. It describes how to interact with code that implements this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed

@matborowczyk matborowczyk marked this pull request as ready for review June 20, 2024 12:19
method: "oidc";
}

export interface LocalConfig {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this one in the KeycloakProvider?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was the top place that requires it, and when I had it in AuthProvider file it created circular dependency and I didn't feel like type.ts file is required here, but I can be mistaken.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving an export to another file should not be triggering circular dependency. If you have a circular dep issue, you might have forgotten to remove the import statement if you moved it to the file where it's used or adjust it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it does, at least madge complains when the interface is in the authprovider, app and tests works just fine

Copy link
Collaborator

@LukasStordeur LukasStordeur Jun 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it's only used in the authProvider component, so either;

  1. don't export it and declare it as an interface inside AuthProvider.
  2. since we are using a switch case on the config.method, perhaps this distinction isn't needed anymore and we can go for a more generic type which has the different possibilities for 'method : "oidc" | "database" | "other" | undefined

Edit: you have it in your tests, in two place, so AuthProvider can export it there, but you need to remove the LocalConfig from your imports in that file.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's reused, and in case of "oidc" the rest of the config is being passed to the keycloakProvider to create keycloak instance, I'll put it to the types.ts file to have it in "more correct" place

return <DatabaseAuthProvider>{children}</DatabaseAuthProvider>;
case "oidc":
return (
<KeycloakProvider config={config}>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't make sense to me. Any reason why you wrapped it like this instead of having the entire implementation in one file?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried it, but when it was in one file I couldn't reach the keycloak instance from the keycloakprovider. The logic has to be one level below initialisation of the context I guess

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A full application in React could hypothetically be written in one single component, we are splitting it up for readability and organization, but technically speaking, everything that can be achieved with multiple components can be done in one.

If you can't figure it out, which is fine, make a ticket for it, and at least, place all the elements/wrappers/parts concerning Keycloak in on single file. You should only call one Provider for Keycloak here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course it could be done, but then there would be no need for useContext. And as far as I know and searched context provider has to be one level higher that the component where we want to use given context.

I'll merge the files.

@LukasStordeur
Copy link
Collaborator

image oss-tests results

<ServiceInventory serviceName={service.name} service={service} />
</StoreProvider>
</DependencyProvider>
</AuthProvider>{" "}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
</AuthProvider>{" "}
</AuthProvider>

<StyledDiv>
<StyledDiv>
<div>
{authHelper.isDisabled() ? null : (
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{!authHelper.isDisabled() && <StyledText>{authHelper.getUser()}</StyledText>}

import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import { LoginPage } from "@/Slices/Login";
import { DependencyContext } from "@/UI/Dependency";
import { SearchSanitizer } from "@/UI/Routing";
import { GlobalStyles } from "@/UI/Styles";
import { NotFoundPage } from "@S/NotFound/UI";
import { KeycloakProvider, PageFrame, Initializer } from "./Components";
import RouteOutlet from "../Routing/RouteOutlet/RouteOutlet";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why have a separate folder for RouteOutlet?
And if you really want a separate folder, it should use an index file.

);
};

export default RouteOutlet;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

avoid export defaults

<StyledDiv>
<StyledDiv>
<div>
{!authHelper.isDisabled() ? (
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{!authHelper.isDisabled() && {authHelper.getUser()}}

There's no need for the ternary here. You changed the wrong line, there was nothing wrong with line 47.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still don't see the point in having a specific folder for the RouteOutlet. But fine.

@matborowczyk matborowczyk added the merge-tool-ready This ticket is ready to be merged in label Jun 25, 2024
@inmantaci
Copy link
Contributor

Processing this pull request

@inmantaci inmantaci removed the merge-tool-ready This ticket is ready to be merged in label Jun 25, 2024
@inmantaci
Copy link
Contributor

Pull request rejected by merge tool. No change entry file found

@matborowczyk matborowczyk added the merge-tool-ready This ticket is ready to be merged in label Jun 25, 2024
@inmantaci
Copy link
Contributor

Processing this pull request

inmantaci pushed a commit that referenced this pull request Jun 25, 2024
…nable and adjustable for new authentication providers (Issue #5759, PR #5789)

# Description

Auth appended to the routing, no_auth injected, database_auth partially injected.

Request for the review as proposed to just verify if the approach is correct with what was agreed

closes #5759

# Self Check:

Strike through any lines that are not applicable (`~~line~~`) then check the box

- [ ] Attached issue to pull request
- [ ] Changelog entry
- [ ] Code is clear and sufficiently documented
- [ ] Sufficient test cases (reproduces the bug/tests the requested feature)
- [ ] Correct, in line with design
- [ ] End user documentation is included or an issue is created for end-user documentation (add ref to issue here: )
@inmantaci
Copy link
Contributor

Merged into branches master, iso7 in 36a46bb

@inmantaci inmantaci closed this Jun 25, 2024
@inmantaci inmantaci deleted the issue/5759-auth-refactor branch June 25, 2024 15:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merge-tool-ready This ticket is ready to be merged in
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Authentication refactor
4 participants