0

I currently use selenium to login to Microsoft admin center and increase or decrease an office subscription of my choosing; however I want to try and use just the http requests library that comes with python to make my request.

Why I am doing this - I can't use the partner api to increase license to due to specific circumstances. I have access to my client's MS admin account and want to use python to increase a license when creating a user using the MS graph.

What I tried - I first tried to create http requests to login into MS....that didn't seem possible: Logging into Microsoft Online website programatically with C# & Difference between CSRF and X-CSRF-Token I tried but seems I need to find the xsrf token that gets generated when using the webpage normally.

So I decided to use selenium to login to MS, then figure out how to use the commerce API when you are logged into MS.

Here is my code:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.actions import action_builder
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.action_chains import ActionChains
from auths.AA_auth import interm_auth, otpauth
from selenium.common import exceptions
import time

import requests
import json
def browser_options():
    options = Options()
    options.headless = True
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    browser_options.browser = webdriver.Chrome(options=options)
    return browser_options.browser

def mslogin(msdata):
    #Go to the specific subscription in question
    browser_options.browser.get("https://admin.microsoft.com/Adminportal/Home?#/subscriptions/webdirect/ENTERSKUIDHERE")
    
    #Enter email
    ms_username = browser_options.browser.find_element_by_css_selector('#i0116')
    ms_username.send_keys("ENTERADMINEMAIL")

    wait = WebDriverWait(browser_options.browser, 10)
    wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#idSIButton9')))
    ms_usernameaccept = browser_options.browser.find_element_by_css_selector('#idSIButton9')
    ms_usernameaccept.send_keys(Keys.ENTER)

    #Enter password
    wait = WebDriverWait(browser_options.browser, 5)
    wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#i0118')))
    ms_password = browser_options.browser.find_element_by_css_selector('#i0118')
    ms_password.send_keys("ENTERADMINPASSWORD")

    wait = WebDriverWait(browser_options.browser, 10)
    wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#idSIButton9')))
    ms_passwordaccept = browser_options.browser.find_element_by_css_selector('#idSIButton9')
    ms_passwordaccept.send_keys(Keys.ENTER)

    #Getting past the reduced password inquiry webpage
    wait = WebDriverWait(browser_options.browser, 5)
    wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#idBtn_Back')))
    reducedlogingcancel = browser_options.browser.find_element_by_css_selector('#idBtn_Back')
    reducedlogingcancel.send_keys(Keys.ENTER)
    time.sleep(1)

    #Get cookieinfo
    request_cookies_browser =  browser_options.browser.get_cookies()
    browser_options.browser.close()
    print(request_cookies_browser)

    s = requests.Session()
    for cookie in request_cookies_browser:
        s.cookies.set(cookie['name'], cookie['value'])

    X = ENTERNUMBERHERE

    patchheaders = {
                "accept":"application/json, text/plain, */*",
                "content-type": "application/json",
            }
    licenseincrease = {
        "totalLicenses":X
    }
    licenseincrease_json = json.dumps(licenseincrease)
    getlicense = s.patch("https://admin.microsoft.com/fd/commerceapi/my-org/subscriptions/ENTERSKUIDHERE", headers=patchheaders, data=licenseincrease_json)
    getlicense_json = getlicense.json()
    print(getlicense_json)

However I was getting an error:

{Message: "There was an error processing the request.", StackTrace: "", ExceptionType: ""}

Is there something I am missing to fix this issue? OR Is there a better method to use the commerce API using http requests?

NOTE: (This is setup as a question and answer. If you have a better method of doing this please leave an answer or comment below)

VLAZ
  • 26,331
  • 9
  • 49
  • 67

1 Answers1

0

To make a patch request with the commerce api (when logged into MS) you need to add the s.AjaxSessionKey to the request. After you add the key, it should return back the subscription json data where you can check the total license amount:

patchheaders = {
                "accept":"application/json, text/plain, */*",
                "content-type": "application/json",
                "ajaxsessionkey":s.cookies.get("s.AjaxSessionKey")
            }