<commit_before>request = require 'request'
koding  = require './bongo'

{ gitlab, hostname } = require 'koding-config-manager'
{ redirectOauth, saveOauthToSession } = require './helpers'

provider = 'gitlab'
headers  =
  'Accept'     : 'application/json'
  'User-Agent' : 'Koding'


fetchGroupSettings = (clientId, callback) ->

  { JSession, JGroup } = koding.models

  JSession.one { clientId }, (err, session) ->
    return callback err  if err
    return callback { message: 'Session invalid' }  unless session

    { groupName: slug } = session

    JGroup.one { slug }, (err, group) ->
      return callback err  if err
      return callback { message: 'Group invalid' }  unless group

      if not group.config?.gitlab? or not group.config.gitlab.enabled
        return callback { message: 'Integration not enabled yet.' }

      group.fetchDataAt 'gitlab', (err, data) ->
        return callback err  if err
        return callback { message: 'Integration settings invalid' }  unless data

        callback null, {
          url: group.config.gitlab.url
          applicationId: group.config.gitlab.applicationId
          applicationSecret: data.applicationSecret
          redirectUri: "http://#{slug}.#{hostname}/-/oauth/#{provider}/callback"
        }


getPathFor = (url, path) ->
  url ?= "http://#{gitlab.host ? 'gitlab.com'}:#{gitlab.port ? 80}"
  "#{url}#{path}"

fail = (req, res) ->
  redirectOauth 'could not get access token', req, res, { provider }

# Get user info with access token
fetchUserInfo = (req, res, access_token) -> (error, response, body) ->

  if error or not id = body.id
    console.error '[GITLAB][3/3] Failed to fetch user info:', error
    return fail req, res

  { username, id, email, name } = body
  { returnUrl } = req.query
  { clientId }  = req.cookies

  if name
    [firstName, restOfNames...] = name.split ' '
    lastName = restOfNames.join ' '

  resp = {
    email
    lastName
    username
    firstName
    token     : access_token
    profile   : lastName
    foreignId : String(id)
    returnUrl : returnUrl
  }

  saveOauthToSession resp, clientId, provider, (err) ->
    redirectOauth err, req, res, { provider, returnUrl }


# Get access token with code
authorizeUser = (req, res) -> (error, response, body) ->

  if error or not access_token = body.access_token
    console.error '[GITLAB][2/3] Failed to get access_token:', error
    return fail req, res

  options   =
    url     : getUrlFor '/api/v3/user'
    method  : 'GET'
    headers : headers
    json    : { access_token }

  request options, fetchUserInfo req, res, access_token


module.exports = (req, res) ->

  unless code = req.query.code
    console.error '[GITLAB][1/3] Failed to get code from query:', req.query
    return fail req, res

  options           =
    url             : getUrlFor '/oauth/token'
    method          : 'POST'
    headers         : headers
    json            :
      redirect_uri  : gitlab.redirectUri
      grant_type    : 'authorization_code'
      client_id     : gitlab.applicationId
      client_secret : gitlab.applicationSecret
      code          : code

  request options, authorizeUser req, res<commit_msg>GitLab_Callback: use provided team settings per request<commit_after>request = require 'request'
koding  = require './bongo'

{ gitlab, hostname } = require 'koding-config-manager'
{ redirectOauth, saveOauthToSession } = require './helpers'

provider = 'gitlab'
headers  =
  'Accept'     : 'application/json'
  'User-Agent' : 'Koding'


fetchGroupSettings = (clientId, callback) ->

  { JSession, JGroup } = koding.models

  JSession.one { clientId }, (err, session) ->
    return callback err  if err
    return callback { message: 'Session invalid' }  unless session

    { groupName: slug } = session

    JGroup.one { slug }, (err, group) ->
      return callback err  if err
      return callback { message: 'Group invalid' }  unless group

      if not group.config?.gitlab? or not group.config.gitlab.enabled
        return callback { message: 'Integration not enabled yet.' }

      group.fetchDataAt 'gitlab', (err, data) ->
        return callback err  if err
        return callback { message: 'Integration settings invalid' }  unless data

        callback null, {
          url: group.config.gitlab.url
          applicationId: group.config.gitlab.applicationId
          applicationSecret: data.applicationSecret
          redirectUri: "http://#{slug}.#{hostname}/-/oauth/#{provider}/callback"
        }


getPathFor = (url, path) ->
  url ?= "http://#{gitlab.host ? 'gitlab.com'}:#{gitlab.port ? 80}"
  "#{url}#{path}"

fail = (req, res) ->
  redirectOauth 'could not grant access', req, res, { provider }

# Get user info with access token
fetchUserInfo = (req, res, access_token) -> (error, response, body) ->

  if error or not id = body.id
    console.error '[GITLAB][4/4] Failed to fetch user info:', error
    return fail req, res

  { username, id, email, name } = body
  { returnUrl } = req.query
  { clientId }  = req.cookies

  if name
    [firstName, restOfNames...] = name.split ' '
    lastName = restOfNames.join ' '

  resp = {
    email
    lastName
    username
    firstName
    token     : access_token
    profile   : lastName
    foreignId : String(id)
    returnUrl : returnUrl
  }

  saveOauthToSession resp, clientId, provider, (err) ->
    redirectOauth err, req, res, { provider, returnUrl }


# Get access token with code
authorizeUser = (url, req, res) -> (error, response, body) ->

  if error or not access_token = body.access_token
    console.error '[GITLAB][3/4] Failed to get access_token:', error
    return fail req, res

  options   =
    url     : getPathFor url, '/api/v3/user'
    method  : 'GET'
    headers : headers
    json    : { access_token }

  request options, fetchUserInfo req, res, access_token


module.exports = (req, res) ->

  unless code = req.query.code
    console.error '[GITLAB][1/4] Failed to get code from query:', req.query
    return fail req, res

  { clientId } = req.cookies

  fetchGroupSettings clientId, (err, settings) ->

    if err or not settings
      console.error '[GITLAB][2/4] Failed to fetch group settings:', err
      return fail req, res

    { url, applicationId, applicationSecret, redirectUri } = settings

    options           =
      url             : getPathFor url, '/oauth/token'
      method          : 'POST'
      headers         : headers
      json            :
        redirect_uri  : redirectUri
        grant_type    : 'authorization_code'
        client_id     : applicationId
        client_secret : applicationSecret
        code          : code

    request options, authorizeUser url, req, res
{'fraction_non_alphanumeric': 0.11200837445790339, 'fraction_numerical': 0.0029908778226409452, 'mean_word_length': 2.62296858071506, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 28, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '239735', 'n_tokens_mistral': 2053, 'n_tokens_neox': 1997, 'n_words': 596}