60 lines
1.5 KiB
Ruby
60 lines
1.5 KiB
Ruby
class AuthorizedKeys
|
|
LINE = %r/^
|
|
(?:
|
|
(?<options> .+?)
|
|
\s+)?
|
|
(?<type> (?:sk-)?ssh-[a-zA-Z0-9.@-]+)
|
|
\s+
|
|
(?<key> \S+)
|
|
(?:\s+
|
|
(?<comment> .*)
|
|
)?
|
|
$/x
|
|
|
|
def self.parse line
|
|
opts, m = {}, LINE.match( line)
|
|
raise "Invalid authorized keys line: #{line}" unless m
|
|
if m[:options]
|
|
o = m[:options].dup
|
|
while not o.empty?
|
|
case o
|
|
|
|
when /^([a-z0-9_-]+)(.*)$/i
|
|
k, o = $1.to_sym, $2
|
|
case o
|
|
when '' then opts[k] = true
|
|
when /^,(.*)$/ then opts[k], o = true, $1
|
|
when /^="([^"]*)"(.*)$/i, /^=([a-z_0-9:-]*)(.*?)$/i
|
|
opts[k], o = $1, $2
|
|
case o
|
|
when /^,(.*)/ then o = $1
|
|
when '' then o = ''
|
|
else raise "Invalid options-string at: #{o}"
|
|
end
|
|
else raise "Invalid options-string at: #{o}"
|
|
end
|
|
|
|
when /^\s*#/
|
|
# comment
|
|
end
|
|
end
|
|
end
|
|
new m[:type], m[:key], m[:comment], **opts
|
|
end
|
|
|
|
attr_reader :type, :key, :comment, :options
|
|
|
|
def initialize type, key, comment, **options
|
|
@type, @key, @comment, @options = type, key, comment, options
|
|
end
|
|
|
|
def to_h() {type: @type, key: @key, comment: @comment, options: @options} end
|
|
def to_a() [@type, @key, @comment, @options] end
|
|
def to_s
|
|
[
|
|
@options.map {|k,v| case v when true then "#{k}" else "#{k}=\"#{v}\"" end }.join( ','),
|
|
@type, @key, @comment
|
|
].join ' '
|
|
end
|
|
end
|