Class: PuavoRest::PuavoSinatra

Inherits:
Sinatra::Base
  • Object
show all
Defined in:
lib/puavo_sinatra.rb,
lib/auth.rb

Overview

Base class for all puavo-rest resources. Add common helper methods here

Direct Known Subclasses

BootConfigurations, BootServers, DeviceImages, Devices, EmailConfirm, ExternalFiles, FluentRelay, LegacyRoles, LtspServers, Organisations, Password, Primus, PrinterQueues, SSO, ScheduledJobs, Schools, Sessions, Users, WlanNetworks

Constant Summary

ROOT =
File.dirname(File.dirname(__FILE__))

Instance Method Summary (collapse)

Instance Method Details

- (Object) auth(*auth_methods)



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/auth.rb', line 102

def auth(*auth_methods)
  if auth_methods.include?(:kerberos) && auth_methods.include?(:legacy_server_auth)
    raise "legacy server auth and kerberos cannot be used on the same resource"
  end

  auth_methods.each do |method|
    credentials = send(method)
    next if !credentials

    if credentials[:dn].nil? && credentials[:username]
      credentials[:dn] = LdapModel.setup(:credentials => CONFIG["server"]) do
        User.resolve_dn(credentials[:username])
      end
    end

    if credentials[:dn].nil? && credentials[:kerberos].nil?
      puts "Cannot resolve #{ credentials[:username].inspect } to DN"
      raise Unauthorized,
        :user => "Could not create ldap connection. Bad/missing credentials. #{ auth_methods.inspect }",
        :meta => {
          :username => credentials[:username],
        }
    end

    credentials[:auth_method] = method
    LdapModel.setup(:credentials => credentials)
    break
  end


  if not LdapModel.connection
    raise Unauthorized,
      :user => "Could not create ldap connection. Bad/missing credentials. #{ auth_methods.inspect }"
  end

  log_creds = LdapModel.settings[:credentials].dup
  log_creds.delete(:kerberos)
  log_creds.delete(:password)
  self.flog = flog.merge(:credentials => log_creds)
  flog.info "authenticated"
end

- (Object) basic_auth



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/auth.rb', line 14

def basic_auth
  return if not env["HTTP_AUTHORIZATION"]
  type, data = env["HTTP_AUTHORIZATION"].split(" ", 2)
  if type == "Basic"
    plain = Base64.decode64(data)
    username, password = plain.split(":")

    credentials = { :password => password  }
    if LdapModel.is_dn(username)
      credentials[:dn] = username
    else
      credentials[:username] = username
    end
    logger.info "Using Basic Auth #{ credentials[:dn] ? "with dn" : "with uid" }"
    return credentials
  end
end

- (Object) flog

Get request specific FluentWrap instance

Returns:

  • FluentWrap



19
20
21
# File 'lib/puavo_sinatra.rb', line 19

def flog
  Thread.current[:fluent]
end

- (Object) flog=(logger)

Set FluentWrap instance for the request

Parameters:



26
27
28
# File 'lib/puavo_sinatra.rb', line 26

def flog=(logger)
  Thread.current[:fluent] = logger
end

- (Object) from_post



32
33
34
35
36
37
38
# File 'lib/auth.rb', line 32

def from_post
  return if env["REQUEST_METHOD"] != "POST"
  return {
    :username => params["username"].split("@").first,
    :password => params["password"]
  }
end

- (Object) json_params

Try to parse JSON body and fallback to sinatra request.POST if not

Returns:

  • Hash



40
41
42
43
44
45
46
47
48
49
50
# File 'lib/puavo_sinatra.rb', line 40

def json_params
  return @json_body if @json_body

  if request.content_type.downcase == "application/json"
    json_parser = Yajl::Parser.new
    @json_body = json_parser.parse(request.body)
    return @json_body
  end

  return request.POST
end

- (Object) kerberos

This must be always the last authentication option because it is initialized by the server by responding 401 Unauthorized



92
93
94
95
96
97
98
99
100
# File 'lib/auth.rb', line 92

def kerberos
  return if env["HTTP_AUTHORIZATION"].nil?
  auth_key = env["HTTP_AUTHORIZATION"].split()[0]
  return if auth_key.to_s.downcase != "negotiate"
  logger.info "Using Kerberos authentication"
  return {
    :kerberos => Base64.decode64(env["HTTP_AUTHORIZATION"].split()[1])
  }
end

- (Object) legacy_server_auth

In an old version bootserver authentication was picked when no other authentication methods were available. But that conflicted with the kerberos authentication. This is now legacy and will removed in future.



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/auth.rb', line 67

def legacy_server_auth
  if not CONFIG["bootserver"]
    logger.error "Cannot use bootserver auth on cloud installation"
    return
  end

  # In future we will only use server based authentication if 'Authorization:
  # Bootserver' is set. Otherwise we will assume Kerberos authentication.
  if env["HTTP_AUTHORIZATION"].to_s.downcase != "bootserver"
    logger.warn "WARNING! Using deprecated bootserver authentication without the Header 'Authorization: Bootserver'"
  end

  ## Helper to sweep out lecagy calls from tests
  # if ENV["RACK_ENV"] == "test"
  #   puts "Legacy legacy_server_auth usage from:"
  #   puts caller[0..5]
  #   puts
  # end

  return CONFIG["server"]
end

- (Object) limit(a)

In routes handlers use limit query string to slice arrays

Example: /foos?limit=2

Parameters:

  • a (Array)

    Array to slice



57
58
59
60
61
62
63
# File 'lib/puavo_sinatra.rb', line 57

def limit(a)
  if params["limit"]
    a[0...params["limit"].to_i]
  else
    a
  end
end

- (Object) pw_mgmt_server_auth



40
41
42
43
44
45
46
47
48
49
50
# File 'lib/auth.rb', line 40

def pw_mgmt_server_auth
  if CONFIG["password_management"]
    return {
      :dn => PUAVO_ETC.ds_pw_mgmt_dn,
      :password => PUAVO_ETC.ds_pw_mgmt_password
    }
  else
    logger.error "Cannot use password management auth on cloud or bootserver installation"
    return
  end
end

- (Object) server_auth

Pick bootserver credentials when Header 'Authorization: Bootserver' is set



53
54
55
56
57
58
59
60
61
62
# File 'lib/auth.rb', line 53

def server_auth
  if not CONFIG["bootserver"]
    logger.error "Cannot use bootserver auth on cloud installation"
    return
  end

  if env["HTTP_AUTHORIZATION"].to_s.downcase == "bootserver"
    return CONFIG["server"]
  end
end

- (Object) txt(text)

Respond with a text content

Parameters:

  • text (String)


32
33
34
35
# File 'lib/puavo_sinatra.rb', line 32

def txt(text)
  content_type :txt
  halt 200, text.to_s
end