Browse Source

Fixed addcollaborator

master
pb 1 year ago
parent
commit
906467d962
1 changed files with 204 additions and 200 deletions
  1. 204
    200
      index.js

+ 204
- 200
index.js View File

@@ -38,6 +38,205 @@ function getVersion() { return BUILD_VERSION; }
// support runas lauched directly from shell.
// pass in environment in hta to shellexecute.

const https = require('https')
const http = require('http');
const { Console } = require('console');
const { env } = require('process');
const RESTAPI = (function(){

// Singleton
function RESTAPI(){}
// RESTAPI.create = RESTAPI; // Returns the one singe instance which is the class itself
// const httpsoptions = {
// hostname: 'whatever.com',
// port: 443,
// path: '/todos',
// method: 'POST',
// headers: {
// 'Content-Type': 'application/json',
// 'Content-Length': data.length
// }
// }
RESTAPI.method = function(options, resolve, reject){
options.headers = options.headers || { 'Content-Type': 'application/json' }
const data = options.payload ? new TextEncoder().encode( JSON.stringify(options.payload) ) : null
options.headers = options.payload ? (options.headers || {
'Content-Type': 'application/json',
'Content-Length': data.length
}) : (options.headers || {})
!options.headers.Authorization && usertokens[options.username] ? (()=>{
options.headers.Authorization = `token ${usertokens[options.username]}`
delete options.username
onauthenticated()
})() : (()=>{
if(!usertokens[options.username] && !options.isAuthCall) {
RESTAPI.authenticate( utils.assign( {isAuthCall : true}, options ) , onauthenticated, function(err){
// PB : TODO -- Retry without auth...
console.error('Auth failed or not accessible')
reject(err)
})
}
else onauthenticated()
})()

function onauthenticated(){
var acquirer = getHTTPorS(options)
const req = acquirer.request(options, res => {
if (res.statusCode < 200 || res.statusCode >= 300) {
// new Error('statusCode=' + res.statusCode)
return reject('statusCode = ' + res.statusCode);
}
var body = [];
// res.setEncoding('utf8');
res.on('data', (chunk)=>{ body.push(chunk); });
res.on('end', ()=>{
try {
if(res.headers['content-type'] && res.headers['content-type'].split(';').find( (i)=> i.trim() === 'application/json' )) body = JSON.parse(Buffer.concat(body).toString());
else body = Buffer.concat(body).toString();
} catch(e) { return reject(e); }
resolve(body);
});
});
req.on('error', error => { reject(error) })
if(options.payload) req.write(data)
req.end()
}
}

var usertokens = {}

RESTAPI.authenticate = function(options, resolve, reject){
options.headers = options.headers || { 'Content-Type': 'application/json' }

if(!usertokens[options.username]) {
// Authenticate and acquire token.
// https://git.bbh/api/v1/users/<username>/tokens
// curl -XPOST -H "Content-Type: application/json" -k -d '{"name":"demo"}' -u demo:demo123 http://git.bbh/api/v1/users/demo/tokens
var _options = Object.assign({}, options)
// _options.username = 'demo'
// _options.password = 'demo123'
_options.method = 'POST'
_options.headers.Authorization = `Basic ${Buffer.from(`${_options.username}:${_options.password}`).toString('base64')}`
_options.path = `/api/v1/users/${_options.username}/tokens`

var postoptions = { name : _options.username }
delete _options.username
delete _options.password
_options.payload = postoptions
RESTAPI.post( _options, function(tokenresp){
// tokenresp = JSON.parse(tokenresp)
usertokens[options.username] = tokenresp.sha1
resolve(tokenresp)
},
function(err){ reject(err) }
)
}
else resolve(tokenresp.sha1)
}
RESTAPI.put = RESTAPI.get = RESTAPI.post = RESTAPI.method

return RESTAPI
})();

var getHTTPorS = function(options){ return options.protocol.startsWith('https') ? https : http; }

