github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/apiserver/authentication/agent_test.go (about)

     1  // Copyright 2014 Canonical Ltd. All rights reserved.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package authentication_test
     5  
     6  import (
     7  	"context"
     8  
     9  	jc "github.com/juju/testing/checkers"
    10  	"github.com/juju/utils/v3"
    11  	gc "gopkg.in/check.v1"
    12  
    13  	"github.com/juju/juju/apiserver/authentication"
    14  	"github.com/juju/juju/juju/testing"
    15  	"github.com/juju/juju/state"
    16  	"github.com/juju/juju/testing/factory"
    17  )
    18  
    19  type agentAuthenticatorSuite struct {
    20  	testing.JujuConnSuite
    21  	machinePassword string
    22  	machineNonce    string
    23  	unitPassword    string
    24  	machine         *state.Machine
    25  	user            *state.User
    26  	unit            *state.Unit
    27  	relation        *state.Relation
    28  }
    29  
    30  var _ = gc.Suite(&agentAuthenticatorSuite{})
    31  
    32  func (s *agentAuthenticatorSuite) SetUpTest(c *gc.C) {
    33  	s.JujuConnSuite.SetUpTest(c)
    34  
    35  	s.user = s.Factory.MakeUser(c, &factory.UserParams{
    36  		Name:        "bobbrown",
    37  		DisplayName: "Bob Brown",
    38  		Password:    "password",
    39  	})
    40  
    41  	// add machine for testing machine agent authentication
    42  	machine, err := s.State.AddMachine(state.UbuntuBase("12.10"), state.JobHostUnits)
    43  	c.Assert(err, jc.ErrorIsNil)
    44  	nonce, err := utils.RandomPassword()
    45  	c.Assert(err, jc.ErrorIsNil)
    46  	err = machine.SetProvisioned("foo", "", nonce, nil)
    47  	c.Assert(err, jc.ErrorIsNil)
    48  	password, err := utils.RandomPassword()
    49  	c.Assert(err, jc.ErrorIsNil)
    50  	err = machine.SetPassword(password)
    51  	c.Assert(err, jc.ErrorIsNil)
    52  	s.machine = machine
    53  	s.machinePassword = password
    54  	s.machineNonce = nonce
    55  
    56  	// add a unit for testing unit agent authentication
    57  	wordpress := s.AddTestingApplication(c, "wordpress", s.AddTestingCharm(c, "wordpress"))
    58  	c.Assert(err, jc.ErrorIsNil)
    59  	unit, err := wordpress.AddUnit(state.AddUnitParams{})
    60  	c.Assert(err, jc.ErrorIsNil)
    61  	s.unit = unit
    62  	password, err = utils.RandomPassword()
    63  	c.Assert(err, jc.ErrorIsNil)
    64  	err = unit.SetPassword(password)
    65  	c.Assert(err, jc.ErrorIsNil)
    66  	s.unitPassword = password
    67  
    68  	// add relation
    69  	wordpressEP, err := wordpress.Endpoint("db")
    70  	c.Assert(err, jc.ErrorIsNil)
    71  	mysql := s.AddTestingApplication(c, "mysql", s.AddTestingCharm(c, "mysql"))
    72  	mysqlEP, err := mysql.Endpoint("server")
    73  	c.Assert(err, jc.ErrorIsNil)
    74  	s.relation, err = s.State.AddRelation(wordpressEP, mysqlEP)
    75  	c.Assert(err, jc.ErrorIsNil)
    76  }
    77  
    78  // testCase is used for structured table based tests
    79  type testCase struct {
    80  	entity       state.Entity
    81  	credentials  string
    82  	nonce        string
    83  	about        string
    84  	errorMessage string
    85  }
    86  
    87  func (s *agentAuthenticatorSuite) TestValidLogins(c *gc.C) {
    88  	testCases := []testCase{{
    89  		entity:      s.user,
    90  		credentials: "password",
    91  		about:       "user login",
    92  	}, {
    93  		entity:      s.machine,
    94  		credentials: s.machinePassword,
    95  		nonce:       s.machineNonce,
    96  		about:       "machine login",
    97  	}, {
    98  		entity:      s.unit,
    99  		credentials: s.unitPassword,
   100  		about:       "unit login",
   101  	}}
   102  
   103  	for i, t := range testCases {
   104  		c.Logf("test %d: %s", i, t.about)
   105  		var authenticator authentication.AgentAuthenticator
   106  		entity, err := authenticator.Authenticate(context.TODO(), s.State, authentication.AuthParams{
   107  			AuthTag:     t.entity.Tag(),
   108  			Credentials: t.credentials,
   109  			Nonce:       t.nonce,
   110  		})
   111  		c.Assert(err, jc.ErrorIsNil)
   112  		c.Assert(entity.Tag(), gc.DeepEquals, t.entity.Tag())
   113  	}
   114  }
   115  
   116  func (s *agentAuthenticatorSuite) TestInvalidLogins(c *gc.C) {
   117  	testCases := []testCase{{
   118  		entity:       s.relation,
   119  		credentials:  "dummy-secret",
   120  		about:        "relation login",
   121  		errorMessage: "invalid request",
   122  	}, {
   123  		entity:       s.user,
   124  		credentials:  "wrongpassword",
   125  		about:        "user login for nonexistant user",
   126  		errorMessage: "invalid entity name or password",
   127  	}, {
   128  		entity:       s.machine,
   129  		credentials:  s.machinePassword,
   130  		nonce:        "123",
   131  		about:        "machine login",
   132  		errorMessage: "machine 0 not provisioned",
   133  	}, {
   134  		entity:       s.user,
   135  		credentials:  "wrong-secret",
   136  		about:        "user login for nonexistant user",
   137  		errorMessage: "invalid entity name or password",
   138  	}}
   139  
   140  	for i, t := range testCases {
   141  		c.Logf("test %d: %s", i, t.about)
   142  		var authenticator authentication.AgentAuthenticator
   143  		entity, err := authenticator.Authenticate(context.TODO(), s.State, authentication.AuthParams{
   144  			AuthTag:     t.entity.Tag(),
   145  			Credentials: t.credentials,
   146  			Nonce:       t.nonce,
   147  		})
   148  		c.Assert(err, gc.ErrorMatches, t.errorMessage)
   149  		c.Assert(entity, gc.IsNil)
   150  	}
   151  }