async def handle_update_bundles(request):
    cwd = None
    try:
        unused_session, cwd = validateSession(request)
    except Exception as e:
        return web.Response(text="Invalid Session: {}".format(e), status=401)

    config = getTracConfig(cwd=cwd)
    tracUrl = config.get("TracUrl")
    credType = config.get("CredentialType", "").upper()
    parentTicketsField = config.get('UseParentTicketsFromInfoField')
    useAuthentication = len(credType) > 0
    user, password, ssId = "", "", None
    try:
        if useAuthentication:
            (user, password,
             ssId) = common_app_server.get_credentials(request, credType)
    except Exception as e:
        '''Credentials are not mandatory for update_bundles - so just pass'''

    logger.info("Handling 'Update Bundles'")
    res, auth_ok = await asyncio.wrap_future(
        ppe.submit(update_bundles, useAuthentication, user, password, tracUrl,
                   parentTicketsField, cwd))
    if not auth_ok:
        common_app_server.invalidate_credentials(ssId)
    logger.debug("Handling 'Update Bundles' finished")
    return web.json_response(res)
def get_managed_bundles(cwd):
    res = list()
    bundles = parseBundles(cwd=cwd)
    tracUrl = getTracConfig(cwd=cwd).get('TracUrl')
    for (unused_id, bundle) in sorted(bundles.items()):
        res.append(common_interfaces.ManagedBundle(bundle,
                                                   tracBaseUrl=tracUrl))
    return res
async def handle_required_auth(request):
    res = list()
    try:
        req = common_interfaces.AuthRequired_validate(
            json.loads(request.rel_url.query['authRequired']))
        availableRefs = set()
        for authRef in req['refs']:
            if common_app_server.is_valid_authRef(authRef):
                availableRefs.add(authRef['authId'])
        actionId = req['actionId']
        logger.debug("handle_required_auth for actionId '{}'".format(actionId))
        if actionId == "login":
            res.extend(
                getRequiredAuthForConfig(
                    availableRefs, getGitRepoConfig(), "RepoUrl",
                    "Please enter your {CredentialType} authentication data in order to clone the GIT Reposiory!"
                ))
        elif actionId == "bundleSync":
            cwd = None
            try:
                unused_session, cwd = validateSession(request)
            except Exception as e:
                return web.Response(text="Invalid Session: {}".format(e),
                                    status=401)
            res.extend(
                getRequiredAuthForConfig(
                    availableRefs, getTracConfig(cwd=cwd), "TracUrl",
                    "Please enter your {CredentialType} authentication data to sync with Trac!"
                ))
        elif actionId == "gitPullRebase":
            cwd = None
            try:
                unused_session, cwd = validateSession(request)
            except Exception as e:
                return web.Response(text="Invalid Session: {}".format(e),
                                    status=401)
            res.extend(
                getRequiredAuthForConfig(
                    availableRefs, getGitRepoConfig(cwd=cwd), "RepoUrl",
                    "Please enter your {CredentialType} authentication data to pull changes from the Git-Server!"
                ))
        elif actionId == "publishChanges":
            try:
                unused_session, cwd = validateSession(request)
            except Exception as e:
                return web.Response(text="Invalid Session: {}".format(e),
                                    status=401)
            res.extend(
                getRequiredAuthForConfig(
                    availableRefs, getGitRepoConfig(cwd=cwd), "RepoUrl",
                    "Please enter your {CredentialType} authentication data to publish changes to GIT!"
                ))
        return web.json_response(res)
    except Exception as e:
        return web.Response(text="Illegal Arguments Provided: {}".format(e),
                            status=400)
def get_managed_bundle_infos(bundleIds, cwd):
    repoSuites = getBundleRepoSuites(bundleIds, cwd=cwd)
    bundles = parseBundles(repoSuites,
                           selectIds=[str(s) for s in repoSuites],
                           cwd=cwd)
    tracUrl = getTracConfig(cwd=cwd).get('TracUrl')
    res = [
        common_interfaces.ManagedBundleInfo(bundle, tracBaseUrl=tracUrl)
        for bundle in bundles.values()
    ]
    return res
def cmd_jsondump(args):
    '''
        Dump bundle-infos to a json file.
    '''
    with open(args.outputFilename[0], "w", encoding="utf-8") as jsonFile:
        logger.info("Scanning Bundles")
        bundles = parseBundles(getBundleRepoSuites())
        config = getTracConfig()
        tracUrl = config.get('TracUrl')
        parentTicketsField = config.get('UseParentTicketsFromInfoField')
        logger.info("Extracting Bundle-Infos")
        bundleInfos = list()
        for bid, bundle in sorted(bundles.items()):
            logger.debug("Extracting Infos for {}".format(bid))
            bundleInfos.append(
                __extractBundleInfos(bundle, tracUrl, parentTicketsField))
        print(json.dumps(bundleInfos, sort_keys=True, indent=4), file=jsonFile)
    logger.info("Bundles-Infos SUCCESSFULLY dumped to file '{}'".format(
        args.outputFilename[0]))
def cmd_list(args):
    '''
        List all bundles grouped by their status / stage.
    '''
    bundles = parseBundles(getBundleRepoSuites())
    tracUrl = getTracConfig().get('TracUrl')
    nl = ""
    for status in BundleStatus:
        if args.stage and not status.getStage() == args.stage:
            continue
        selected = filterBundles(
            bundles, status if not args.candidates else status.getCandidates())
        if len(selected) > 0:
            headline = "{}{} '{}'{}:".format(
                nl, "Bundles with status" if not args.candidates else
                "Candidates for status", status, " (stage '" +
                status.getStage() + "')" if status.getStage() else "")
            if True:  # make it switchable later?
                print("{}\n{}".format(headline, "=" * len(headline)))
            listBundles(selected, tracUrl)
            nl = "\n"
def cmd_update_bundles(args):
    '''
        Updates the file `bundles` against the currently available (rolled out) bundles
        and synchronizes or creates the corresponding trac-Tickets.
    '''
    tracApi = None
    parentTicketsField = None
    if not args.no_trac:
        try:
            config = getTracConfig()
            parentTicketsField = config.get('UseParentTicketsFromInfoField')
            tracApi = trac_api.TracApi(config['TracUrl'], config.get('User'),
                                       config.get('Password'))
        except KeyError as e:
            logger.warn(
                "Missing Key {} in local trac configuration --> no synchronization with trac will be done!"
                .format(e))
        except Exception as e:
            logger.warn("Trac will not be synchronized: {}".format(e))

    updateBundles(tracApi, parentTicketsField=parentTicketsField)