GitHub API获取用户最后登录时间

5
我有一个GitHub组织,我想确定该组织中所有用户的最后登录日期。 我发现可以获取最后提交的方式,但是有些用户只进行拉取操作,因此这种方法行不通。 调用“/users/:user/events”没有返回结果。
2个回答

4
GitHub用户API事件API均不包含该信息。
我怀疑用户的最后登录时间被认为是“私人信息”,这意味着您不应该知道用户上次登录的时间。(隐私问题) GitHub隐私声明指出:“用户个人信息不包括聚合的,非个人身份识别信息”。用户的最后登录时间可能在此声明下被包括进来。

1
如果您拥有GitHub Enterprise Cloud,则可以使用审计日志确定最近90天是否有活动发生。
未经测试但可供参考的方法:
"""
Script to retrieve all audit events for a user.
Note need GitHub enterprise cloud 
"""

import csv
import os
import requests

# Fetch required values from environment variables
github_username = os.environ.get('GITHUB_USERNAME')
github_password = os.environ.get('GITHUB_PASSWORD')
github_base_url = os.environ.get('GITHUB_BASE_URL', 'https://api.github.com')
github_org = os.environ.get('GITHUB_ORG', 'my-org')
per_page = int(os.environ.get('PER_PAGE', 100))
csv_path = os.environ.get('CSV_PATH', 'output/permissions_for_team_repos.csv')

# Check credentials have been supplied
if not github_username or not github_password:
    raise ValueError('GITHUB_USERNAME and GITHUB_PASSWORD must be supplied')

# Prepare a requests session to reuse authentication configuration
# auth parameter will use basic auth automatically
session = requests.Session()
session.auth = (github_username, github_password)
session.headers = {'accept': 'application/vnd.github.v3+json'}

def generate_members():
    """
    Generator function to paginate through all organisation members (users)
    https://docs.github.com/en/rest/reference/orgs#list-organization-members
    """
    # Fetch the repositories for the specified team
    url = f"{github_base_url}/orgs/{github_org}/members"

    # Set pagination counters
    page = 1
    paginate = True

    # Paginate until there are no repos left
    while paginate:
        response = session.get(url, params={'per_page': per_page, 'page': page})
        if response.status_code > 399:
            raise Exception(f"GitHub API response code: {response.status_code}")
        members = response.json()
        records = len(members)
        # Check if the current page contains any records, if not continue looping
        if records == 0:
            paginate = False
        # Fetch source repo permissions
        for member in members:
            yield member
        # Increment page counter for next loop
        page += 1

def generate_member_audit_events(member_name):
    """
    Generator function to fetch organisation audit events for a specific member
    https://docs.github.com/en/rest/reference/orgs#get-the-audit-log-for-an-organization
    https://docs.github.com/en/organizations/keeping-your-organization-secure/reviewing-the-audit-log-for-your-organization
    """
    url = f"{github_base_url}/orgs/{github_org}/audit-log"

    # Set pagination counters
    page = 1
    paginate = True
    # Paginate until there are no teams left
    while paginate:
        response = session.get(url, params={'per_page': per_page, 'page': page, 'phrase': f'actor:{member_name}'})
        if response.status_code > 399:
            raise Exception(f"GitHub API response code: {response.status_code}")
        audit_events = response.json()
        records = len(audit_events)
        # Check if the current page contains any records, if not continue looping
        if records == 0:
            paginate = False
        # Fetch source repo permissions
        for audit_event in audit_events:
            yield audit_event
        # Increment page counter for next loop
        page += 1

with open(csv_path, 'w', newline='') as csvfile:
    fieldnames = ['member', 'member_type', 'site_admin', 'action', 'created_at']
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

    writer.writeheader()

    for member in generate_members():
        row = {'member': member['login'], 'member_type': member['type'], 'site_admin': member['site_admin']}
        for audit_event in generate_member_audit_events(member['login']):
            row['action'] = audit_event['action']
            row['created_at'] = audit_event['created_at']
            writer.writerow(row)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接