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

Multiple organization support #46

Conversation

xavierjurado
Copy link

Description

Add support to accounts with more than one organization.

Rationale

An organization_id is needed by most API requests because it's the only way to properly identify an application. We were assuming that an account was member of a single organization, so we made a request to /organizations right after we got a valid session and stored the identifier of the first object returned (as seen here: https://github.com/strongself/fabricio/blob/develop/lib/fabricio/authorization/authorization_client.rb#L118).

This is sadly not a valid approach for accounts linked to two or more organizations and can lead to issues like #45.

With this PR I've tried to solve this issue by building (and caching) an app_id to organization_id map (see OrganizationIdProvider class). I've done so lazily since this involves performing a new request in order to obtain the full list of applications for the account. Hopefully no performance loss should come from this because I've been able to delete the previous request to /organizations.

I'm new to this project and I'm not used to write Ruby so any feedback is more than welcomed!

@@ -54,10 +55,11 @@ def initialize(options =
@auth_client = Fabricio::Authorization::AuthorizationClient.new
session = obtain_session
network_client = Fabricio::Networking::NetworkClient.new(@auth_client, @session_storage)
organization_id_provider = Fabricio::Networking::OrganizationIdProvider.new(lambda { return @app_service.all })
Copy link
Author

Choose a reason for hiding this comment

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

I'm not 100% happy with this approach, but it's the easiest way I found to break the circular reference between OrganizationIdProvider and AppService without giving up constructor injection (the provider needs the service to lazily request the list of applications, and the service needs the provider to build some URLs via its model factory).

Copy link
Member

Choose a reason for hiding this comment

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

Looks ok to me

Copy link
Member

@etolstoy etolstoy left a comment

Choose a reason for hiding this comment

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

Thanks for contributing! I haven't encountered this problem before. @CognitiveDisson will review changes too and after that we'll merge the PR and update gem.

@@ -54,10 +55,11 @@ def initialize(options =
@auth_client = Fabricio::Authorization::AuthorizationClient.new
session = obtain_session
network_client = Fabricio::Networking::NetworkClient.new(@auth_client, @session_storage)
organization_id_provider = Fabricio::Networking::OrganizationIdProvider.new(lambda { return @app_service.all })
Copy link
Member

Choose a reason for hiding this comment

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

Looks ok to me

@etolstoy
Copy link
Member

We just discussed the implementation logic with @CognitiveDisson. It seems that hiding details of multiple organisations from the user isn't a good idea.
E.g. your account may belong to two organisations - work and personal. In this case it would be more convenient to explicitly choose the organisation for retrieving apps. Yes, the user is forced to pass more parameters - but that's another problem that can be solved by introducing query objects and builders.
So, if you'd like you can change the implementation to pass the organisation id explicitly for each request. However if you don't have enough time for that @CognitiveDisson soon will be able to do it himself.

@xavierjurado
Copy link
Author

Sure, I can do that, it should be easy! That being said, your approach will break existing clients since we will start asking for an extra argument in pretty much all the relevant app_service & build_service requests. Are you ok with that?

@eMxPi
Copy link

eMxPi commented Jan 24, 2018

Hi,

Any ETA on this feature?

Regarding the impact on previous versions, why don’t the gem use the first organisation found if not provided?

Regards

@CognitiveDisson
Copy link
Contributor

CognitiveDisson commented Feb 21, 2018

@eMxPi @xavierjurado Implement multiple organization support in #49 . If there are any problems please inform

@xavierjurado
Copy link
Author

xavierjurado commented Feb 24, 2018

Thanks for the update @CognitiveDisson. As far as I can see some requests in app_service such as crashfree() don't support accounts with multiple organisations. It should be easy to fix however.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants