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

Adding oauthn #690

Merged
merged 72 commits into from
Dec 3, 2024
Merged

Adding oauthn #690

merged 72 commits into from
Dec 3, 2024

Conversation

ZohebShaikh
Copy link
Contributor

@ZohebShaikh ZohebShaikh commented Oct 25, 2024

Alternative to the authentication were investigated:-

Client Libraries

In the end I decided to not use them as we just need to make 2 requests and there is not that much error handling required as well ... We can look into integrating on of the above mentioned alternatives for the OAuth device flow integration.

Copy link

codecov bot commented Oct 25, 2024

Codecov Report

Attention: Patch coverage is 98.38710% with 4 lines in your changes missing coverage. Please review.

Project coverage is 93.10%. Comparing base (879ccee) to head (a614684).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/blueapi/service/main.py 87.50% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #690      +/-   ##
==========================================
+ Coverage   92.17%   93.10%   +0.92%     
==========================================
  Files          35       36       +1     
  Lines        1803     2030     +227     
==========================================
+ Hits         1662     1890     +228     
+ Misses        141      140       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

src/blueapi/cli/cli.py Outdated Show resolved Hide resolved
src/blueapi/cli/cli.py Outdated Show resolved Hide resolved
src/blueapi/cli/cli.py Outdated Show resolved Hide resolved
src/blueapi/cli/cli.py Outdated Show resolved Hide resolved
src/blueapi/cli/cli.py Outdated Show resolved Hide resolved
src/blueapi/service/authentication.py Outdated Show resolved Hide resolved
src/blueapi/service/authentication.py Outdated Show resolved Hide resolved
src/blueapi/service/authentication.py Outdated Show resolved Hide resolved
src/blueapi/service/authentication.py Outdated Show resolved Hide resolved
async def on_token_error_401(_: Request, __: Exception):
return JSONResponse(
status_code=status.HTTP_401_UNAUTHORIZED,
content={},
Copy link
Contributor

Choose a reason for hiding this comment

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

All challenges defined by this specification MUST use the auth-scheme
value "Bearer". This scheme MUST be followed by one or more
auth-param values. The auth-param attributes used or defined by this
specification are as follows. Other auth-param attributes MAY be
used as well.

If the protected resource request included an access token and failed
authentication, the resource server SHOULD include the "error"
attribute to provide the client with the reason why the access
request was declined.

3.1. Error Codes

 When a request fails, the resource server responds using the
 appropriate HTTP status code (typically, 400, 401, 403, or 405) and
 includes one of the following error codes in the response:

 invalid_request
       The request is missing a required parameter, includes an
       unsupported parameter or parameter value, repeats the same
       parameter, uses more than one method for including an access
       token, or is otherwise malformed.  The resource server SHOULD
       respond with the HTTP 400 (Bad Request) status code.

 invalid_token
       The access token provided is expired, revoked, malformed, or
       invalid for other reasons.  The resource SHOULD respond with
       the HTTP 401 (Unauthorized) status code.  The client MAY
       request a new access token and retry the protected resource
       request.

 insufficient_scope
       The request requires higher privileges than provided by the
       access token.  The resource server SHOULD respond with the HTTP
       403 (Forbidden) status code and MAY include the "scope"
       attribute with the scope necessary to access the protected
       resource.

 If the request lacks any authentication information (e.g., the client
 was unaware that authentication is necessary or attempted using an
 unsupported authentication method), the resource server SHOULD NOT
 include an error code or other error information.

Quotes end:
return JsonResponse(status_code=status.HTTP_401_UNAUTHORIZED, headers={"WWW-Authenticate": "Bearer realm=blueapi"})```

seems a reasonable first attempt. According to the spec we SHOULD check what type of JWTException we get and set the error appropriately too.

@ZohebShaikh
Copy link
Contributor Author

All challenges defined by this specification MUST use the auth-scheme
value "Bearer". This scheme MUST be followed by one or more
auth-param values. The auth-param attributes used or defined by this
specification are as follows. Other auth-param attributes MAY be
used as well.

If the protected resource request included an access token and failed
authentication, the resource server SHOULD include the "error"
attribute to provide the client with the reason why the access
request was declined.

[3.1](https://www.rfc-editor.org/rfc/rfc6750#section-3.1). Error Codes

When a request fails, the resource server responds using the
appropriate HTTP status code (typically, 400, 401, 403, or 405) and
includes one of the following error codes in the response:

invalid_request
The request is missing a required parameter, includes an
unsupported parameter or parameter value, repeats the same
parameter, uses more than one method for including an access
token, or is otherwise malformed. The resource server SHOULD
respond with the HTTP 400 (Bad Request) status code.

invalid_token
The access token provided is expired, revoked, malformed, or
invalid for other reasons. The resource SHOULD respond with
the HTTP 401 (Unauthorized) status code. The client MAY
request a new access token and retry the protected resource
request.

insufficient_scope
The request requires higher privileges than provided by the
access token. The resource server SHOULD respond with the HTTP
403 (Forbidden) status code and MAY include the "scope"
attribute with the scope necessary to access the protected
resource.

If the request lacks any authentication information (e.g., the client
was unaware that authentication is necessary or attempted using an
unsupported authentication method), the resource server SHOULD NOT
include an error code or other error information.

Quotes end:
return JsonResponse(status_code=status.HTTP_401_UNAUTHORIZED, headers={"WWW-Authenticate": "Bearer realm=blueapi"})```

seems a reasonable first attempt. According to the spec we SHOULD check what type of JWTException we get and set the error appropriately too.

I had a look at the fast api docs https://fastapi.tiangolo.com/advanced/security/oauth2-scopes/#global-view

They raise the following error

for scope in security_scopes.scopes:
    if scope not in token_data.scopes:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Not enough permissions",
            headers={"WWW-Authenticate": authenticate_value},
        )

I can add the check for scopes but currently we are not using scopes to decide on permissions ...I think we should add this when we do authz.

src/blueapi/service/authentication.py Outdated Show resolved Hide resolved
@@ -138,7 +138,7 @@ def wrapper(*args, **kwargs):
try:
func(*args, **kwargs)
except ConnectionError:
print("Failed to establish connection to FastAPI server.")
print("Failed to establish connection to Blueapi server.")
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there some agreement somewhere on how blueapi should be stylized? blueAPI/BlueApi,Blueapi etc?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is no agreement that I know of but I have seen three ways of using this blueapi ,Blueapi and BlueAPI<- added recently in tracing

Copy link
Contributor

Choose a reason for hiding this comment

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

image
I believe it's stylised blueapi

@@ -138,7 +138,7 @@ def wrapper(*args, **kwargs):
try:
func(*args, **kwargs)
except ConnectionError:
print("Failed to establish connection to FastAPI server.")
print("Failed to establish connection to Blueapi server.")
Copy link
Contributor

Choose a reason for hiding this comment

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

image
I believe it's stylised blueapi

@ZohebShaikh ZohebShaikh merged commit 71d536a into main Dec 3, 2024
29 checks passed
@ZohebShaikh ZohebShaikh deleted the adding-oauthn branch December 3, 2024 15:14
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.

3 participants