const GITEA = (function(){

function GITEA(){}
GITEA.APIROOT = '/api/v1'
GITEA.repository = {
fork( httpoptions, cmdoptions, giteaoptions, resolve, reject ){
// forkoptions = { owner : httpoptions.username, repo : {{reoptoFork}} }
// giteaoptions = {
// organization string
// --- organization name, if forking into an organization
// }
// http://try.gitea.io/api/v1/repos/{owner}/{repo}/forks
httpoptions.path = `${GITEA.APIROOT}/repos/${cmdoptions.owner}/${cmdoptions.repo}/forks`
httpoptions.method = 'POST'
httpoptions.payload = giteaoptions;
return RESTAPI.post(httpoptions, resolve || function(){}, reject || function(){} )
}
, updateattributes( httpoptions, cmdoptions, giteaoptions, resolve, reject ){
httpoptions.path = `${GITEA.APIROOT}/repos/${cmdoptions.owner}/${cmdoptions.repo}`
httpoptions.method = 'PATCH'
httpoptions.payload = giteaoptions;
return RESTAPI.post(httpoptions, resolve || function(){}, reject || function(){} )
}
, exists( httpoptions, repo, owner ) {
// ​/users​/{username} // Get a user
httpoptions.path = `${GITEA.APIROOT}/repos/${owner}/${repo}`
httpoptions.method = 'GET'
return new Promise( (resolve, reject) => {
RESTAPI.get(httpoptions, function(o){
if(o.id) return resolve(true)
return resolve(false) }, reject || function(){ return false } )
})
}
, addcollaborator( httpoptions, repodef, owner, collaborator, permission ) {
permission = permission || 'Read'
httpoptions.payload = { permission }
httpoptions.path = `${GITEA.APIROOT}/repos/${owner}/${repodef.repo}/collaborators/${collaborator}`
httpoptions.method = 'PUT'
return new Promise( (resolve, reject) => {
RESTAPI.put(httpoptions, function(o){
//
if(o === "") return resolve(true)
return resolve(false) }, reject || function(){ return false } )
})
}
}

GITEA.user = {
getuser( httpoptions, cmdoptions, giteaoptions, resolve, reject ){
// ​/users​/{username} // Get a user
httpoptions.path = `${GITEA.APIROOT}/users/${httpoptions.username}`
httpoptions.method = 'GET'
return RESTAPI.get(httpoptions, giteaoptions, resolve || function(){}, reject || function(){} )
}
}

return GITEA
})();

// Wrapper for Git shell operations. Some meta operations will map to a bunch of GIT commands.
const GIT = (function(){
function GIT(){}

Object.assign(GIT, {
'switch user'(username){
var httpoptions = new URL(selectedinstance.reposerver);
httpoptions.username = selectedinstance.username
httpoptions.password = selectedinstance.password

return GITEA.user.getuser(httpoptions).then(()=>{
return nodeShellExec('git', ['config', '--replace-all', 'user.name', username],
{
inherit: true, shell: true,
env: ENV
, cwd: instanceroot + '/' + repo
, runas: processedArgs.runas
, title: `'git', ${['config', '--replace-all', 'user.name', username].join(' ')}`
})
}
)
.catch(e => {
console.error(e + 'Could not switch. Probably no such user.')
})

}
})

return GIT
})();



