App-Netdisco

 view release on metacpan or  search on metacpan

lib/App/Netdisco/Web/API/User.pm  view on Meta::CPAN

  path => (setting('api_base') || '').'/user',
  description => 'Provision a service account and issue an API token. Creates the user if not present (null password, token-auth only). Idempotent.',
  parameters => [
    body => {
      in => 'body',
      schema => {
        type => 'object',
        required => ['username'],
        properties => {
          username => {
            type => 'string',
            description => 'Username of the service account',
          },
          permanent => {
            type => 'boolean',
            default => 0,
            description => 'Issue a non-expiring token (requires allow_permanent_tokens in config)',
          },
          allowed_ips => {
            type => 'array',
            items => { type => 'string' },
            description => 'CIDR prefixes allowed to use this token (omit for no restriction)',
          },
          revoke => {
            type => 'boolean',
            default => 0,
            description => 'Revoke the token instead of issuing one',
          },
        },
      },
    },
  ],
  responses => { default => { examples => {
    'application/json' => { username => 'grafana-svc', api_key => 'cc9d5c02d8898e5728b7d7a0339c0785', permanent => 1 },
  } } },
}, post '/api/v1/user' => require_role api_admin => sub {
  header('Content-Type' => 'application/json');

  my $body = try { from_json(request->body) } catch { {} };
  my $username = $body->{username}
    or return send_error(to_json({ error => 'Missing username' }), 400);

  my $user = schema('netdisco')->resultset('User')
    ->find_or_create({ username => $username });

  if ($body->{revoke}) {
    $user->update({ token => undef, token_from => undef, token_no_expire => \"false",
                    token_allowed_ips => undef });
    return to_json { username => $username, revoked => \1 };
  }

  my $provider = Dancer::Plugin::Auth::Extensible::auth_provider('users');

  my $want_permanent = $body->{permanent} && setting('allow_permanent_tokens');
  my $allowed_ips    = (ref $body->{allowed_ips} eq ref []) ? $body->{allowed_ips} : undef;

  $user->update({
    token_from      => time,
    token_no_expire => ($want_permanent ? \"true" : \"false"),
    (defined $allowed_ips ? (token_allowed_ips => $allowed_ips) : ()),
    ($provider->validate_api_token($user->token)
      ? () : (token => \'md5(random()::text)')),
  })->discard_changes();

  return to_json {
    username  => $username,
    api_key   => $user->token,
    permanent => ($user->token_no_expire ? \1 : \0),
    ($user->token_allowed_ips
      ? (allowed_ips => $user->token_allowed_ips) : ()),
  };
};

true;



( run in 1.526 second using v1.01-cache-2.11-cpan-6aa56a78535 )