pkiadm/cmd/pkiadmd/subject.go
Gibheer bc84bc4a28 add location support
This commit adds basic support for adding, deleting, ... locations. This
needed a bit of rework for the ResourceName, as it was kind of stupid to
have different implementations server internally and in the lib.

There is still some need for cleanup, but it works basically.
2017-05-31 21:03:51 +02:00

160 lines
4.4 KiB
Go

package main
import (
"crypto/x509/pkix"
"fmt"
"github.com/gibheer/pkiadm"
)
type (
Subject struct {
ID string
Data pkix.Name
}
)
// Create a new subject resource. The commonName of the name is not used at the
// moment.
func NewSubject(id string, name pkix.Name) (*Subject, error) {
return &Subject{
ID: id,
Data: name,
}, nil
}
// Return the unique ResourceName
func (sub *Subject) Name() pkiadm.ResourceName { return pkiadm.ResourceName{sub.ID, pkiadm.RTSubject} }
// AddDependency registers a depending resource to be retuened by Dependencies()
// Refresh must trigger a rebuild of the resource.
// This is a NOOP as it does not have any dependencies.
func (sub *Subject) Refresh(_ *Storage) error { return nil }
// Return the PEM output of the contained resource.
func (sub *Subject) Pem() ([]byte, error) { return []byte{}, nil }
func (sub *Subject) Checksum() []byte { return []byte{} }
// DependsOn must return the resource names it is depending on.
func (sub *Subject) DependsOn() []pkiadm.ResourceName { return []pkiadm.ResourceName{} }
// GetName returns the stored name definition.
func (sub *Subject) GetName() pkix.Name {
return sub.Data
}
// CreateSubject is the RPC endpoint to create a new subject.
func (s *Server) CreateSubject(inSubj pkiadm.Subject, res *pkiadm.Result) error {
s.lock()
defer s.unlock()
subj, err := NewSubject(inSubj.ID, inSubj.Name)
if err != nil {
res.SetError(err, "Could not create new subject '%s'", inSubj.ID)
return nil
}
if err := s.storage.AddSubject(subj); err != nil {
res.SetError(err, "Could not add subject '%s'", inSubj.ID)
return nil
}
return s.store(res)
}
// SetSubject is the RPC endpoint to adjust fields on a subject.
func (s *Server) SetSubject(changeset pkiadm.SubjectChange, res *pkiadm.Result) error {
s.lock()
defer s.unlock()
subj, err := s.storage.GetSubject(pkiadm.ResourceName{ID: changeset.Subject.ID, Type: pkiadm.RTSubject})
if err != nil {
res.SetError(err, "Could not find subject '%s'", changeset.Subject.ID)
return nil
}
changes := changeset.Subject.Name
for _, field := range changeset.FieldList {
switch field {
case "serial":
subj.Data.SerialNumber = changes.SerialNumber
case "common-name":
subj.Data.CommonName = changes.CommonName
case "country":
subj.Data.Country = changes.Country
case "org":
subj.Data.Organization = changes.Organization
case "org-unit":
subj.Data.OrganizationalUnit = changes.OrganizationalUnit
case "locality":
subj.Data.Locality = changes.Locality
case "province":
subj.Data.Province = changes.Province
case "street":
subj.Data.StreetAddress = changes.StreetAddress
case "code":
subj.Data.PostalCode = changes.PostalCode
default:
res.SetError(fmt.Errorf("unknown field"), "unknown field '%s'", field)
return nil
}
}
if err := s.storage.Update(pkiadm.ResourceName{ID: subj.ID, Type: pkiadm.RTSubject}); err != nil {
res.SetError(err, "Could not update subject '%s'", changeset.Subject.ID)
return nil
}
return s.store(res)
}
// ListSubjects is the RPC endpoint to list all available subjects.
func (s *Server) ListSubjects(filter pkiadm.Filter, res *pkiadm.ResultSubjects) error {
s.lock()
defer s.unlock()
for _, subj := range s.storage.Subjects {
res.Subjects = append(res.Subjects, pkiadm.Subject{
ID: subj.ID,
Name: subj.GetName(),
})
}
return nil
}
// DeleteSubject is the RPC endpoint to delete a subject.
func (s *Server) DeleteSubject(inSubj pkiadm.ResourceName, res *pkiadm.Result) error {
s.lock()
defer s.unlock()
subj, err := s.storage.Get(pkiadm.ResourceName{ID: inSubj.ID, Type: pkiadm.RTSubject})
if err == ENotFound {
return nil
} else if err != nil {
res.SetError(err, "Could not find resource '%s'", inSubj)
return nil
}
if err := s.storage.Remove(subj); err != nil {
res.SetError(err, "Could not remove subject '%s'", inSubj)
return nil
}
return s.store(res)
}
// ShowSubject is the RPC endpoint to get a single subject resource for detailed
// inspection.
func (s *Server) ShowSubject(inSubj pkiadm.ResourceName, res *pkiadm.ResultSubjects) error {
s.lock()
defer s.unlock()
subj, err := s.storage.GetSubject(pkiadm.ResourceName{ID: inSubj.ID, Type: pkiadm.RTSubject})
if err == ENotFound {
return nil
} else if err != nil {
res.Result.SetError(err, "could not find resource '%s'", inSubj)
return nil
}
res.Subjects = []pkiadm.Subject{
pkiadm.Subject{
ID: subj.ID,
Name: subj.GetName(),
},
}
return nil
}