Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
194 commits
Select commit Hold shift + click to select a range
80d93af
Update .gitignore
rayluo Sep 1, 2016
404c5d3
A generic MsalError class
rayluo Aug 30, 2016
549ee7a
Scaffoldwith test case
rayluo Aug 31, 2016
d1be5f5
Experimental OAuth2 client secret flow
rayluo Sep 1, 2016
7bec95b
A generic low level oauth implementation
rayluo Sep 2, 2016
17bba2c
Bugfix: clean up the None value parameters when needed
rayluo Sep 2, 2016
323d04d
Refactor OAuth2 interface
rayluo Sep 2, 2016
5687d97
Start the work on Request middle layer
rayluo Sep 7, 2016
eb38e8b
Implement an AuthenticationResult equivalent
rayluo Sep 8, 2016
fc9cd84
Support using certificate as client credential
rayluo Sep 10, 2016
a185274
ClientCredentialRequest logic are now in its own class
rayluo Sep 13, 2016
972c0d5
Merge pull request #1 from AzureAD/client-credential
rayluo Sep 22, 2016
4f00884
Merge pull request #2 from AzureAD/client-credential-certificate
rayluo Sep 22, 2016
2b79b7e
Adjust the client_id parameter in AuthorizationCodeGrant.get_token()
rayluo Sep 14, 2016
33ab177
Implement get_token_by_refresh_token()
rayluo Sep 14, 2016
c879a9c
Adjust authorization_url() api
rayluo Sep 14, 2016
62871bf
Provide explicit client_secret in ClientCredentialGrant.get_token()
rayluo Sep 14, 2016
823b761
Add more documentation for OAuth2
rayluo Sep 17, 2016
80404f2
Fix a typo in AuithorizationCodeGrant
rayluo Sep 21, 2016
76c561c
Use Unicode in error message template
rayluo Sep 21, 2016
99c60ae
Give a better break point for a frequent error
rayluo Sep 22, 2016
438f118
Now scope parameter can accept list, set, tuple too
rayluo Sep 22, 2016
b589733
Defines a set of API for Authorization Code Grant
rayluo Sep 22, 2016
b7e159d
Addresses most TBD according to CR conclusion
rayluo Sep 28, 2016
5df3dce
oauth2.Client._get_token() accepts query params too
rayluo Sep 28, 2016
7ead4a3
Most acquisitions support policy now
rayluo Sep 28, 2016
0c1bb4a
Decorate scope in most grant flows
rayluo Sep 30, 2016
bab4d16
Merge pull request #3 from AzureAD/defining-interfaces
rayluo Oct 10, 2016
6527adc
Conditional end-to-end tests
rayluo Feb 2, 2017
ba30f5f
Include .travis.yml
rayluo Feb 2, 2017
e1ed342
Merge pull request #6 from AzureAD/travis-ci
rayluo Feb 2, 2017
56296b0
A self-contained test server
rayluo Jan 28, 2017
c96e3cf
Refactor test cases based on AuthCodeReceiver
rayluo Feb 1, 2017
e1744f2
Merge pull request #5 from AzureAD/test-server
rayluo Feb 2, 2017
5952ce7
Authority validation with instance discovery
rayluo Sep 28, 2016
2f11df4
Rejects tenant immediately followed by fragment
rayluo Sep 29, 2016
4edf439
Actually performs tenant discovery
rayluo Oct 3, 2016
48d6daf
Rename m to match_object
rayluo Oct 5, 2016
f6e5bed
Remove login.windows.net from implementation code base
rayluo Oct 5, 2016
063a4c1
Document the validate_authority behavior
rayluo Feb 2, 2017
7d18be8
Merge pull request #4 from AzureAD/authority
rayluo Feb 2, 2017
b05229e
Use authority rather than authority_url as the input parameter
rayluo Oct 11, 2016
f20c0fa
Adjust the None parameter behavior
rayluo Oct 12, 2016
1bcad65
Demote normalize_to_string() from root level function to internal method
rayluo Oct 18, 2016
aa82118
Provide better output in test cases
rayluo Feb 3, 2017
fa6c881
Introduce a default_body parameter in base class
rayluo Oct 12, 2016
4865563
Replace ClientCredentialRequest with oauth2.Client.default_body
rayluo Oct 18, 2016
f7817f9
RT grant and AC grant support client certificate
rayluo Oct 18, 2016
020cb38
Change super(ThisClass, self).foo() to self.foo()
rayluo Feb 4, 2017
d512539
Based on previous experiment, now decide to implement oauth2 Client a…
rayluo Feb 4, 2017
89746d3
Minor cleanup to prepare upcoming major revamp
rayluo Feb 18, 2017
1ab11de
New login.microsoftonline.us authority
rayluo Mar 8, 2017
75a378e
Merge branch 'new-authority' into dev
rayluo Mar 9, 2017
b99d464
Make authcode.py CLI tool generic
rayluo Mar 9, 2017
798aa77
Merge branch 'generic-authcode-cli' into dev
rayluo Mar 9, 2017
51d7ba1
Adjust error message per discussion with skwan
rayluo May 2, 2017
d7c32a2
Initial commit
rayluo Apr 2, 2018
0a36ca7
An OAUTH2 client with explicit params and data arguments
rayluo Apr 3, 2018
02fd5af
Refactor auth uri APIs
rayluo Apr 6, 2018
3394393
.gitignore ignores vim files
rayluo Apr 6, 2018
6f8d796
Stringify scope ascendingly
rayluo Apr 15, 2018
acc012f
RT storage
rayluo Apr 16, 2018
ba2579c
Unittest
rayluo Apr 16, 2018
f37de60
Client Credential Grant
rayluo Sep 22, 2018
1c6832b
OAuth2 U/P grant
rayluo Sep 23, 2018
d93a05d
Test case for auth code grant
rayluo Sep 24, 2018
6d0a718
Fix missing import
rayluo May 14, 2018
0c3c390
Test config file uses snake_case, which is used in RFC
rayluo May 14, 2018
8eb2246
Add test case for username password grant
rayluo May 16, 2018
6fd0a49
Merge branch 'prototype' into dev
rayluo Sep 24, 2018
a516eb3
Promote AuthCodeReceiver from tests to library
rayluo Sep 4, 2018
6c1a991
Refactor AuthCodeReceiver.acquire() to a plain function
rayluo Sep 4, 2018
34e7573
Merge branch 'authcode-receiver' into dev
rayluo Sep 24, 2018
66112d6
authcode.py now supports Python3
rayluo Sep 23, 2018
2612ae5
Granular tests/test_client.py
rayluo Sep 24, 2018
fb9cb38
Automatically set client_id in public client auth code grant
rayluo Sep 24, 2018
b8fb7cf
Close server properly
rayluo Sep 24, 2018
9c0d2a8
Loosely check auth code grant
rayluo Sep 24, 2018
8119dcc
Add force_fresh for acquire_token_for_client()
rayluo Sep 24, 2018
78eb988
Test app reads authority from configuration file now
rayluo Sep 25, 2018
96f0c8c
Authority adds new member instance and tenant
rayluo Sep 27, 2018
6680610
Token cache for Client Secret grant
rayluo Sep 28, 2018
2c18c4e
Supports client_info
rayluo Sep 28, 2018
666435b
Write IdTokens
rayluo Sep 28, 2018
1b40f96
Implements get_accounts() method, in order to call acquire_token_sile…
rayluo Oct 1, 2018
cc04a1c
Implements RT callbacks so that ATS(...) actually works with RT too
rayluo Oct 1, 2018
7857dcd
Remove the relic of ADAL cache implementation
rayluo Oct 1, 2018
b7357d4
Make TokenCache methods public, and documenting the persistence
rayluo Oct 2, 2018
f655f18
Write family_id flag into cache too
rayluo Oct 3, 2018
02d86ca
Adjust to new configuration api
rayluo Oct 3, 2018
35a7726
add(event) accepts a pure dict now
rayluo Oct 4, 2018
cc8c9e2
Refactor the assertLoosely(...) behavior to make it generic
rayluo Sep 30, 2018
3a4c3e1
Configuration via OpenID Connect Discovery
rayluo Oct 2, 2018
2af612a
Device Flow
rayluo Oct 3, 2018
07a5eac
Provide an optional polling behavior
rayluo Oct 3, 2018
1711aa7
Should have allowed extra data parameter
rayluo Oct 4, 2018
387decf
Merge branch 'device-flow' into dev
rayluo Oct 6, 2018
0ffffc9
Use logger instead of logging
rayluo Oct 6, 2018
5996dbd
Always do OIDC discovery
rayluo Oct 6, 2018
50264b4
Adds event listeners into Client
rayluo Sep 21, 2018
2d66281
Adjust on_obtaining_tokens(event) to a plain dict
rayluo Oct 3, 2018
42965f1
Merge branch 'events' into dev
rayluo Oct 8, 2018
836d98f
Supports obtaining token with assertion
rayluo Oct 24, 2018
db834da
Supports Confidential Client authenticating by certificate
rayluo Oct 24, 2018
8dc3bbc
Merge branch 'assertion' into dev
rayluo Oct 25, 2018
d9b2052
Refactor Oauth2TestCase and test logger
rayluo Oct 25, 2018
1ddddf4
Device Flow
rayluo Oct 6, 2018
81db8d2
Username password grant also support cache now
rayluo Oct 8, 2018
861f7fa
MEX
rayluo Oct 13, 2018
ea28a54
WsTrust
rayluo Oct 17, 2018
82e8eda
Implemented Username/Password grant for federated user
rayluo Oct 25, 2018
671495c
Confidential Client refactored
rayluo Oct 25, 2018
114d1bb
Adjust API document for oauth2.BaseClient.__init__()
rayluo Oct 31, 2018
2ea4a36
Adjusting API to make server_configuration a required parameter
rayluo Oct 31, 2018
f4678ff
Support default and adhoc headers, relay **kwargs to requests
rayluo Nov 1, 2018
2dde680
Refactor internal server configuration usage
rayluo Nov 1, 2018
49f4b1b
x-client-sku, x-client-ver, x-clinet-os, x-client-cpu
rayluo Nov 1, 2018
dd1c283
Add exit hint for obtain_auth_code() helper
rayluo Nov 5, 2018
8317201
Shorten some test case name for less typing on single case testing
rayluo Nov 9, 2018
a6af6fa
Clean up acquire_for_client(...) signature
rayluo Nov 9, 2018
4a74670
Rename obtain_token_with_client_credentials() to obtain_token_for_cli…
rayluo Nov 9, 2018
f3860e3
Rename obtain_token_with_authorization_code(...) to ...by...(...)
rayluo Nov 9, 2018
a76755a
Rename get_authorization_request_url(scope, ...) to ...(scopes, ...)
rayluo Nov 9, 2018
f11abec
Rename obtain_token_with_refresh_token(...) to ...by...(...)
rayluo Nov 12, 2018
8654230
Rename acquire_token_with_authorization_code(..., scope, ...) to ...b…
rayluo Nov 9, 2018
967e22c
Change device flow's scope into scopes
rayluo Nov 12, 2018
3f380c5
Change acquire_token_silent(scope, ...) to ...(scopes, ...)
rayluo Nov 12, 2018
e5769a5
Rename obtain_token_with_username_password(...) to ...by...(...)
rayluo Nov 15, 2018
ac99ccb
Rename obtain_token_with_assertion(...) to ...by...(...)
rayluo Nov 15, 2018
05d19b3
Change acquire_token_with_username_password(..., scope, ...) to ...by…
rayluo Nov 13, 2018
9971053
get_accounts(username='CaseInsensitiveUserName')
rayluo Nov 13, 2018
518711b
Clean up unused methods
rayluo Nov 15, 2018
cc23f9b
Support verify, proxies and timeout behavior
rayluo Nov 16, 2018
595dcde
Merge branch 'adjust-api-signatures' into dev
rayluo Nov 20, 2018
9079588
Implement verify, proxies, timeout based on requests.session
rayluo Nov 16, 2018
5c11bdb
Adjust device flow exit_condition signature and behavior
rayluo Nov 20, 2018
5528fe3
Adjust device flow api interface and behavior
rayluo Nov 21, 2018
17307d8
Using relative import for Python 3
rayluo Nov 21, 2018
1339821
Merge remote-tracking branch 'oauth2cli/dev' into oauth2
rayluo Nov 21, 2018
9013cb0
Preparation
rayluo Nov 21, 2018
e724682
Change from logger.warn(...) to logger.warning(...)
rayluo Nov 27, 2018
02030e9
Merge remote-tracking branch into oauth2
rayluo Nov 27, 2018
fad75c9
Merge branch 'oauth2' into assemble
rayluo Nov 27, 2018
87755a2
Remove oauth2rt.py implementation, for now
rayluo Nov 27, 2018
91dac7c
Minor readability adjustment
rayluo Nov 27, 2018
c2ea9a1
Version 0.1.0 which officially expose JwtSigner
rayluo Nov 27, 2018
85455c8
Merge branch oauth2cli into oauth2
rayluo Nov 27, 2018
c6181b1
Merge branch 'oauth2' into assemble
rayluo Nov 27, 2018
f6e9542
Assembling parts
rayluo Nov 27, 2018
4900eaf
tests can now be skipped when configuration is absent
rayluo Nov 27, 2018
1da7421
Merge remote branch into oauth2
rayluo Nov 27, 2018
b9e0128
Merge branch 'oauth2' into assemble
rayluo Nov 27, 2018
31e0d60
Adjust imports in test cases
rayluo Nov 27, 2018
5f79d27
Skip tests when tests/config.json is absent
rayluo Nov 27, 2018
e1beddf
Merge remote branch into oauth2
rayluo Nov 27, 2018
8338b3f
Merge branch 'oauth2' into assemble
rayluo Nov 27, 2018
9466088
Adjust a test case for Python 3
rayluo Nov 27, 2018
ea5ff4c
"Backport" FileNotFoundError to Python 2
rayluo Nov 27, 2018
6ec2f4a
Avoid accidentally commit tests/config.json
rayluo Nov 27, 2018
b791f8a
Merge remote branch into oauth2
rayluo Nov 27, 2018
088ef93
Merge branch 'oauth2' into assemble
rayluo Nov 27, 2018
317daed
Avoid emitting SkipTest exception b/c it halts Python2 unittest
rayluo Nov 28, 2018
87dbc05
Merge remote branch into oauth2
rayluo Nov 28, 2018
bed7f8b
Merge branch 'oauth2' into assemble
rayluo Nov 28, 2018
7ff35d7
Merge branch 'crossroads' into dev
rayluo Nov 30, 2018
6e2e5e3
Merge branch 'core' into dev
rayluo Nov 30, 2018
2349f5d
Merge branch 'federated' into dev
rayluo Nov 30, 2018
5971e53
Merge branch 'confidential-client' into dev
rayluo Nov 30, 2018
e0653fb
Merge branch 'refactor-server-configuration' into dev
rayluo Nov 30, 2018
ec803c7
Merge branch 'sku' into dev
rayluo Nov 30, 2018
54a6231
Merge branch 'cleanup-api-surface' into dev
rayluo Nov 30, 2018
9b7ba25
Merge branch 'assemble' into dev
rayluo Dec 1, 2018
d2f6d88
SerialzableTokenCache
rayluo Nov 30, 2018
d702d86
Merge branch 'serializable-cache' into dev
rayluo Dec 3, 2018
b547c99
Provides setup.py
rayluo Dec 5, 2018
16278c8
Make acquire_token_silent(..., account, ...) a required parameter
rayluo Dec 5, 2018
6efccb0
Demote Device Flow into subclass PublicClientApplication, for now
rayluo Dec 6, 2018
9495a2c
3 samples
rayluo Nov 30, 2018
89a1420
Use delegated scope for user scopes
rayluo Dec 3, 2018
eff46e5
Fix typos
rayluo Dec 5, 2018
1f9d674
Adjust descriptions based on latest API changes
rayluo Dec 5, 2018
92d094a
Merge pull request #7 from AzureAD/samples
rayluo Dec 6, 2018
97ef19d
Auto detect (sub)modules
rayluo Dec 7, 2018
70d6374
Merge branch 'packaging' into dev
rayluo Dec 7, 2018
b0d4a72
Create README.md
rayluo Dec 7, 2018
62666e6
Minor editorial change
rayluo Dec 7, 2018
ce1e067
Addressing PR comments
rayluo Dec 11, 2018
77908e7
Fix incorrect installation link
rayluo Dec 11, 2018
068741d
Creating contributing.md
rayluo Dec 11, 2018
2d7e426
Choose to NOT promote username password flow
rayluo Dec 11, 2018
5e5f3fc
Merge pull request #8 from AzureAD/readme
rayluo Dec 12, 2018
0ce5e37
Prepare release pipeline
rayluo Dec 11, 2018
3257532
Travis requires a workaround for Python 3.7
rayluo Dec 12, 2018
93c58b8
Prepare release 0.1.0
rayluo Dec 11, 2018
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
Prev Previous commit
Next Next commit
Decorate scope in most grant flows
  • Loading branch information
