async checkPullRequestSignatures(args, item) {
        const submitterSignatureRequired = config.server.feature_flag.required_signees.indexOf('submitter') > -1
        const committerSignatureRequired = !config.server.feature_flag.required_signees || config.server.feature_flag.required_signees.indexOf('committer') > -1
        const organizationOverrideEnabled = config.server.feature_flag.organization_override_enabled
        if (!item) {
            item = await this._getLinkedItem(args.repo, args.owner, args.token)
        }

        let signees = []
        var hasExternalCommiter = {
            check: false
        }

        if (!item) {
            throw new Error('No linked item found')
        }

        args.gist = item.gist
        args.repoId = item.repoId
        args.orgId = item.orgId
        args.onDates = [new Date()]

        if (!args.gist) {
            return ({
                signed: true
            })
        }
        // logger.debug(`checkPullRequestSignatures-->getGistObject for the repo ${args.owner}/${args.repo}`)
        const gist = await this._getGistObject(args.gist, item.token, args.owner)
        if (!gist) {
            throw new Error('No gist found for item')
        }
        args.gist_version = gist.data.history[0].version

        // logger.debug(`checkPullRequestSignatures-->getPR for the repo ${args.owner}/${args.repo}`)
        const pullRequest = (await this._getPR(args.owner, args.repo, args.number, item.token)).data
        if (!pullRequest) {
            throw new Error('No pull request found')
        }
        args.onDates.push(new Date(pullRequest.created_at))

        if (pullRequest.head && pullRequest.head.repo && pullRequest.head.repo.owner) {
            // check if the contribution comes from an Organization
            const isOrgHead = pullRequest.head.repo.owner.type === 'Organization'
            // check that this is actually a fork (and not just a branch in the same repo)
            const isForked = pullRequest.head.repo.fork
            // only if feature flag is enabled
            if (organizationOverrideEnabled && isOrgHead) {
                const {
                    owner: headOrg
                } = pullRequest.head.repo
                const {
                    owner: baseOrg
                } = pullRequest.base.repo
                if (item.isUserOnAllowlist !== undefined && item.isUserOnAllowlist(headOrg.login)) {
                    const orgMembers = await this._getGHOrgMembers(headOrg.login, item.token)
                    const committers = await repoService.getPRCommitters(args)
                    var externalCommitters = _.differenceBy(committers, orgMembers, 'id')
                    if ((!externalCommitters || externalCommitters.length === 0) || (baseOrg.login === headOrg.login && isForked === false)) {
                        return ({
                            signed: true
                        })
                    }

                    if (externalCommitters.length > 0 && isForked && baseOrg.login !== headOrg.login) {                   // filter out users explicitly mentioned on allowlist
                        externalCommitters = externalCommitters.filter(externalCommitter =>
                            externalCommitter && !(item.isUserOnAllowlist !== undefined && item.isUserOnAllowlist(externalCommitter.name))
                        )
                        hasExternalCommiter.check = true
                        hasExternalCommiter.orgName = headOrg.login
                        return this._checkAll(
                            externalCommitters,
                            item.repoId,
                            item.orgId,
                            item.sharedGist,
                            item.gist,
                            args.gist_version,
                            args.onDates,
                            hasExternalCommiter
                        )
                    }

                }
                const {
                    signed,
                    userMap
                } = await this._checkAll(
                    [{
                        name: headOrg.login,
                        id: headOrg.id
                    }],
                    item.repoId,
                    item.orgId,
                    item.sharedGist,
                    item.gist,
                    args.gist_version,
                    args.onDates,
                    hasExternalCommiter
                )
                if (signed && userMap.signed.includes(headOrg.login)) {
                    return ({
                        signed,
                        userMap
                    })
                }
            }
        }

        if (submitterSignatureRequired) { //TODO: test it
            signees.push({
                name: pullRequest.user.login,
                id: pullRequest.user.id
            })
        }

        if (committerSignatureRequired) {
            // logger.debug(`checkPullRequestSignatures-->getPRCommitters for the repo ${args.owner}/${args.repo}`)
            const committers = await repoService.getPRCommitters(args)
            signees = _.uniqWith([...signees, ...committers], (object, other) => object.id == other.id)
        }

        signees = signees.filter(signee =>
            signee && !(item.isUserOnAllowlist !== undefined && item.isUserOnAllowlist(signee.name))
        )

        // loop through the signees and check which ones belong to an excepted org
        const signeesNotExcluded = []
        for (const signee of signees) {
            // get org memberships for the signee
            const userOrgMemberships = await this._getGHOrgMemberships(signee.name, item.token, args.owner)

            // if one of the Organizations is on the allowlist we accept that as signature and don't need to look further
            const userOrgIsOnAllowlist = userOrgMemberships && userOrgMemberships.find(userOrgMembership => item.isOrgOnAllowlist && item.isOrgOnAllowlist(userOrgMembership.name))

            // if the user is not on the allowlist add them to the signeesNotExcluded array
            if (!userOrgIsOnAllowlist) {
                signeesNotExcluded.push(signee)
            }
        }

        return this._checkAll(
            signeesNotExcluded,
            item.repoId,
            item.orgId,
            item.sharedGist,
            item.gist,
            args.gist_version,
            args.onDates,
            hasExternalCommiter.check
        )
    }
