def set_secret(keyvault_name: str, secret_name: str, value: str):
    if value:
        az_cli("keyvault secret set", "--name", secret_name, "--vault-name",
               keyvault_name, "--value", value)
    else:
        print("WARN: Provided secret '%s' value is empty, ignoring request " %
              secret_name)
Ejemplo n.º 2
0
def _add_member_to_group(existing_group_name: str,
                         user_or_identity_obj_id: str):
    is_member = az_cli("ad group member check", "--member-id",
                       user_or_identity_obj_id, "--group", existing_group_name,
                       "--query", "value")
    if not is_member:
        az_cli("ad group member add", "--member-id", user_or_identity_obj_id,
               "--group", existing_group_name)
Ejemplo n.º 3
0
def add_service_principal_delegated_permission(sp_app_id: str,
                                               api_resource_id: str,
                                               permission_id: str):
    rsp = az_cli("ad app permission add", "--id", sp_app_id, "--api",
                 api_resource_id, "--api-permissions",
                 "%s=Scope" % permission_id)
    print(rsp)
Ejemplo n.º 4
0
def add_role_assigment(role: str, ad_group_id: str, resource_group: str):
    """
    Adds role assigment for ad_group_id on resourec group level
    :param role: 
    :param ad_group_id: object ids for users, groups, service principals, and managed identities.
    :return: 
    """
    rsp = az_cli("role assignment create", "--role", role,
                 "--assignee-object-id", ad_group_id, "--resource-group",
                 resource_group)
    return rsp
def copy_search_index_definitions(resource_group: str, runtime_storage: str):
    storage_connection_str = az.az_cli(
        "storage account show-connection-string", "--resource-group",
        resource_group, "--name", runtime_storage, "--query",
        "connectionString")

    files = [
        'schema/indexes/azure_employees_index_definition.json',
        'schema/indexes/azure_mails_index_definition.json'
    ]
    _upload_data_from_local(runtime_storage=runtime_storage,
                            dest_container_name="deployment-artifacts",
                            dest_storage_connection_str=storage_connection_str,
                            files=files)
def copy_file(source_path: str, resource_group: str, runtime_storage: str,
              dest_container_name: str, dest_path):
    storage_connection_str = az.az_cli(
        "storage account show-connection-string", "--resource-group",
        resource_group, "--name", runtime_storage, "--query",
        "connectionString")

    dest_service = BlockBlobService(account_name=runtime_storage,
                                    connection_string=storage_connection_str)
    print("Copying %s into %s : %s/%s " %
          (source_path, runtime_storage, dest_container_name, dest_path))
    dest_service.create_blob_from_path(container_name=dest_container_name,
                                       blob_name=dest_path,
                                       file_path=source_path)
Ejemplo n.º 7
0
def _find_build_in_role(aad_app_id: str,
                        role_name: str = None,
                        permission_name: str = None):
    if not role_name and not permission_name:
        raise ValueError("role_name or permission_name must be provided")
    if role_name and permission_name:
        raise ValueError("role_name or permission_name are mutual exclusive")

    app = az_cli("ad sp show", "--id", aad_app_id, "--query",
                 "{Name:appDisplayName, Id:appId}")
    if app:
        app_id = app['Id']
        query = "appRoles[?value=='%s'].{Value:value, Id:id}" % role_name
        if permission_name:
            query = "oauth2Permissions[?value=='%s'].{Value:value, Id:id}" % permission_name
        roles_rsp = az_cli("ad sp show", "--id", app_id, "--query", query)
        if len(roles_rsp) == 1:
            role_id = roles_rsp[0]['Id']
            return {"appId": app_id, "id": role_id}
        else:
            print("Cant' find unique result for '%s' in '%s'" %
                  (role_name, aad_app_id))

    return None
Ejemplo n.º 8
0
def make_user_owner_for_app(user_object_id: str, app_id: str):
    return az_cli("ad app owner add --id", app_id, "--owner-object-id",
                  user_object_id)
Ejemplo n.º 9
0
def get_group_members(group_object_id: str):
    return az_cli("ad group member list --group", group_object_id)
