Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(204)

Side by Side Diff: state/apiserver/apiserver.go

Issue 7598043: Annotation documents and Environment Entity
Patch Set: Annotation documents and Environment Entity Created 12 years ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b