/**
     * Check whether all committers signed the current cla at current moment or at the pull request moment.
     * Params:
     *   user (mandatory)
     *   number (mandatory)
     *   owner (mandatory)
     *   repo (optional)
     */
Check whether all committers signed the current cla at current moment or at the pull request moment.
Check whether all committers signed the current cla at current moment or at the pull request moment .
async checkPullRequestSignatures(args, item) {
        const submitterSignatureRequired = config.server.feature_flag.required_signees.indexOf('submitter') > -1
        const committerSignatureRequired = !config.server.feature_flag.required_signees || config.server.feature_flag.required_signees.indexOf('committer') > -1
        const organizationOverrideEnabled = config.server.feature_flag.organization_override_enabled
        if (!item) {
            item = await this._getLinkedItem(args.repo, args.owner, args.token)
        }
        let signees = []
        var hasExternalCommiter = {
            check: false
        }
        if (!item) {
            throw new Error('No linked item found')
        }
        args.gist = item.gist
        args.repoId = item.repoId
        args.orgId = item.orgId
        args.onDates = [new Date()]
        if (!args.gist) {
            return ({
                signed: true
            })
        }
        const gist = await this._getGistObject(args.gist, item.token, args.owner)
        if (!gist) {
            throw new Error('No gist found for item')
        }
        args.gist_version = gist.data.history[0].version
        const pullRequest = (await this._getPR(args.owner, args.repo, args.number, item.token)).data
        if (!pullRequest) {
            throw new Error('No pull request found')
        }
        args.onDates.push(new Date(pullRequest.created_at))
        if (pullRequest.head && pullRequest.head.repo && pullRequest.head.repo.owner) {
            const isOrgHead = pullRequest.head.repo.owner.type === 'Organization'
            const isForked = pullRequest.head.repo.fork
            if (organizationOverrideEnabled && isOrgHead) {
                const {
                    owner: headOrg
                } = pullRequest.head.repo
                const {
                    owner: baseOrg
                } = pullRequest.base.repo
                if (item.isUserOnAllowlist !== undefined && item.isUserOnAllowlist(headOrg.login)) {
                    const orgMembers = await this._getGHOrgMembers(headOrg.login, item.token)
                    const committers = await repoService.getPRCommitters(args)
                    var externalCommitters = _.differenceBy(committers, orgMembers, 'id')
                    if ((!externalCommitters || externalCommitters.length === 0) || (baseOrg.login === headOrg.login && isForked === false)) {
                        return ({
                            signed: true
                        })
                    }
                    if (externalCommitters.length > 0 && isForked && baseOrg.login !== headOrg.login) {                   
                        externalCommitters = externalCommitters.filter(externalCommitter =>
                            externalCommitter && !(item.isUserOnAllowlist !== undefined && item.isUserOnAllowlist(externalCommitter.name))
                        )
                        hasExternalCommiter.check = true
                        hasExternalCommiter.orgName = headOrg.login
                        return this._checkAll(
                            externalCommitters,
                            item.repoId,
                            item.orgId,
                            item.sharedGist,
                            item.gist,
                            args.gist_version,
                            args.onDates,
                            hasExternalCommiter
                        )
                    }
                }
                const {
                    signed,
                    userMap
                } = await this._checkAll(
                    [{
                        name: headOrg.login,
                        id: headOrg.id
                    }],
                    item.repoId,
                    item.orgId,
                    item.sharedGist,
                    item.gist,
                    args.gist_version,
                    args.onDates,
                    hasExternalCommiter
                )
                if (signed && userMap.signed.includes(headOrg.login)) {
                    return ({
                        signed,
                        userMap
                    })
                }
            }
        }
        if (submitterSignatureRequired) { 
            signees.push({
                name: pullRequest.user.login,
                id: pullRequest.user.id
            })
        }
        if (committerSignatureRequired) {
            const committers = await repoService.getPRCommitters(args)
            signees = _.uniqWith([...signees, ...committers], (object, other) => object.id == other.id)
        }
        signees = signees.filter(signee =>
            signee && !(item.isUserOnAllowlist !== undefined && item.isUserOnAllowlist(signee.name))
        )
        const signeesNotExcluded = []
        for (const signee of signees) {
            const userOrgMemberships = await this._getGHOrgMemberships(signee.name, item.token, args.owner)
            const userOrgIsOnAllowlist = userOrgMemberships && userOrgMemberships.find(userOrgMembership => item.isOrgOnAllowlist && item.isOrgOnAllowlist(userOrgMembership.name))
            if (!userOrgIsOnAllowlist) {
                signeesNotExcluded.push(signee)
            }
        }
        return this._checkAll(
            signeesNotExcluded,
            item.repoId,
            item.orgId,
            item.sharedGist,
            item.gist,
            args.gist_version,
            args.onDates,
            hasExternalCommiter.check
        )
    }