rayluo committed Sep 30, 2016
commit 0c1bb4af39af44fb8c9737ce8565e86b3bf39f04
22 changes: 13 additions & 9 deletions msal/application.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from . import oauth2
from .authority import Authority
from .request import decorate_scope
from .client_credential import ClientCredentialRequest


Expand All @@ -23,7 +24,8 @@ def acquire_token_silent(
client = oauth2.Client(self.client_id, token_endpoint=a.token_endpoint)
refresh_token = kwargs.get('refresh_token') # For testing purpose
response = client.get_token_by_refresh_token(
refresh_token, scope=scope,
refresh_token,
scope=decorate_scope(scope, self.client_id, policy),
client_secret=getattr(self, 'client_credential'), # TODO: JWT too
query={'policy': policy} if policy else None)
# TODO: refresh the refresh_token
Expand Down Expand Up @@ -80,7 +82,8 @@ def __init__(
def acquire_token_for_client(self, scope, policy=''):
return ClientCredentialRequest(
client_id=self.client_id, client_credential=self.client_credential,
scope=scope, policy=policy, authority=self.authority).run()
scope=scope, # This grant flow requires no scope decoration
policy=policy, authority=self.authority).run()

def get_authorization_request_url(
self,
Expand Down Expand Up @@ -111,7 +114,7 @@ def get_authorization_request_url(
self.client_id, authorization_endpoint=a.authorization_endpoint)
return grant.authorization_url(
redirect_uri=redirect_uri, state=state, login_hint=login_hint,
scope=scope, # TODO: handle additional_scope
scope=decorate_scope(scope, self.client_id, policy),
policy=policy if policy else None,
**(extra_query_params or {}))

Expand Down Expand Up @@ -143,15 +146,16 @@ def acquire_token_by_authorization_code(
So the developer need to specify a scope so that we can restrict the
token to be issued for the corresponding audience.
"""
# If absent, STS will give you a token associated to ONE of the scope
# sent in the authorization request, typically the very first one.
# So only omit this when you are working with only one scope.
scope = scope or ["openid", "email", "profile", "offline_access"] # TBD

# If scope is absent on the wire, STS will give you a token associated
# to the FIRST scope sent during the authorization request.
# So in theory, you can omit scope here when you were working with only
# one scope. But, MSAL decorates your scope anyway, so they are never
# really empty.
grant = oauth2.AuthorizationCodeGrant(
self.client_id, token_endpoint=self.authority.token_endpoint)
return grant.get_token(
code, scope=scope, redirect_uri=redirect_uri,
code, redirect_uri=redirect_uri,
scope=decorate_scope(scope, self.client_id, policy),
client_secret=self.client_credential, # TODO: Support certificate
query={'policy': policy} if policy else None)

Expand Down
30 changes: 30 additions & 0 deletions msal/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,36 @@
from .exceptions import MsalServiceError


def decorate_scope(
scope, client_id, policy,
reserved_scope=frozenset(['openid', 'profile', 'offline_access'])):
scope_set = set(scope) # Input scope is typically a list. Copy it to a set.
if scope_set & reserved_scope:
# These scopes are reserved for the API to provide good experience.
# We could make the developer pass these and then if they do they will
# come back asking why they don't see refresh token or user information.
raise ValueError(
"API does not accept {} value as user-provided scopes".format(
reserved_scope))
if client_id in scope_set:
if len(scope_set) > 1:
# We make developers pass their client id, so that they can express
# the intent that they want the token for themselves (their own
# app).
# If we do not restrict them to passing only client id then they
# could write code where they expect an id token but end up getting
# access_token.
raise ValueError("Client Id can only be provided as a single scope")
decorated = set(reserved_scope) # Make a writable copy
else:
decorated = scope_set | reserved_scope
if policy:
# special case b2c scenarios to not send email and profile as scopes
decorated.discard("email")
decorated.discard("profile")
return decorated


class BaseRequest(object):

def __init__(
Expand Down
8 changes: 4 additions & 4 deletions tests/test_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class TestConfidentialClientApplication(unittest.TestCase):
def test_confidential_client_using_secret(self):
app = ConfidentialClientApplication(
self.config['CLIENT_ID'], self.config['CLIENT_SECRET'])
result = app.acquire_token_for_client(self.scope, "policy")
result = app.acquire_token_for_client(self.scope)
self.assertIn('access_token', result)

def test_confidential_client_using_certificate(self):
Expand All @@ -27,7 +27,7 @@ def test_confidential_client_using_certificate(self):
}
app = ConfidentialClientApplication(
self.config['CLIENT_ID'], certificate)
result = app.acquire_token_for_client(self.scope, "policy")
result = app.acquire_token_for_client(self.scope)
self.assertIn('access_token', result)

def test_get_authorization_request_url(self):
Expand All @@ -41,10 +41,10 @@ def test_get_authorization_request_url(self):
def test_acquire_token_by_authorization_code(self):
app = ConfidentialClientApplication(
self.config['CLIENT_ID'], self.config['CLIENT_SECRET'])
auth_code = "OAQ...snipped..."
auth_code = self.config['AUTHORIZATION_CODE'] # TODO: It expires soon
token = app.acquire_token_by_authorization_code(auth_code, self.scope2)
self.assertEqual(token.get('error_description', ""), "") # Expired?
# print(token)
print(token) # Show your refresh token

def test_acquire_token_silent(self):
app = ConfidentialClientApplication(
Expand Down