Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
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
132 changes: 132 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Microsoft Authentication Library (MSAL) for Python Preview

The MSAL library for Python enables your app to access the
[Microsoft Cloud](https://cloud.microsoft.com)
by supporting authentication of users with
[Microsoft Azure Active Directory accounts](https://azure.microsoft.com/en-us/services/active-directory/)
and [Microsoft Accounts](https://account.microsoft.com) using industry standard OAuth2 and OpenID Connect.
Soon MSAL Python will also support [Azure AD B2C](https://azure.microsoft.com/services/active-directory-b2c/).

More and more detail about MSAL Python functionality and usage will be documented in the
[Wiki](https://github.com/AzureAD/microsoft-authentication-library-for-python/wiki).

## Important Note about the MSAL Preview

This library is suitable for use in a production environment.
We provide the same production level support for this library as we do our current production libraries.
During the preview we may make changes to the API, internal cache format, and other mechanisms of this library,
which you will be required to take along with bug fixes or feature improvements.
This may impact your application.
For instance, a change to the cache format may impact your users, such as requiring them to sign in again.
An API change may require you to update your code.
When we provide the General Availability release
we will require you to update to the General Availability version within six months,
as applications written using a preview version of library may no longer work.

## Installation

1. If you haven't already, [install and/or upgrade the pip](https://pip.pypa.io/en/stable/installing/)
of your Python environment to a recent version. We tested with pip 18.1.
2. For now, you can install from our latest dev branch, by `pip install git+https://github.com/AzureAD/microsoft-authentication-library-for-python.git@dev`

## Usage

Before using MSAL Python (or any MSAL SDKs, for that matter), you will have to
[register your application with the AAD 2.0 endpoint](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-v2-register-an-app).

Acquiring tokens with MSAL Python need to follow this 3-step pattern.

1. MSAL proposes a clean separation between
[public client applications, and confidential client applications](https://tools.ietf.org/html/rfc6749#section-2.1).
So you will first create either a `PublicClientApplication` or a `ConfidentialClientApplication` instance,
and ideally reuse it during the lifecycle of your app. The following example shows a `PublicClientApplication`:

```python
from msal import PublicClientApplication
app = PublicClientApplication("your_client_id", authority="...")
```

Later, each time you would want an access token, you start by:
```python
result = None # It is just an initial value. Please follow instructions below.
```

2. The API model in MSAL provides you explicit control on how to utilize token cache.
This cache part is technically optional, but we highly recommend you to harness the power of MSAL cache.
It will automatically handle the token refresh for you.

```python
# We now check the cache to see
# whether we already have some accounts that the end user already used to sign in before.
accounts = app.get_accounts()
if accounts:
# If so, you could then somehow display these accounts and let end user choose
print("Pick the account you want to use to proceed:")
for a in accounts:
print(a["username"])
# Assuming the end user chose this one
chosen = accounts[0]
# Now let's try to find a token in cache for this account
result = app.acquire_token_silent(config["scope"], account=chosen)
```

3. Either there is no suitable token in the cache, or you chose to skip the previous step,
now it is time to actually send a request to AAD to obtain a token.
There are different methods based on your client type and scenario. Here we demonstrate a placeholder flow.

```python
if not result:
# So no suitable token exists in cache. Let's get a new one from AAD.
result = app.acquire_token_by_one_of_the_actual_method(..., scopes=["user.read"])
if "access_token" in result:
print(result["access_token"]) # Yay!
else:
print(result.get("error"))
print(result.get("error_description"))
print(result.get("correlation_id")) # You may need this when reporting a bug
```

That is it. There will be some variations for different flows.


## Samples and Documentation

The generic documents on
[Auth Scenarios](https://docs.microsoft.com/en-us/azure/active-directory/develop/authentication-scenarios)
and
[Auth protocols](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols)
are recommended reading.

The API reference of MSAL Python is coming soon.

You can try [runnable samples in this repo](https://github.com/AzureAD/microsoft-authentication-library-for-python/tree/dev/sample).


## Versions

This library follows [Semantic Versioning](http://semver.org/).

You can find the changes for each version under
[Releases](https://github.com/AzureAD/microsoft-authentication-library-for-python/releases).

## Community Help and Support

We leverage Stack Overflow to work with the community on supporting Azure Active Directory and its SDKs, including this one!
We highly recommend you ask your questions on Stack Overflow (we're all on there!)
Also browser existing issues to see if someone has had your question before.

We recommend you use the "msal" tag so we can see it!
Here is the latest Q&A on Stack Overflow for MSAL:
[http://stackoverflow.com/questions/tagged/msal](http://stackoverflow.com/questions/tagged/msal)

## Security Reporting

If you find a security issue with our libraries or services please report it to [[email protected]](mailto:[email protected]) with as much detail as possible. Your submission may be eligible for a bounty through the [Microsoft Bounty](http://aka.ms/bugbounty) program. Please do not post security issues to GitHub Issues or any other public site. We will contact you shortly upon receiving the information. We encourage you to get notifications of when security incidents occur by visiting [this page](https://technet.microsoft.com/en-us/security/dd252948) and subscribing to Security Advisory Alerts.

## Contributing

All code is licensed under the MIT license and we triage actively on GitHub. We enthusiastically welcome contributions and feedback. Please read the [contributing guide](./contributing.md) before starting.

## We Value and Adhere to the Microsoft Open Source Code of Conduct

This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [[email protected]](mailto:[email protected]) with any additional questions or comments.
122 changes: 122 additions & 0 deletions contributing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# CONTRIBUTING

Azure Active Directory SDK projects welcomes new contributors. This document will guide you
through the process.

### CONTRIBUTOR LICENSE AGREEMENT

Please visit [https://cla.microsoft.com/](https://cla.microsoft.com/) and sign the Contributor License
Agreement. You only need to do that once. We can not look at your code until you've submitted this request.


### FORK

Fork this project on GitHub and check out your copy.

Example for Project Foo (which can be any ADAL or MSAL or just any library):

```
$ git clone [email protected]:username/project-foo.git
$ cd project-foo
$ git remote add upstream [email protected]:AzureAD/project-foo.git
```

No need to decide if you want your feature or bug fix to go into the dev branch
or the master branch. **All bug fixes and new features should go into the dev branch.**

The master branch is effectively frozen; patches that change the SDKs
protocols or API surface area or affect the run-time behavior of the SDK will be rejected.

Some of our SDKs have bundled dependencies that are not part of the project proper.
Any changes to files in those directories or its subdirectories should be sent to their respective projects.
Do not send your patch to us, we cannot accept it.

In case of doubt, open an issue in the [issue tracker](issues).

Especially do so if you plan to work on a major change in functionality. Nothing is more
frustrating than seeing your hard work go to waste because your vision
does not align with our goals for the SDK.


### BRANCH

Okay, so you have decided on the proper branch. Create a feature branch
and start hacking:

```
$ git checkout -b my-feature-branch
```

### COMMIT

Make sure git knows your name and email address:

```
$ git config --global user.name "J. Random User"
$ git config --global user.email "[email protected]"
```

Writing good commit logs is important. A commit log should describe what
changed and why. Follow these guidelines when writing one:

1. The first line should be 50 characters or less and contain a short
description of the change prefixed with the name of the changed
subsystem (e.g. "net: add localAddress and localPort to Socket").
2. Keep the second line blank.
3. Wrap all other lines at 72 columns.

A good commit log looks like this:

```
fix: explaining the commit in one line

Body of commit message is a few lines of text, explaining things
in more detail, possibly giving some background about the issue
being fixed, etc etc.

The body of the commit message can be several paragraphs, and
please do proper word-wrap and keep columns shorter than about
72 characters or so. That way `git log` will show things
nicely even when it is indented.
```

The header line should be meaningful; it is what other people see when they
run `git shortlog` or `git log --oneline`.

Check the output of `git log --oneline files_that_you_changed` to find out
what directories your changes touch.


### REBASE

Use `git rebase` (not `git merge`) to sync your work from time to time.

```
$ git fetch upstream
$ git rebase upstream/v0.1 # or upstream/master
```


### TEST

Bug fixes and features should come with tests. Add your tests in the
test directory. This varies by repository but often follows the same convention of /src/test. Look at other tests to see how they should be
structured (license boilerplate, common includes, etc.).


Make sure that all tests pass.


### PUSH

```
$ git push origin my-feature-branch
```

Go to https://github.com/username/microsoft-authentication-library-for-***.git and select your feature branch. Click
the 'Pull Request' button and fill out the form.

Pull requests are usually reviewed within a few days. If there are comments
to address, apply your changes in a separate commit and push that to your
feature branch. Post a comment in the pull request afterwards; GitHub does
not send out notifications when you add commits.