Ejemplo n.º 10
0
def get_or_create_service_principal(name: str,
                                    tenant_id: str,
                                    non_interactive_mode: bool,
                                    create_if_not_exists: bool = True,
                                    credentials_valid_years: int = 1,
                                    is_web_app: bool = False,
                                    **kwargs):
    if is_web_app:
        assert 'reply_url' in kwargs
        assert 'logout_url' in kwargs

    if not non_interactive_mode:
        service_principal = dict()
        sp_accepted = False
        while not sp_accepted:
            existing_sps = az_cli(
                "ad sp list ", "--all", "--filter",
                "displayName eq '%s' " % name, "--query",
                "[?contains(appOwnerTenantId, '%s')]" % tenant_id)
            if len(existing_sps) > 1:
                print(
                    "There are multiple service principal found in your tenant "
                )
                if create_if_not_exists:
                    print(
                        "Please select unique name/objectId or enter new one to create: "
                    )
                else:
                    print("Please select unique name/objectId : ")
                print("appId\tName ")
                for sp in existing_sps:
                    print("%s\t%s" % (sp['appId'], sp['displayName']))
                app_id = input(
                    "If you want to use one of the service principals enter one of the app ids, otherwise press enter: "
                )
                selected_sp = None
                if app_id:
                    for sp in existing_sps:
                        if sp['appId'] == app_id:
                            selected_sp = sp
                            break
                else:
                    name = input("Enter a name for a new service principal: ")

                if selected_sp:
                    password = getpass.getpass(
                        prompt="Service Principal Secret")
                    conf_password = getpass.getpass(
                        prompt="Confirm Service Principal Secret")
                    service_principal = {
                        "appId": sp['appId'],
                        "password": password,
                        "name": name
                    }
                    sp_accepted = password != "" and password == conf_password
            elif len(existing_sps) == 1:
                sp = existing_sps[0]
                print(
                    "\nFound an existing service principal : %s, appId: %s. " %
                    (sp['displayName'], sp['appId']))
                print(
                    "The service principal with this name is required for the deployment process. You can either reuse this service principal or abort the deployment."
                )
                print(
                    "Reusing it requires you to provide a service principal client secret. "
                )
                print(
                    "If you are an owner of the service principal, you also have the option of creating a new secret and providing that (e.g. if you don't know the current one)."
                )
                sp_accepted = yes_no(
                    "Would you like to reuse the existing service principal? (y/n)"
                )
                print("\n")
                if sp_accepted:
                    password = getpass.getpass(
                        prompt="Service Principal Secret")
                    conf_password = getpass.getpass(
                        prompt="Confirm Service Principal Secret")
                    service_principal = {
                        "appId": sp['appId'],
                        "password": password,
                        "name": name
                    }
                    sp_accepted = password != "" and password == conf_password
                else:
                    name = input(
                        "Enter a name different from %s, that will be used to create a new service principal: "
                        % name)
            else:
                if create_if_not_exists:
                    if is_web_app:
                        service_principal = _create_web_app_service_principal(
                            display_name=name,
                            reply_url=kwargs['reply_url'],
                            logout_url=kwargs['logout_url'],
                            credentials_valid_years=credentials_valid_years)
                        sp_accepted = True
                    else:
                        sp = az_cli("ad sp create-for-rbac", "--name", name,
                                    "--years", str(credentials_valid_years))
                        service_principal = {
                            "appId": sp['appId'],
                            "password": sp['password'],
                            "name": name
                        }
                        sp_accepted = True
                else:
                    return None
    else:
        # if the application is running in non interactive mode even if there is a service principal
        # with the given name we will create a new one
        if is_web_app:
            service_principal = _create_web_app_service_principal(
                display_name=name,
                reply_url=kwargs['reply_url'],
                logout_url=kwargs['logout_url'],
                credentials_valid_years=credentials_valid_years)
        else:
            sp = az_cli("ad sp create-for-rbac", "--name", name, "--years",
                        str(credentials_valid_years))
            service_principal = {
                "appId": sp['appId'],
                "password": sp['password'],
                "name": name
            }

    return service_principal