async checkPullRequestSignatures ( args , item ) { const submitterSignatureRequired = config . server . feature_flag . required_signees . indexOf ( 'submitter' ) > - 1 const committerSignatureRequired = ! config . server . feature_flag . required_signees || config . server . feature_flag . required_signees . indexOf ( 'committer' ) > - 1 const organizationOverrideEnabled = config . server . feature_flag . organization_override_enabled if ( ! item ) { item = await this . _getLinkedItem ( args . repo , args . owner , args . token ) } let signees = [ ] var hasExternalCommiter = { check : false } if ( ! item ) { throw new Error ( 'No linked item found' ) } args . gist = item . gist args . repoId = item . repoId args . orgId = item . orgId args . onDates = [ new Date ( ) ] if ( ! args . gist ) { return ( { signed : true } ) } const gist = await this . _getGistObject ( args . gist , item . token , args . owner ) if ( ! gist ) { throw new Error ( 'No gist found for item' ) } args . gist_version = gist . data . history [ 0 ] . version const pullRequest = ( await this . _getPR ( args . owner , args . repo , args . number , item . token ) ) . data if ( ! pullRequest ) { throw new Error ( 'No pull request found' ) } args . onDates . push ( new Date ( pullRequest . created_at ) ) if ( pullRequest . head && pullRequest . head . repo && pullRequest . head . repo . owner ) { const isOrgHead = pullRequest . head . repo . owner . type === 'Organization' const isForked = pullRequest . head . repo . fork if ( organizationOverrideEnabled && isOrgHead ) { const { owner : headOrg } = pullRequest . head . repo const { owner : baseOrg } = pullRequest . base . repo if ( item . isUserOnAllowlist !== undefined && item . isUserOnAllowlist ( headOrg . login ) ) { const orgMembers = await this . _getGHOrgMembers ( headOrg . login , item . token ) const committers = await repoService . getPRCommitters ( args ) var externalCommitters = _ . differenceBy ( committers , orgMembers , 'id' ) if ( ( ! externalCommitters || externalCommitters . length === 0 ) || ( baseOrg . login === headOrg . login && isForked === false ) ) { return ( { signed : true } ) } if ( externalCommitters . length > 0 && isForked && baseOrg . login !== headOrg . login ) { externalCommitters = externalCommitters . filter ( externalCommitter => externalCommitter && ! ( item . isUserOnAllowlist !== undefined && item . isUserOnAllowlist ( externalCommitter . name ) ) ) hasExternalCommiter . check = true hasExternalCommiter . orgName = headOrg . login return this . _checkAll ( externalCommitters , item . repoId , item . orgId , item . sharedGist , item . gist , args . gist_version , args . onDates , hasExternalCommiter ) } } const { signed , userMap } = await this . _checkAll ( [ { name : headOrg . login , id : headOrg . id } ] , item . repoId , item . orgId , item . sharedGist , item . gist , args . gist_version , args . onDates , hasExternalCommiter ) if ( signed && userMap . signed . includes ( headOrg . login ) ) { return ( { signed , userMap } ) } } } if ( submitterSignatureRequired ) { signees . push ( { name : pullRequest . user . login , id : pullRequest . user . id } ) } if ( committerSignatureRequired ) { const committers = await repoService . getPRCommitters ( args ) signees = _ . uniqWith ( [ ... signees , ... committers ] , ( object , other ) => object . id == other . id ) } signees = signees . filter ( signee => signee && ! ( item . isUserOnAllowlist !== undefined && item . isUserOnAllowlist ( signee . name ) ) ) const signeesNotExcluded = [ ] for ( const signee of signees ) { const userOrgMemberships = await this . _getGHOrgMemberships ( signee . name , item . token , args . owner ) const userOrgIsOnAllowlist = userOrgMemberships && userOrgMemberships . find ( userOrgMembership => item . isOrgOnAllowlist && item . isOrgOnAllowlist ( userOrgMembership . name ) ) if ( ! userOrgIsOnAllowlist ) { signeesNotExcluded . push ( signee ) } } return this . _checkAll ( signeesNotExcluded , item . repoId , item . orgId , item . sharedGist , item . gist , args . gist_version , args . onDates , hasExternalCommiter . check ) }
Check whether all committers signed the current cla at current moment or at the pull request moment.
Check whether all committers signed the current cla at current moment or at the pull request moment .
// logger.debug(`checkPullRequestSignatures-->getGistObject for the repo ${args.owner}/${args.repo}`) // logger.debug(`checkPullRequestSignatures-->getPR for the repo ${args.owner}/${args.repo}`) // check if the contribution comes from an Organization // check that this is actually a fork (and not just a branch in the same repo) // only if feature flag is enabled // filter out users explicitly mentioned on allowlist //TODO: test it // logger.debug(`checkPullRequestSignatures-->getPRCommitters for the repo ${args.owner}/${args.repo}`) // loop through the signees and check which ones belong to an excepted org // get org memberships for the signee // if one of the Organizations is on the allowlist we accept that as signature and don't need to look further // if the user is not on the allowlist add them to the signeesNotExcluded array