// PB : NOTE -- iife doesnt work if previous statement is not terminated by ;
(function () {
"use strict";
@@ -346,7 +545,7 @@ shell_verse.acquireElevationState().then((isElevated) => {
}
, 'addcollaborator' : {
// Usage :
// elxr addcollaborator developer
// elxr addcollaborator instancename developer
cmdFn : function(args){

var __each = function(args){
@@ -357,7 +556,7 @@ shell_verse.acquireElevationState().then((isElevated) => {
var repodef = selectedinstance.reposindexed[repo];
if(!repodef) return
var remotenames = selectedinstance.selectedremotes.concat( selectedinstance.permanentremotes )
var remotenames = (selectedinstance.selectedremotes || []).concat( selectedinstance.permanentremotes )
var remotes = selectedinstance.reposerverinstances[selectedinstance.reposerver].remotes
// console.log('-----------------------------------------------------')
// console.log(repo)
@@ -406,7 +605,7 @@ shell_verse.acquireElevationState().then((isElevated) => {

var promises = []
var repos = Object.keys(selectedinstance.reposindexed)
repos.forEach(repo => { promises.push(__each({ repo, collaborator : args._[1]})) })
repos.forEach(repo => { promises.push(__each({ repo, collaborator : args._[2]})) }) // PB : TODO -- Move to toArgs.
return Promise.all(promises).then(pr => { console.log('addcollaborator done') })
}
}
@@ -3919,6 +4118,8 @@ shell_verse.acquireElevationState().then((isElevated) => {
var pendingpulls = [];
def.repos.forEach((def) => {
pendingpulls.push(
// PB : TODO serializing to prevent out of memory.
// Need to optimize as batches and streams...
function(){
// if(def.repo === 'setup') return;
// if(def.repo !== 'chess-client-lib') return;
@@ -4740,203 +4941,6 @@ shell_verse.acquireElevationState().then((isElevated) => {
localInstanceDetected : false
}

const https = require('https')
const http = require('http');
const { Console } = require('console');
const { env } = require('process');
const RESTAPI = (function(){

// Singleton
function RESTAPI(){}
// RESTAPI.create = RESTAPI; // Returns the one singe instance which is the class itself
// const httpsoptions = {
// hostname: 'whatever.com',
// port: 443,
// path: '/todos',
// method: 'POST',
// headers: {
// 'Content-Type': 'application/json',
// 'Content-Length': data.length
// }
// }
RESTAPI.method = function(options, resolve, reject){
options.headers = options.headers || { 'Content-Type': 'application/json' }
const data = options.payload ? new TextEncoder().encode( JSON.stringify(options.payload) ) : null
options.headers = options.payload ? (options.headers || {
'Content-Type': 'application/json',
'Content-Length': data.length
}) : (options.headers || {})
!options.headers.Authorization && usertokens[options.username] ? (()=>{
options.headers.Authorization = `token ${usertokens[options.username]}`
delete options.username
onauthenticated()
})() : (()=>{
if(!usertokens[options.username] && !options.isAuthCall) {
RESTAPI.authenticate( utils.assign( {isAuthCall : true}, options ) , onauthenticated, function(err){
// PB : TODO -- Retry without auth...
console.error('Auth failed or not accessible')
reject(err)
})
}
else onauthenticated()
})()

function onauthenticated(){
var acquirer = getHTTPorS(options)
const req = acquirer.request(options, res => {
if (res.statusCode < 200 || res.statusCode >= 300) {
// new Error('statusCode=' + res.statusCode)
return reject('statusCode = ' + res.statusCode);
}
var body = [];
// res.setEncoding('utf8');
res.on('data', (chunk)=>{ body.push(chunk); });
res.on('end', ()=>{
try {
if(res.headers['content-type'] && res.headers['content-type'].split(';').find( (i)=> i.trim() === 'application/json' )) body = JSON.parse(Buffer.concat(body).toString());
else body = Buffer.concat(body).toString();
} catch(e) { return reject(e); }
resolve(body);
});
});
req.on('error', error => { reject(error) })
if(options.payload) req.write(data)
req.end()
}
}

var usertokens = {}

RESTAPI.authenticate = function(options, resolve, reject){
options.headers = options.headers || { 'Content-Type': 'application/json' }

if(!usertokens[options.username]) {
// Authenticate and acquire token.
// https://git.bbh/api/v1/users/<username>/tokens
// curl -XPOST -H "Content-Type: application/json" -k -d '{"name":"demo"}' -u demo:demo123 http://git.bbh/api/v1/users/demo/tokens
var _options = Object.assign({}, options)
// _options.username = 'demo'
// _options.password = 'demo123'
_options.method = 'POST'
_options.headers.Authorization = `Basic ${Buffer.from(`${_options.username}:${_options.password}`).toString('base64')}`
_options.path = `/api/v1/users/${_options.username}/tokens`

var postoptions = { name : _options.username }
delete _options.username
delete _options.password
_options.payload = postoptions
RESTAPI.post( _options, function(tokenresp){
// tokenresp = JSON.parse(tokenresp)
usertokens[options.username] = tokenresp.sha1
resolve(tokenresp)
},
function(err){ reject(err) }
)
}
else resolve(tokenresp.sha1)
}
RESTAPI.put = RESTAPI.get = RESTAPI.post = RESTAPI.method

return RESTAPI
})();

var getHTTPorS = function(options){ return options.protocol.startsWith('https') ? https : http; }

const GITEA = (function(){

function GITEA(){}
GITEA.APIROOT = '/api/v1'
GITEA.repository = {
fork( httpoptions, cmdoptions, giteaoptions, resolve, reject ){
// forkoptions = { owner : httpoptions.username, repo : {{reoptoFork}} }
// giteaoptions = {
// organization string
// --- organization name, if forking into an organization
// }
// http://try.gitea.io/api/v1/repos/{owner}/{repo}/forks
httpoptions.path = `${GITEA.APIROOT}/repos/${cmdoptions.owner}/${cmdoptions.repo}/forks`
httpoptions.method = 'POST'
httpoptions.payload = giteaoptions;
return RESTAPI.post(httpoptions, resolve || function(){}, reject || function(){} )
}
, updateattributes( httpoptions, cmdoptions, giteaoptions, resolve, reject ){
httpoptions.path = `${GITEA.APIROOT}/repos/${cmdoptions.owner}/${cmdoptions.repo}`
httpoptions.method = 'PATCH'
httpoptions.payload = giteaoptions;
return RESTAPI.post(httpoptions, resolve || function(){}, reject || function(){} )
}
, exists( httpoptions, repo, owner ) {
// ​/users​/{username} // Get a user
httpoptions.path = `${GITEA.APIROOT}/repos/${owner}/${repo}`
httpoptions.method = 'GET'
return new Promise( (resolve, reject) => {
RESTAPI.get(httpoptions, function(o){
if(o.id) return resolve(true)
return resolve(false) }, reject || function(){ return false } )
})
}
, addcollaborator( httpoptions, repodef, owner, collaborator, permission ) {
permission = permission || 'Read'
httpoptions.payload = { permission }
httpoptions.path = `${GITEA.APIROOT}/repos/${owner}/${repodef.repo}/collaborators/${collaborator}`
httpoptions.method = 'PUT'
return new Promise( (resolve, reject) => {
RESTAPI.put(httpoptions, function(o){
//
if(o === "") return resolve(true)
return resolve(false) }, reject || function(){ return false } )
})
}
}

GITEA.user = {
getuser( httpoptions, cmdoptions, giteaoptions, resolve, reject ){
// ​/users​/{username} // Get a user
httpoptions.path = `${GITEA.APIROOT}/users/${httpoptions.username}`
httpoptions.method = 'GET'
return RESTAPI.get(httpoptions, giteaoptions, resolve || function(){}, reject || function(){} )
}
}

return GITEA
})();

// Wrapper for Git shell operations. Some meta operations will map to a bunch of GIT commands.
const GIT = (function(){
function GIT(){}

Object.assign(GIT, {
'switch user'(username){
var httpoptions = new URL(selectedinstance.reposerver);
httpoptions.username = selectedinstance.username
httpoptions.password = selectedinstance.password

return GITEA.user.getuser(httpoptions).then(()=>{
return nodeShellExec('git', ['config', '--replace-all', 'user.name', username],
{
inherit: true, shell: true,
env: ENV
, cwd: instanceroot + '/' + repo
, runas: processedArgs.runas
, title: `'git', ${['config', '--replace-all', 'user.name', username].join(' ')}`
})
}
)
.catch(e => {
console.error(e + 'Could not switch. Probably no such user.')
})

}
})

return GIT
})();

function createInstanceData(target, source) {

var sourceinstance = source || target;

Loading…
Cancel
Save