xref: /web-master/manage/github.php (revision 48cb59d3)
1<?php // vim: et ts=2 sw=2
2
3// This script evolved from a quick'n'dirty shell script. If you are reading
4// this feel free to clean it!
5
6require '../include/login.inc';
7
8@include './github-config.php';
9if (!defined('GITHUB_CLIENT_ID') || !defined('GITHUB_CLIENT_SECRET')) {
10  die('GITHUB_CLIENT_ID or GITHUB_CLIENT_SECRET not defined. Please verify ./github-config.php');
11}
12
13define('GITHUB_PHP_OWNER_TEAM_ID', 65141);
14define('GITHUB_REPO_TEAM_ID', 138591);
15if (!defined('GITHUB_USER_AGENT')) {
16  define('GITHUB_USER_AGENT', 'php.net repository management (master.php.net, systems@php.net, johannes@php.net)');
17}
18
19function github_api($endpoint, $method = 'GET', $options = [])
20{
21  $options['method'] = $method;
22  $options['user_agent'] = GITHUB_USER_AGENT;
23
24  $ctxt = stream_context_create(['http' => $options]);
25
26  $url = 'https://api.github.com'.$endpoint;
27  $s = @file_get_contents($url, false, $ctxt);
28  if ($s === false) {
29    die('Request to GitHub failed. Endpoint: '.$endpoint);
30  }
31
32  $retval = json_decode($s);
33  return $retval;
34}
35
36function github_current_user($access_token = false)
37{
38  if (!$access_token) {
39    $access_token = $_SESSION['github']['access_token'];
40  }
41
42  if (empty($_SESSION['github']['current_user'])) {
43    $user = github_api('/user?access_token='.urlencode($access_token));
44    if (!$user->login) {
45      die('Failed to get current user');
46    }
47
48    $_SESSION['github']['current_user'] = $user;
49  }
50
51  return $_SESSION['github']['current_user'];
52}
53
54function github_require_valid_user()
55{
56  if (isset($_SESSION['github']['access_token'])) {
57    return true;
58  }
59
60  if (isset($_GET['code'])) {
61    $data = [
62      'client_id' => GITHUB_CLIENT_ID,
63      'client_secret' => GITHUB_CLIENT_SECRET,
64      'code' => $_GET['code']
65    ];
66    $data_encoded = http_build_query($data);
67    $opts = [
68      'method' => 'POST',
69      'user_agent' => GITHUB_USER_AGENT,
70      'header'  => 'Content-type: application/x-www-form-urlencoded',
71      'content' => $data_encoded,
72    ];
73    $ctxt = stream_context_create(['http' => $opts]);
74    $s = @file_get_contents('https://github.com/login/oauth/access_token', false, $ctxt);
75    if (!$s) {
76      die('Failed while checking with GitHub,either you are trying to hack us or our configuration is wrong (GITHUB_CLIENT_SECRET outdated?)');
77    }
78    $gh = [];
79    parse_str($s, $gh);
80    if (empty($gh['access_token'])) {
81      die("GitHub responded but didn't send an access_token");
82    }
83
84    $user = github_current_user($gh['access_token']);
85
86    $endpoint = '/teams/'.urlencode((string)GITHUB_PHP_OWNER_TEAM_ID).'/members/'.urlencode($user->login);
87    $opts = ['user_agent' => GITHUB_USER_AGENT];
88    $ctxt = stream_context_create(['http' => $opts]);
89    $is_member = file_get_contents('https://api.github.com'.$endpoint.'?access_token='.urlencode($gh['access_token']), false, $ctxt);
90
91    if ($is_member === false) {
92      head("github administration");
93      echo '<h1>You (Authenticated GitHub user: '.htmlentities($user->login). ') are no member of the php organization on github.</h1>'.
94        '<p>Please contact an existing member if you see need.</p>';
95      foot();
96      exit;
97    }
98    // SUCCESS
99    $_SESSION['github']['access_token'] = $gh['access_token'];
100    header('Location: github.php');
101    exit;
102  }
103
104  // Start oauth
105  header('Location: https://github.com/login/oauth/authorize?scope=repo&client_id='.urlencode(GITHUB_CLIENT_ID));
106  exit;
107}
108
109if (isset($_POST['description']) && isset($_SESSION['github']['access_token'])) {
110  action_create_repo();
111} elseif (isset($_GET['login']) || isset($_GET['code']) || isset($_SESSION['github']['access_token'])) {
112  action_form();
113} else {
114  action_default();
115}
116
117function action_default()
118{
119  head("github administration");
120  echo '<p>This tool is for administrating PHP repos on GitHub. Currently it is used for adding repos only.</p>';
121  echo '<p><b>NOTE:</b> Only members of the PHP organisation on GitHub can use this tool. We try to keep the number of members limited.</p>';
122  echo '<p>In case you are a member you can <a href="github.php?login=1">login using GitHub</a>.</p>';
123  foot();
124}
125
126function action_form()
127{
128  github_require_valid_user();
129  $user = $_SESSION['github']['current_user'];
130  head("github administration");
131?>
132<p><b>GitHub user: </b> <?php echo htmlentities($user->login); ?></p>
133<p>Creating a GitHub repo using this form ensures the proper configuration. This
134includes disabling the GitHub wiki and issue tracker as well as enabling the
135php-pulls user to push changes made on git.php.net.</p>
136<p>The name, description and homepage should follow other existing repositories.</p>
137<form method="post" action="github.php">
138Github repo name: http://github.com/php/<input name="name"> (i.e. pecl-category-foobar)<br>
139Description: <input name="description"> (i.e. PECL foobar extension)<br>
140Homepage: <input name="homepage"> (i.e. http://pecl.php.net/package/foobar)<br>
141<input type="submit" value="Create Repository on GitHub">
142<input type="hidden" name="action" value="create">
143<?php
144  foot();
145}
146
147function action_create_repo()
148{
149  github_require_valid_user();
150
151  $data = [
152    'name' => $_POST['name'],
153    'description' => $_POST['description'],
154
155    'homepage' => $_POST['homepage'],
156    'private' => false,
157    'has_issues' => false,
158    'has_wiki' => false,
159    'has_downloads' => false,
160    'team_id' => GITHUB_REPO_TEAM_ID,
161  ];
162  $data_j = json_encode($data);
163  $opts = [
164    'content' => $data_j,
165  ];
166  $res = github_api('/orgs/php/repos?access_token='.urlencode($_SESSION['github']['access_token']), 'POST', $opts);
167
168  head("github administration");
169  if (isset($res->html_url)) {
170    echo '<p>Repo created!</p><p><a href="'.htmlentities($res->html_url, ENT_QUOTES).'">Check on GitHub</a>.</p>';
171  } else {
172    echo "Error while creating repo.";
173  }
174  foot();
175}
176?>
177