Left: | ||
Right: |
OLD | NEW |
---|---|
1 package apiserver | 1 package apiserver |
2 | 2 |
3 import ( | 3 import ( |
4 "code.google.com/p/go.net/websocket" | 4 "code.google.com/p/go.net/websocket" |
5 "fmt" | 5 "fmt" |
6 "launchpad.net/juju-core/charm" | 6 "launchpad.net/juju-core/charm" |
7 "launchpad.net/juju-core/juju" | 7 "launchpad.net/juju-core/juju" |
8 "launchpad.net/juju-core/log" | 8 "launchpad.net/juju-core/log" |
9 "launchpad.net/juju-core/state" | 9 "launchpad.net/juju-core/state" |
10 "launchpad.net/juju-core/state/api" | 10 "launchpad.net/juju-core/state/api" |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
158 // Any user is allowed to access their own user object. | 158 // Any user is allowed to access their own user object. |
159 // We check at this level rather than at the operation | 159 // We check at this level rather than at the operation |
160 // level to stop malicious probing for current user names. | 160 // level to stop malicious probing for current user names. |
161 // When we provide support for user administration, | 161 // When we provide support for user administration, |
162 // this will need to be changed to allow access to | 162 // this will need to be changed to allow access to |
163 // the administrator. | 163 // the administrator. |
164 e := r.user.entity() | 164 e := r.user.entity() |
165 if e == nil { | 165 if e == nil { |
166 return nil, errNotLoggedIn | 166 return nil, errNotLoggedIn |
167 } | 167 } |
168 » if e.EntityName() != name { | 168 » if r.user.entityName != name { |
169 return nil, errPerm | 169 return nil, errPerm |
170 } | 170 } |
171 u, err := r.srv.state.User(name) | 171 u, err := r.srv.state.User(name) |
172 if err != nil { | 172 if err != nil { |
173 return nil, err | 173 return nil, err |
174 } | 174 } |
175 return &srvUser{ | 175 return &srvUser{ |
176 root: r, | 176 root: r, |
177 u: u, | 177 u: u, |
178 }, nil | 178 }, nil |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
391 // EnvironmentInfo returns information about the current environment (default | 391 // EnvironmentInfo returns information about the current environment (default |
392 // series and type). | 392 // series and type). |
393 func (c *srvClient) EnvironmentInfo() (api.EnvironmentInfo, error) { | 393 func (c *srvClient) EnvironmentInfo() (api.EnvironmentInfo, error) { |
394 conf, err := c.root.srv.state.EnvironConfig() | 394 conf, err := c.root.srv.state.EnvironConfig() |
395 if err != nil { | 395 if err != nil { |
396 return api.EnvironmentInfo{}, err | 396 return api.EnvironmentInfo{}, err |
397 } | 397 } |
398 info := api.EnvironmentInfo{ | 398 info := api.EnvironmentInfo{ |
399 DefaultSeries: conf.DefaultSeries(), | 399 DefaultSeries: conf.DefaultSeries(), |
400 ProviderType: conf.Type(), | 400 ProviderType: conf.Type(), |
401 Name: conf.Name(), | |
401 } | 402 } |
402 return info, nil | 403 return info, nil |
403 } | 404 } |
404 | 405 |
405 // GetAnnotations returns annotations about a given entity. | 406 // GetAnnotations returns annotations about a given entity. |
406 func (c *srvClient) GetAnnotations(args params.GetAnnotations) (params.GetAnnota tionsResults, error) { | 407 func (c *srvClient) GetAnnotations(args params.GetAnnotations) (params.GetAnnota tionsResults, error) { |
407 » entity, err := c.root.srv.state.Entity(args.EntityId) | 408 » entity, err := c.root.srv.state.Annotator(args.EntityId) |
408 if err != nil { | 409 if err != nil { |
409 return params.GetAnnotationsResults{}, err | 410 return params.GetAnnotationsResults{}, err |
410 } | 411 } |
411 » return params.GetAnnotationsResults{Annotations: entity.Annotations()}, nil | 412 » ann, err := entity.Annotations() |
413 » if err != nil { | |
414 » » return params.GetAnnotationsResults{}, err | |
415 » } | |
416 » return params.GetAnnotationsResults{Annotations: ann}, nil | |
412 } | 417 } |
413 | 418 |
414 // SetAnnotation stores an annotation about a given entity. | 419 // SetAnnotation stores an annotation about a given entity. |
415 func (c *srvClient) SetAnnotation(args params.SetAnnotation) error { | 420 func (c *srvClient) SetAnnotation(args params.SetAnnotation) error { |
416 » entity, err := c.root.srv.state.Entity(args.EntityId) | 421 » entity, err := c.root.srv.state.Annotator(args.EntityId) |
417 if err != nil { | 422 if err != nil { |
418 return err | 423 return err |
419 } | 424 } |
420 return entity.SetAnnotation(args.Key, args.Value) | 425 return entity.SetAnnotation(args.Key, args.Value) |
421 } | 426 } |
422 | 427 |
423 // Login logs in with the provided credentials. | 428 // Login logs in with the provided credentials. |
424 // All subsequent requests on the connection will | 429 // All subsequent requests on the connection will |
425 // act as the authenticated user. | 430 // act as the authenticated user. |
426 func (a *srvAdmin) Login(c params.Creds) error { | 431 func (a *srvAdmin) Login(c params.Creds) error { |
(...skipping 10 matching lines...) Expand all Loading... | |
437 func (m *srvMachine) Watch() (params.EntityWatcherId, error) { | 442 func (m *srvMachine) Watch() (params.EntityWatcherId, error) { |
438 w := m.m.Watch() | 443 w := m.m.Watch() |
439 if _, ok := <-w.Changes(); !ok { | 444 if _, ok := <-w.Changes(); !ok { |
440 return params.EntityWatcherId{}, statewatcher.MustErr(w) | 445 return params.EntityWatcherId{}, statewatcher.MustErr(w) |
441 } | 446 } |
442 return params.EntityWatcherId{ | 447 return params.EntityWatcherId{ |
443 EntityWatcherId: m.root.watchers.register(w).id, | 448 EntityWatcherId: m.root.watchers.register(w).id, |
444 }, nil | 449 }, nil |
445 } | 450 } |
446 | 451 |
447 func setPassword(e state.Entity, password string) error { | 452 func setPassword(e state.Authenticator, password string) error { |
448 // Catch expected common case of mispelled | 453 // Catch expected common case of mispelled |
449 // or missing Password parameter. | 454 // or missing Password parameter. |
450 if password == "" { | 455 if password == "" { |
451 return fmt.Errorf("password is empty") | 456 return fmt.Errorf("password is empty") |
452 } | 457 } |
453 return e.SetPassword(password) | 458 return e.SetPassword(password) |
454 } | 459 } |
455 | 460 |
456 // SetPassword sets the machine's password. | 461 // SetPassword sets the machine's password. |
457 func (m *srvMachine) SetPassword(p params.Password) error { | 462 func (m *srvMachine) SetPassword(p params.Password) error { |
458 // Allow: | 463 // Allow: |
459 // - the machine itself. | 464 // - the machine itself. |
460 // - the environment manager. | 465 // - the environment manager. |
461 e := m.root.user.entity() | 466 e := m.root.user.entity() |
462 » allow := e.EntityName() == m.m.EntityName() || | 467 » allow := m.root.user.entityName == m.m.EntityName() || |
463 isMachineWithJob(e, state.JobManageEnviron) | 468 isMachineWithJob(e, state.JobManageEnviron) |
464 if !allow { | 469 if !allow { |
465 return errPerm | 470 return errPerm |
466 } | 471 } |
467 return setPassword(m.m, p.Password) | 472 return setPassword(m.m, p.Password) |
468 } | 473 } |
469 | 474 |
470 // Get retrieves all the details of a unit. | 475 // Get retrieves all the details of a unit. |
471 func (u *srvUnit) Get() (params.Unit, error) { | 476 func (u *srvUnit) Get() (params.Unit, error) { |
472 var ru params.Unit | 477 var ru params.Unit |
473 ru.DeployerName, _ = u.u.DeployerName() | 478 ru.DeployerName, _ = u.u.DeployerName() |
474 // TODO add other unit attributes | 479 // TODO add other unit attributes |
475 return ru, nil | 480 return ru, nil |
476 } | 481 } |
477 | 482 |
478 // SetPassword sets the unit's password. | 483 // SetPassword sets the unit's password. |
479 func (u *srvUnit) SetPassword(p params.Password) error { | 484 func (u *srvUnit) SetPassword(p params.Password) error { |
480 » ename := u.root.user.entity().EntityName() | 485 » ename := u.root.user.entityName |
481 // Allow: | 486 // Allow: |
482 // - the unit itself. | 487 // - the unit itself. |
483 // - the machine responsible for unit, if unit is principal | 488 // - the machine responsible for unit, if unit is principal |
484 // - the unit's principal unit, if unit is subordinate | 489 // - the unit's principal unit, if unit is subordinate |
485 allow := ename == u.u.EntityName() | 490 allow := ename == u.u.EntityName() |
486 if !allow { | 491 if !allow { |
487 deployerName, ok := u.u.DeployerName() | 492 deployerName, ok := u.u.DeployerName() |
488 allow = ok && ename == deployerName | 493 allow = ok && ename == deployerName |
489 } | 494 } |
490 if !allow { | 495 if !allow { |
491 return errPerm | 496 return errPerm |
492 } | 497 } |
493 return setPassword(u.u, p.Password) | 498 return setPassword(u.u, p.Password) |
494 } | 499 } |
495 | 500 |
496 // SetPassword sets the user's password. | 501 // SetPassword sets the user's password. |
497 func (u *srvUser) SetPassword(p params.Password) error { | 502 func (u *srvUser) SetPassword(p params.Password) error { |
498 return setPassword(u.u, p.Password) | 503 return setPassword(u.u, p.Password) |
499 } | 504 } |
500 | 505 |
501 // Get retrieves all details of a user. | 506 // Get retrieves all details of a user. |
502 func (u *srvUser) Get() (params.User, error) { | 507 func (u *srvUser) Get() (params.User, error) { |
503 return params.User{}, nil | 508 return params.User{}, nil |
504 } | 509 } |
505 | 510 |
506 // authUser holds login details. It's ok to call | 511 // authUser holds login details. It's ok to call |
507 // its methods concurrently. | 512 // its methods concurrently. |
508 type authUser struct { | 513 type authUser struct { |
509 » mu sync.Mutex | 514 » mu sync.Mutex |
510 » _entity state.Entity // logged-in entity (access only when mu is locked) | 515 » _entity state.Authenticator // logged-in entity (access only when mu is locked) |
dimitern
2013/03/19 09:06:12
why the underscore here? please remove.
frankban
2013/03/19 10:17:58
I don't know why, _entity preexisted.
Anyway, rena
| |
516 » entityName string | |
511 } | 517 } |
512 | 518 |
513 // login authenticates as entity with the given name,. | 519 // login authenticates as entity with the given name,. |
514 func (u *authUser) login(st *state.State, entityName, password string) error { | 520 func (u *authUser) login(st *state.State, entityName, password string) error { |
515 u.mu.Lock() | 521 u.mu.Lock() |
516 defer u.mu.Unlock() | 522 defer u.mu.Unlock() |
517 » entity, err := st.Entity(entityName) | 523 » entity, err := st.Authenticator(entityName) |
518 if err != nil && !state.IsNotFound(err) { | 524 if err != nil && !state.IsNotFound(err) { |
519 return err | 525 return err |
520 } | 526 } |
521 // TODO(rog) remove | 527 // TODO(rog) remove |
522 if !AuthenticationEnabled { | 528 if !AuthenticationEnabled { |
523 u._entity = entity | 529 u._entity = entity |
524 return nil | 530 return nil |
525 } | 531 } |
526 // We return the same error when an entity | 532 // We return the same error when an entity |
527 // does not exist as for a bad password, so that | 533 // does not exist as for a bad password, so that |
528 // we don't allow unauthenticated users to find information | 534 // we don't allow unauthenticated users to find information |
529 // about existing entities. | 535 // about existing entities. |
530 if err != nil || !entity.PasswordValid(password) { | 536 if err != nil || !entity.PasswordValid(password) { |
531 return errBadCreds | 537 return errBadCreds |
532 } | 538 } |
533 u._entity = entity | 539 u._entity = entity |
540 u.entityName = entityName | |
534 return nil | 541 return nil |
535 } | 542 } |
536 | 543 |
537 // entity returns the currently logged-in entity, or nil if not | 544 // entity returns the currently logged-in entity, or nil if not |
538 // currently logged on. The returned entity should not be modified | 545 // currently logged on. The returned entity should not be modified |
539 // because it may be used concurrently. | 546 // because it may be used concurrently. |
540 func (u *authUser) entity() state.Entity { | 547 func (u *authUser) entity() state.Authenticator { |
541 u.mu.Lock() | 548 u.mu.Lock() |
542 defer u.mu.Unlock() | 549 defer u.mu.Unlock() |
543 return u._entity | 550 return u._entity |
544 } | 551 } |
545 | 552 |
546 // isMachineWithJob returns whether the given entity is a machine that | 553 // isMachineWithJob returns whether the given entity is a machine that |
547 // is configured to run the given job. | 554 // is configured to run the given job. |
548 func isMachineWithJob(e state.Entity, j state.MachineJob) bool { | 555 func isMachineWithJob(e state.Authenticator, j state.MachineJob) bool { |
549 m, ok := e.(*state.Machine) | 556 m, ok := e.(*state.Machine) |
550 if !ok { | 557 if !ok { |
551 return false | 558 return false |
552 } | 559 } |
553 for _, mj := range m.Jobs() { | 560 for _, mj := range m.Jobs() { |
554 if mj == j { | 561 if mj == j { |
555 return true | 562 return true |
556 } | 563 } |
557 } | 564 } |
558 return false | 565 return false |
559 } | 566 } |
560 | 567 |
561 // isAgent returns whether the given entity is an agent. | 568 // isAgent returns whether the given entity is an agent. |
562 func isAgent(e state.Entity) bool { | 569 func isAgent(e state.Authenticator) bool { |
563 _, isUser := e.(*state.User) | 570 _, isUser := e.(*state.User) |
564 return !isUser | 571 return !isUser |
565 } | 572 } |
566 | 573 |
567 // watcher represents the interface provided by state watchers. | 574 // watcher represents the interface provided by state watchers. |
568 type watcher interface { | 575 type watcher interface { |
569 Stop() error | 576 Stop() error |
570 } | 577 } |
571 | 578 |
572 // watchers holds all the watchers for a connection. | 579 // watchers holds all the watchers for a connection. |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
628 func (ws *watchers) stopAll() { | 635 func (ws *watchers) stopAll() { |
629 ws.mu.Lock() | 636 ws.mu.Lock() |
630 defer ws.mu.Unlock() | 637 defer ws.mu.Unlock() |
631 for _, w := range ws.ws { | 638 for _, w := range ws.ws { |
632 if err := w.w.Stop(); err != nil { | 639 if err := w.w.Stop(); err != nil { |
633 log.Printf("state/api: error stopping %T watcher: %v", w , err) | 640 log.Printf("state/api: error stopping %T watcher: %v", w , err) |
634 } | 641 } |
635 } | 642 } |
636 ws.ws = make(map[string]*srvWatcher) | 643 ws.ws = make(map[string]*srvWatcher) |
637 } | 644 } |
OLD | NEW |