Ejemplo n.º 11
0
def prompt_or_create_ad_group(msg: str,
                              tenant_id='default',
                              provided_ad_group_id: str = None,
                              create_if_not_exists=False,
                              no_input: bool = False,
                              add_signed_user: bool = False):
    """
     Prompt for existing or create a new AD group
    :param msg:
    :param tenant_id:
    :param create_if_not_exists:
    :param add_signed_user:
    :return:
    """
    group_accepted = False
    ad_group = provided_ad_group_id
    while not group_accepted:
        if not ad_group:
            ad_group = input(msg)
            print('\n')

        if is_valid_uuid(ad_group):
            rsp = az_cli("ad group list ", "--filter",
                         "objectId eq '%s' " % ad_group)
        else:
            rsp = az_cli("ad group list ", "--filter",
                         "displayname eq '%s' " % ad_group)
        if len(rsp) > 1:
            print("There are multiple groups found in your %s tenant " %
                  tenant_id)
            if create_if_not_exists:
                print(
                    "Please select unique name/objectId or enter new one to create: "
                )
            else:
                print("Please select unique name/objectId : ")
            print("ObjectId\tName ")
            for group in rsp:
                print("%s\t%s" % (group['objectId'], group['displayName']))
        elif len(rsp) == 1:
            group = rsp[0]
            if not no_input:
                group_accepted = yes_no(
                    "Selected group: %s, objectId: %s, confirm (y/n)" %
                    (group['displayName'], group['objectId']))
                # reset selection if not accepted to prompt again
                ad_group = ad_group if group_accepted else None
            else:
                # no confirmation needed for non-interactive mode
                group_accepted = True
        else:
            if create_if_not_exists:
                desc = "AD group for GDC app administrators. It manages full access to App resources and SQL database"
                az_cli(
                    "ad group create --display-name %s --mail-nickname %s " %
                    (ad_group, ad_group.lower()), "--description", desc)
                group_accepted = True

    group = az_cli("ad group show ", "--group", ad_group)
    if add_signed_user:
        _add_signed_user_to_group(existing_group_name=ad_group)

    return {
        "ad_group_name": group['displayName'],
        "objectId": group['objectId']
    }
Ejemplo n.º 12
0
def _create_web_app_service_principal(display_name,
                                      reply_url,
                                      logout_url,
                                      credentials_valid_years: int = 1):
    graph_permission = find_graph_user_read_permission()
    azure_service_management_permission = find_azure_service_management_user_impersonation_permission(
    )
    azure_storage_permission = find_azure_storage_user_impersonation_permission(
    )
    if not graph_permission:
        raise RuntimeError("Couldn't find 'User.Read' permission reference")
    if not azure_service_management_permission:
        raise RuntimeError(
            "Couldn't find 'user_impersonation' permission reference")
    tmp_file_name = "/tmp/" + str(uuid.uuid4()) + ".json"
    with open(tmp_file_name, mode="w") as fp:
        graphAppId = graph_permission['appId']
        graph_permission_id = graph_permission['id']
        azure_service_management_app_id = azure_service_management_permission[
            'appId']
        azure_service_management_permission_id = azure_service_management_permission[
            'id']
        azure_storage_app_id = azure_storage_permission['appId']
        azure_storage_permission_id = azure_storage_permission['id']
        permissions = [{
            "resourceAppId":
            graphAppId,
            "resourceAccess": [{
                "id": graph_permission_id,
                "type": "Scope"
            }]
        }, {
            "resourceAppId":
            azure_service_management_app_id,
            "resourceAccess": [{
                "id": azure_service_management_permission_id,
                "type": "Scope"
            }]
        }, {
            "resourceAppId":
            azure_storage_app_id,
            "resourceAccess": [{
                "id": azure_storage_permission_id,
                "type": "Scope"
            }]
        }]
        json.dump(permissions, fp)
        fp.flush()
    try:
        password = make_strong_password(42, '/+')
        start_date = date.today()
        end_date = date(start_date.year + credentials_valid_years,
                        start_date.month, start_date.day)
        rsp = az_cli("ad app create", "--available-to-other-tenants", "false",
                     "--password", password, "--display-name", display_name,
                     "--end-date", str(end_date), "--reply-urls", reply_url,
                     "--required-resource-accesses", "@%s" % tmp_file_name)
        _update_logout_url(logout_url, app_id=rsp['appId'])
        _update_group_membership_claims('SecurityGroup', app_id=rsp['appId'])

        service_principal = {
            "appId": rsp['appId'],
            "password": password,
            "name": display_name
        }
        return service_principal
    finally:
        if os.path.exists(tmp_file_name):
            try:
                os.remove(tmp_file_name)
            except BaseException as e:
                pass
Ejemplo n.º 13
0
def _update_group_membership_claims(groupMembershipClaims: str, app_id: str):
    az_cli("ad app update", "--id", app_id, "--set",
           "groupMembershipClaims=\"%s\"" % groupMembershipClaims)
Ejemplo n.º 14
0
def _update_logout_url(logout_url: str, app_id: str):
    az_cli("ad app update", "--id", app_id, "--set",
           "logoutUrl=\"%s\"" % logout_url)